def convert_mouse_pos(self, x, y, min_x, min_y): # Original position zoom corrected ex, ey = x, y # Correct for zoom px_width, px_height = self.anat_image.pixelSize() x /= px_width y /= px_height # Inverse transformation from display to data coords = np.intp(pg.transformCoordinates(self.anat_image.inverseDataTransform(), np.array([x, y]))) dx = min_x + coords[0] dy = min_y + coords[1] # Divide dx and dy by the number of the atlas scale (here, 10) dx = dx dy = dy return dx, dy
def map(self, obj): """ Extends QMatrix4x4.map() to allow mapping (3, ...) arrays of coordinates """ if isinstance(obj, np.ndarray) and obj.ndim >= 2 and obj.shape[0] in (2,3): return pg.transformCoordinates(self, obj) else: return QtGui.QMatrix4x4.map(self, obj)
def test_pyqtgraph_conversion(self): if not HAVE_PYQTGRAPH: self.skipTest("pyqtgraph could not be imported") pts2 = np.random.normal(size=(100, 2)) qtr1 = pyqtgraph.QtGui.QTransform() qtr1.scale(1.1, -9) qtr1.translate(3, -30) qtr1.rotate(32) t_atr = linear.STTransform.convert_from(qtr1, 'pyqtgraph') qtr2 = t_atr.convert_to('pyqtgraph') assert np.allclose( pyqtgraph.transformCoordinates(qtr1, pts2, transpose=True), t_atr.map(pts2)) assert np.allclose( pyqtgraph.transformCoordinates(qtr2, pts2, transpose=True), t_atr.map(pts2)) pts3 = np.random.normal(size=(100, 3)) qtr1 = pyqtgraph.Transform3D() qtr1.scale(1.1, -9, 1e4) qtr1.translate(3, -30, 0) qtr1.rotate(32, 0, 1, 2) t_atr = linear.AffineTransform.convert_from(qtr1, 'pyqtgraph') print(t_atr) qtr2 = t_atr.convert_to('pyqtgraph') assert np.allclose( pyqtgraph.transformCoordinates(qtr1, pts3, transpose=True), t_atr.map(pts3)) assert np.allclose( pyqtgraph.transformCoordinates(qtr2, pts3, transpose=True), t_atr.map(pts3))
def __init__(self, h): self.h = h verts, edges = h.get_geometry() meshes = [] sec_ids = [] for edge in edges: ends = verts['pos'][edge] dia = verts['dia'][edge] sec_id = verts['sec_index'][edge[0]] dif = ends[1]-ends[0] length = (dif**2).sum() ** 0.5 mesh = gl.MeshData.cylinder(rows=1, cols=8, radius=[dia[0]/2., dia[1]/2.], length=length) mesh_verts = mesh.vertexes(indexed='faces') # Rotate cylinder vertexes to match segment p1 = pg.Vector(*ends[0]) p2 = pg.Vector(*ends[1]) z = pg.Vector(0,0,1) axis = pg.QtGui.QVector3D.crossProduct(z, p2-p1) ang = z.angle(p2-p1) tr = pg.Transform3D() tr.translate(ends[0][0], ends[0][1], ends[0][2]) # move into position tr.rotate(ang, axis.x(), axis.y(), axis.z()) mesh_verts = pg.transformCoordinates(tr, mesh_verts, transpose=True) sec_id_array = np.empty(mesh_verts.shape[0]*3, dtype=int) sec_id_array[:] = sec_id meshes.append(mesh_verts) sec_ids.append(sec_id_array) self.vertex_sec_ids = np.concatenate(sec_ids, axis=0) mesh_verts = np.concatenate(meshes, axis=0) md = gl.MeshData(vertexes=mesh_verts) gl.GLMeshItem.__init__(self, meshdata=md, shader='shaded')
def correctCoordinates(node, item): ## Remove transformation matrices from <g> tags by applying matrix to coordinates inside. ## Each item is represented by a single top-level group with one or more groups inside. ## Each inner group contains one or more drawing primitives, possibly of different types. groups = node.getElementsByTagName('g') ## Since we leave text unchanged, groups which combine text and non-text primitives must be split apart. ## (if at some point we start correcting text transforms as well, then it should be safe to remove this) groups2 = [] for grp in groups: subGroups = [grp.cloneNode(deep=False)] textGroup = None for ch in grp.childNodes[:]: if isinstance(ch, xml.Element): if textGroup is None: textGroup = ch.tagName == 'text' if ch.tagName == 'text': if textGroup is False: subGroups.append(grp.cloneNode(deep=False)) textGroup = True else: if textGroup is True: subGroups.append(grp.cloneNode(deep=False)) textGroup = False subGroups[-1].appendChild(ch) groups2.extend(subGroups) for sg in subGroups: node.insertBefore(sg, grp) node.removeChild(grp) groups = groups2 for grp in groups: matrix = grp.getAttribute('transform') match = re.match(r'matrix\((.*)\)', matrix) if match is None: vals = [1,0,0,1,0,0] else: vals = [float(a) for a in match.groups()[0].split(',')] tr = np.array([[vals[0], vals[2], vals[4]], [vals[1], vals[3], vals[5]]]) removeTransform = False for ch in grp.childNodes: if not isinstance(ch, xml.Element): continue if ch.tagName == 'polyline': removeTransform = True coords = np.array([[float(a) for a in c.split(',')] for c in ch.getAttribute('points').strip().split(' ')]) coords = pg.transformCoordinates(tr, coords, transpose=True) ch.setAttribute('points', ' '.join([','.join([str(a) for a in c]) for c in coords])) elif ch.tagName == 'path': removeTransform = True newCoords = '' oldCoords = ch.getAttribute('d').strip() if oldCoords == '': continue for c in oldCoords.split(' '): x,y = c.split(',') if x[0].isalpha(): t = x[0] x = x[1:] else: t = '' nc = pg.transformCoordinates(tr, np.array([[float(x),float(y)]]), transpose=True) newCoords += t+str(nc[0,0])+','+str(nc[0,1])+' ' ch.setAttribute('d', newCoords) elif ch.tagName == 'text': removeTransform = False ## leave text alone for now. Might need this later to correctly render text with outline. #c = np.array([ #[float(ch.getAttribute('x')), float(ch.getAttribute('y'))], #[float(ch.getAttribute('font-size')), 0], #[0,0]]) #c = pg.transformCoordinates(tr, c, transpose=True) #ch.setAttribute('x', str(c[0,0])) #ch.setAttribute('y', str(c[0,1])) #fs = c[1]-c[2] #fs = (fs**2).sum()**0.5 #ch.setAttribute('font-size', str(fs)) ## Correct some font information families = ch.getAttribute('font-family').split(',') if len(families) == 1: font = QtGui.QFont(families[0].strip('" ')) if font.style() == font.SansSerif: families.append('sans-serif') elif font.style() == font.Serif: families.append('serif') elif font.style() == font.Courier: families.append('monospace') ch.setAttribute('font-family', ', '.join([f if ' ' not in f else '"%s"'%f for f in families])) ## correct line widths if needed if removeTransform and ch.getAttribute('vector-effect') != 'non-scaling-stroke': w = float(grp.getAttribute('stroke-width')) s = pg.transformCoordinates(tr, np.array([[w,0], [0,0]]), transpose=True) w = ((s[0]-s[1])**2).sum()**0.5 ch.setAttribute('stroke-width', str(w)) if removeTransform: grp.removeAttribute('transform')
def correctCoordinates(node, item): ## Remove transformation matrices from <g> tags by applying matrix to coordinates inside. groups = node.getElementsByTagName("g") for grp in groups: matrix = grp.getAttribute("transform") match = re.match(r"matrix\((.*)\)", matrix) if match is None: vals = [1, 0, 0, 1, 0, 0] else: vals = map(float, match.groups()[0].split(",")) tr = np.array([[vals[0], vals[2], vals[4]], [vals[1], vals[3], vals[5]]]) removeTransform = False for ch in grp.childNodes: if not isinstance(ch, xml.Element): continue if ch.tagName == "polyline": removeTransform = True coords = np.array([map(float, c.split(",")) for c in ch.getAttribute("points").strip().split(" ")]) coords = pg.transformCoordinates(tr, coords, transpose=True) ch.setAttribute("points", " ".join([",".join(map(str, c)) for c in coords])) elif ch.tagName == "path": removeTransform = True newCoords = "" oldCoords = ch.getAttribute("d").strip() if oldCoords == "": continue for c in oldCoords.split(" "): x, y = c.split(",") if x[0].isalpha(): t = x[0] x = x[1:] else: t = "" nc = pg.transformCoordinates(tr, np.array([[float(x), float(y)]]), transpose=True) newCoords += t + str(nc[0, 0]) + "," + str(nc[0, 1]) + " " ch.setAttribute("d", newCoords) elif ch.tagName == "text": removeTransform = False ## leave text alone for now. Might need this later to correctly render text with outline. # c = np.array([ # [float(ch.getAttribute('x')), float(ch.getAttribute('y'))], # [float(ch.getAttribute('font-size')), 0], # [0,0]]) # c = pg.transformCoordinates(tr, c, transpose=True) # ch.setAttribute('x', str(c[0,0])) # ch.setAttribute('y', str(c[0,1])) # fs = c[1]-c[2] # fs = (fs**2).sum()**0.5 # ch.setAttribute('font-size', str(fs)) ## Correct some font information families = ch.getAttribute("font-family").split(",") if len(families) == 1: font = QtGui.QFont(families[0].strip('" ')) if font.style() == font.SansSerif: families.append("sans-serif") elif font.style() == font.Serif: families.append("serif") elif font.style() == font.Courier: families.append("monospace") ch.setAttribute("font-family", ", ".join([f if " " not in f else '"%s"' % f for f in families])) ## correct line widths if needed if removeTransform and ch.getAttribute("vector-effect") != "non-scaling-stroke": w = float(grp.getAttribute("stroke-width")) s = pg.transformCoordinates(tr, np.array([[w, 0], [0, 0]]), transpose=True) w = ((s[0] - s[1]) ** 2).sum() ** 0.5 ch.setAttribute("stroke-width", str(w)) if removeTransform: grp.removeAttribute("transform")
def correctCoordinates(node, item): ## Remove transformation matrices from <g> tags by applying matrix to coordinates inside. groups = node.getElementsByTagName('g') for grp in groups: matrix = grp.getAttribute('transform') match = re.match(r'matrix\((.*)\)', matrix) if match is None: vals = [1, 0, 0, 1, 0, 0] else: vals = map(float, match.groups()[0].split(',')) tr = np.array([[vals[0], vals[2], vals[4]], [vals[1], vals[3], vals[5]]]) removeTransform = False for ch in grp.childNodes: if not isinstance(ch, xml.Element): continue if ch.tagName == 'polyline': removeTransform = True coords = np.array([ map(float, c.split(',')) for c in ch.getAttribute('points').strip().split(' ') ]) coords = pg.transformCoordinates(tr, coords, transpose=True) ch.setAttribute( 'points', ' '.join([','.join(map(str, c)) for c in coords])) elif ch.tagName == 'path': removeTransform = True newCoords = '' oldCoords = ch.getAttribute('d').strip() if oldCoords == '': continue for c in oldCoords.split(' '): x, y = c.split(',') if x[0].isalpha(): t = x[0] x = x[1:] else: t = '' nc = pg.transformCoordinates(tr, np.array( [[float(x), float(y)]]), transpose=True) newCoords += t + str(nc[0, 0]) + ',' + str(nc[0, 1]) + ' ' ch.setAttribute('d', newCoords) elif ch.tagName == 'text': removeTransform = False ## leave text alone for now. Might need this later to correctly render text with outline. #c = np.array([ #[float(ch.getAttribute('x')), float(ch.getAttribute('y'))], #[float(ch.getAttribute('font-size')), 0], #[0,0]]) #c = pg.transformCoordinates(tr, c, transpose=True) #ch.setAttribute('x', str(c[0,0])) #ch.setAttribute('y', str(c[0,1])) #fs = c[1]-c[2] #fs = (fs**2).sum()**0.5 #ch.setAttribute('font-size', str(fs)) ## Correct some font information families = ch.getAttribute('font-family').split(',') if len(families) == 1: font = QtGui.QFont(families[0].strip('" ')) if font.style() == font.SansSerif: families.append('sans-serif') elif font.style() == font.Serif: families.append('serif') elif font.style() == font.Courier: families.append('monospace') ch.setAttribute( 'font-family', ', '.join([ f if ' ' not in f else '"%s"' % f for f in families ])) ## correct line widths if needed if removeTransform and ch.getAttribute( 'vector-effect') != 'non-scaling-stroke': w = float(grp.getAttribute('stroke-width')) s = pg.transformCoordinates(tr, np.array([[w, 0], [0, 0]]), transpose=True) w = ((s[0] - s[1])**2).sum()**0.5 ch.setAttribute('stroke-width', str(w)) if removeTransform: grp.removeAttribute('transform')
def correctCoordinates(node, item): ## Remove transformation matrices from <g> tags by applying matrix to coordinates inside. ## Each item is represented by a single top-level group with one or more groups inside. ## Each inner group contains one or more drawing primitives, possibly of different types. groups = node.getElementsByTagName('g') ## Since we leave text unchanged, groups which combine text and non-text primitives must be split apart. ## (if at some point we start correcting text transforms as well, then it should be safe to remove this) groups2 = [] for grp in groups: subGroups = [grp.cloneNode(deep=False)] textGroup = None for ch in grp.childNodes[:]: if isinstance(ch, xml.Element): if textGroup is None: textGroup = ch.tagName == 'text' if ch.tagName == 'text': if textGroup is False: subGroups.append(grp.cloneNode(deep=False)) textGroup = True else: if textGroup is True: subGroups.append(grp.cloneNode(deep=False)) textGroup = False subGroups[-1].appendChild(ch) groups2.extend(subGroups) for sg in subGroups: node.insertBefore(sg, grp) node.removeChild(grp) groups = groups2 for grp in groups: matrix = grp.getAttribute('transform') match = re.match(r'matrix\((.*)\)', matrix) if match is None: vals = [1, 0, 0, 1, 0, 0] else: vals = [float(a) for a in match.groups()[0].split(',')] tr = np.array([[vals[0], vals[2], vals[4]], [vals[1], vals[3], vals[5]]]) removeTransform = False for ch in grp.childNodes: if not isinstance(ch, xml.Element): continue if ch.tagName == 'polyline': removeTransform = True coords = np.array( [[float(a) for a in c.split(',')] for c in ch.getAttribute('points').strip().split(' ')]) coords = pg.transformCoordinates(tr, coords, transpose=True) ch.setAttribute( 'points', ' '.join([','.join([str(a) for a in c]) for c in coords])) elif ch.tagName == 'path': removeTransform = True newCoords = '' oldCoords = ch.getAttribute('d').strip() if oldCoords == '': continue for c in oldCoords.split(' '): x, y = c.split(',') if x[0].isalpha(): t = x[0] x = x[1:] else: t = '' nc = pg.transformCoordinates(tr, np.array( [[float(x), float(y)]]), transpose=True) newCoords += t + str(nc[0, 0]) + ',' + str(nc[0, 1]) + ' ' ch.setAttribute('d', newCoords) elif ch.tagName == 'text': removeTransform = False ## leave text alone for now. Might need this later to correctly render text with outline. #c = np.array([ #[float(ch.getAttribute('x')), float(ch.getAttribute('y'))], #[float(ch.getAttribute('font-size')), 0], #[0,0]]) #c = pg.transformCoordinates(tr, c, transpose=True) #ch.setAttribute('x', str(c[0,0])) #ch.setAttribute('y', str(c[0,1])) #fs = c[1]-c[2] #fs = (fs**2).sum()**0.5 #ch.setAttribute('font-size', str(fs)) ## Correct some font information families = ch.getAttribute('font-family').split(',') if len(families) == 1: font = QtGui.QFont(families[0].strip('" ')) if font.style() == font.SansSerif: families.append('sans-serif') elif font.style() == font.Serif: families.append('serif') elif font.style() == font.Courier: families.append('monospace') ch.setAttribute( 'font-family', ', '.join([ f if ' ' not in f else '"%s"' % f for f in families ])) ## correct line widths if needed if removeTransform and ch.getAttribute( 'vector-effect') != 'non-scaling-stroke': w = float(grp.getAttribute('stroke-width')) s = pg.transformCoordinates(tr, np.array([[w, 0], [0, 0]]), transpose=True) w = ((s[0] - s[1])**2).sum()**0.5 ch.setAttribute('stroke-width', str(w)) if removeTransform: grp.removeAttribute('transform')