def test_normalise(seed): vectors = -100 + 200 * np.random.random((200, 3)) def parallel(v1, v2): v1 = v1 / affine.veclength(v1) v2 = v2 / affine.veclength(v2) return np.isclose(np.dot(v1, v2), 1) for v in vectors: vtype = random.choice((list, tuple, np.array)) v = vtype(v) vn = affine.normalise(v) vl = affine.veclength(vn) assert np.isclose(vl, 1.0) assert parallel(v, vn) # normalise should also be able # to do multiple vectors at once results = affine.normalise(vectors) lengths = affine.veclength(results) pars = np.zeros(200) for i in range(200): v = vectors[i] r = results[i] pars[i] = parallel(v, r) assert np.all(np.isclose(lengths, 1)) assert np.all(pars)
def _pickModeLeftMouseDrag(self, ev, canvas, mousePos, canvasPos): """Handles left mouse drag events in ``pick`` mode. If the currently selected overlay is a :class:`.Mesh`, identifies the mesh vertex which is nearest to the mouse click, and updates the :attr:`.DisplayContext.location`. Otherwise, returns ``False``. """ import fsl.data.mesh as fslmesh overlay = self.displayCtx.getSelectedOverlay() if not isinstance(overlay, fslmesh.Mesh): return False opts = self.displayCtx.getOpts(overlay) loc = opts.transformCoords(canvasPos, 'display', 'mesh') # The GLMesh caches the most # recently drawn cross section # vertices, and corresponding # mesh triangle indices, in # the mesh coordinate system. xsect = self.overlayList.getData( overlay, 'crosssection_{}'.format(canvas.opts.zax), None) # No cross-section calculated, # can't pick the nearest vertex. if xsect is None or len(xsect[0]) == 0: return False lines, faces = xsect lines = lines.reshape(-1, 3) # Find the location on the cross section # that was nearest to the mouse click ldists = affine.veclength(loc - lines) lidx = np.argsort(ldists)[0] lvert = lines[lidx] fidx = faces[int(np.floor(lidx / 2))] # Get the triangle on the mesh # corresponding to this location face = overlay.indices[fidx] faceVerts = overlay.vertices[face] # Calculate the nearest vertex on # this triangle fdists = affine.veclength(faceVerts - lvert) vidx = np.argsort(fdists)[0] vidx = face[vidx] loc = overlay.vertices[vidx, :] loc = opts.transformCoords(loc, 'mesh', 'display') self.displayCtx.location.xyz = loc
def test_veclength(seed): def l(v): v = np.array(v, copy=False).reshape((-1, 3)) x = v[:, 0] y = v[:, 1] z = v[:, 2] l = x * x + y * y + z * z return np.sqrt(l) vectors = -100 + 200 * np.random.random((200, 3)) for v in vectors: vtype = random.choice((list, tuple, np.array)) v = vtype(v) assert np.isclose(affine.veclength(v), l(v)) # Multiple vectors in parallel result = affine.veclength(vectors) expected = l(vectors) assert np.all(np.isclose(result, expected))
def parallel(v1, v2): v1 = v1 / affine.veclength(v1) v2 = v2 / affine.veclength(v2) return np.isclose(np.dot(v1, v2), 1)
def _pickModeLeftMouseDown(self, ev, canvas, mousePos, canvasPos): """Called on mouse down events in ``pick`` mode. Updates the :attr:`DisplayContext.location` property. """ from fsl.data.mesh import Mesh displayCtx = self.displayCtx ovl = displayCtx.getSelectedOverlay() if ovl is None: return # The canvasPos is located on the near clipping # plane (see Scene3DCanvas.canvasToWorld). # We also need the corresponding point on the # far clipping plane. farPos = canvas.canvasToWorld(mousePos[0], mousePos[1], near=False) # For non-mesh overlays, we select a point which # is in between the near/far clipping planes. if not isinstance(ovl, Mesh): posDir = farPos - canvasPos dist = affine.veclength(posDir) posDir = affine.normalise(posDir) midPos = canvasPos + 0.5 * dist * posDir self.displayCtx.location.xyz = midPos else: opts = self.displayCtx.getOpts(ovl) rayOrigin = canvasPos rayDir = affine.normalise(farPos - canvasPos) # transform location from display into model space rayOrigin = opts.transformCoords(rayOrigin, 'display', 'mesh') rayDir = opts.transformCoords(rayDir, 'display', 'mesh', vector=True) loc, tri = ovl.rayIntersection([rayOrigin], [rayDir], vertices=True) if len(loc) == 0: return loc = loc[0] tri = ovl.indices[int(tri[0]), :] # The rayIntersection method gives us a # point on one of the mesh triangles - # we want the vertex on that triangle # which is nearest to the intersection. triVerts = ovl.vertices[tri, :] triDists = affine.veclength(loc - triVerts) vertIdx = np.argsort(triDists)[0] loc = ovl.vertices[tri[vertIdx], :] loc = opts.transformCoords(loc, 'mesh', 'display') self.displayCtx.location.xyz = loc