def _OnMouseMotion(self, event):
     
     # Handle or pass?
     if not (self._interact_down and self._screenVec):
         return
     
     # Get vector relative to reference position
     refPos = vv.Point(self._refPos)
     pos = vv.Point(event.x, event.y)
     vec = pos - refPos
     
     # Length of reference vector, and its normalized version
     screenVec = vv.Point(self._screenVec)
     L = screenVec.norm()
     V = screenVec.normalize()
     
     # Number of indexes to change
     n = vec.dot(V) / L
     
     # Apply!
     # scale of 100 is approximately half the height of a stent
     #delta = (self._refZ + n*50.0) - self.translation.z
     #self.translation += vv.Point(0, 0, delta)
     self.performMeasurements(self._refZ + n*50, True)
     if self._slider is not None:
         self._slider._range.max = float(self._refZ + n*50)
         self._slider._limitRangeAndSetText()
         self._slider.Draw()
def fit_cirlce(pp, warnIfIllDefined=True):
    """ fit_cirlce(pp, warnIfIllDefined=True)
    Calculate the circle (x - c.x)**2 + (y - x.y)**2 = c.r**2
    From the set of points pp. Returns a point instance with an added
    attribute "r" specifying the radius.
    
    In case the three points are on a line, the algorithm will fail, and
    return 0 for x,y and r. This waring can be suppressed.
    
    The solution is a Least Squares fit. The method as describes in [1] is
    called Modified Least Squares (MLS) and poses a closed form solution
    which is very robust.

    [1]
    Dale Umbach and Kerry N. Jones
    2000
    A Few Methods for Fitting Circles to Data
    IEEE Transactions on Instrumentation and Measurement
    """
    
    # Init error point
    ce = vv.Point(0,0)
    ce.r = 0.0
    
    def cov(a, b):
        n = len(a)
        Ex = a.sum() / n
        Ey = b.sum() / n
        return ( (a-Ex)*(b-Ey) ).sum() / (n-1)
    
    # Get x and y elements
    X = pp[:,0]
    Y = pp[:,1]
    
    # In the paper there is a factor n*(n-1) in all equations below. However,
    # this factor is removed by devision in the equations in the following cell
    A = cov(X,X)
    B = cov(X,Y)
    C = cov(Y,Y)
    D = 0.5 * ( cov(X,Y**2) + cov(X,X**2) )
    E = 0.5 * ( cov(Y,X**2) + cov(Y,Y**2) )
    
    # Calculate denumerator
    denum = A*C - B*B
    if denum==0:
        if warnIfIllDefined:
            print "Warning: can not fit a circle to the given points."
        return ce
    
    # Calculate point
    c = vv.Point( (D*C-B*E)/denum, (A*E-B*D)/denum )
    
    # Calculate radius
    c.r = c.distance(pp).sum() / len(pp)
    
    # Done
    return c
Exemple #3
0
 def onClick(event):
     if event.button == 2 and vv.KEY_SHIFT in event.modifiers:
         # Get clicked location in NDC
         w, h = event.owner.position.size
         x, y = 2 * event.x / w - 1, -2 * event.y / h + 1
         # Apply inverse camera transform to get two points on the clicked line
         M = np.linalg.inv(get_camera_matrix(event.owner))
         p1 = vv.Point(np.dot((x, y, -100, 1), M)[:3])
         p2 = vv.Point(np.dot((x, y, +100, 1), M)[:3])
         # Calculate center point and vector
         pm = 0.5 * (p1 + p2)
         vec = (p2 - p1).normalize()
         # Prepare for searching in two directions
         pp = [pm - vec, pm + vec]
         status = 0 if sample(vol, pm) is None else 1
         status = [status, status]
         hit = None
         max_sample = -999999
         step = min(vol.sampling)
         # Look in two directions simulaneously, search for volume, collect samples
         for i in range(10000):  # Safe while-loop
             for j in (0, 1):
                 if status[j] < 2:
                     s = sample(vol, pp[j])
                     inside = s is not None
                     if inside:
                         if s > max_sample:
                             max_sample, hit = s, pp[j]
                         if status[j] == 0:
                             status[j] = 1
                             status[
                                 not j] = 2  # stop looking in other direction
                     else:
                         if status[j] == 1:
                             status[j] = 2
                     pp[j] += (j * 2 - 1) * step * vec
             if status[0] == 2 and status[1] == 2:
                 break
         else:
             print('Warning: ray casting to collect samples did not stop'
                   )  # clicking outside the volume
         # Draw
         pp2 = vv.Pointset(3)
         text = 'No point inside volume selected.'
         if hit:
             pp2.append(hit)
             ii = vol.point_to_index(hit)
             text = 'At z=%1.1f, y=%1.1f, x=%1.1f -> X[%i, %i, %i] -> %1.2f' % (
                 hit.z, hit.y, hit.x, ii[0], ii[1], ii[2], max_sample)
         line.SetPoints(pp2)
         label.text = text
         return True  # prevent default mouse action
def arrows(points, vectors, head=(0.2, 1.0), **kwargs):

    if 'ls' in kwargs:
        raise ValueError('Cannot set line style for arrows.')

    ppd = vv.Pointset(pp.ndim)
    for i in range(len(points)):

        p1 = points[i]  # source point
        v1 = vectors[i]  # THE vector
        v1_norm = v1.norm()
        p2 = p1 + v1  # destination point
        if v1_norm:
            pn = v1.normal() * v1_norm * abs(head[0])  # normal vector
        else:
            pn = vv.Point(0, 0)
        ph1 = p1 + v1 * head[1]
        ph2 = ph1 - v1 * head[0]

        # Add stick
        ppd.append(p1)
        ppd.append(p2)
        # Add arrowhead
        ppd.append(ph1)
        ppd.append(ph2 + pn)
        ppd.append(ph1)
        ppd.append(ph2 - pn)

    return vv.plot(ppd, ls='+', **kwargs)
 def __init__(self, xy, v):
     #global w
     """:param xy: Initial position, :param v: Initial velocity. """
     # cast inputs as 2-d numpy arrays
     self.xy = xy.reshape((1,3)) #np.array(xy)
     self.v = v.reshape((1,3))  #np.array(v)
     
     # generate sphere data and colors.
     self.object = vv.solidSphere(vv.Point(self.xy), scaling=(0.05, 0.05, 0.05))
     self.object.faceColor = [random(), random(), random()]
     self.trans = self.object.transformations[0]
 def _CalculateDonut(self, N=32, M=32, thickness=0.2):
     
     # Quick access
     pi2 = np.pi*2
     cos = np.cos
     sin = np.sin
     sl = M+1
     
     # Calculate vertices, normals and texcords
     vertices = vv.Pointset(3)
     normals = vv.Pointset(3)
     texcords = vv.Pointset(2)
     # Cone
     for n in range(N+1):
         v = float(n)/N
         a = pi2 * v        
         # Obtain outer and center position of "tube"
         po = vv.Point(sin(a), cos(a), 0)
         pc = po * (1.0-0.5*thickness)
         # Create two vectors that span the the circle orthogonal to the tube
         p1 = (pc-po)
         p2 = vv.Point(0, 0, 0.5*thickness)
         # Sample around tube        
         for m in range(M+1):
             u = float(m) / (M)
             b = pi2 * (u) 
             dp = cos(b) * p1 + sin(b) * p2
             vertices.append(pc+dp)
             normals.append(dp.normalize())
             texcords.append(v,u)
     
     # Calculate indices
     indices = []
     for j in range(N):
         for i in range(M):
             indices.extend([(j+1)*sl+i, (j+1)*sl+i+1, j*sl+i+1, j*sl+i])
     
     # Make indices a numpy array
     indices = np.array(indices, dtype=np.uint32)
     
     return vertices, indices, normals, texcords
Exemple #7
0
def draw_error_ellipsoid_visvis(mu,
                                covariance_matrix,
                                stdev=1,
                                z_offset=0,
                                color_ellipsoid="g",
                                pt_size=5):
    """
    @brief Plot the error (uncertainty) ellipsoid using a 3D covariance matrix for a given standard deviation
    @param mu: The mean vector
    @param covariance_matrix: the 3x3 covariance matrix
    @param stdev: The desire standard deviation value to draw the uncertainty ellipsoid for. Default is 1.
    """
    import visvis as vv

    # Step 1: make a unit n-sphere
    u = np.linspace(0.0, 2.0 * np.pi, 30)
    v = np.linspace(0.0, np.pi, 30)
    x_sph = np.outer(np.cos(u), np.sin(v))
    y_sph = np.outer(np.sin(u), np.sin(v))
    z_sph = np.outer(np.ones_like(u), np.cos(v))
    X_sphere = np.dstack((x_sph, y_sph, z_sph))
    # Step 2:  apply the following linear transformation to get the points of your ellipsoid (Y):
    C = np.linalg.cholesky(covariance_matrix)

    ellipsoid_pts = mu + stdev * np.dot(X_sphere, C)

    x = ellipsoid_pts[..., 0]
    y = ellipsoid_pts[..., 1]
    z = ellipsoid_pts[..., 2] + z_offset

    # plot
    ellipsoid_surf = vv.surf(x, y, z)
    # Get axes

    #     ellipsoid_surf = vv.grid(x, y, z)
    ellipsoid_surf.faceShading = "smooth"
    ellipsoid_surf.faceColor = color_ellipsoid
    #     ellipsoid_surf.edgeShading = "plain"
    #     ellipsoid_surf.edgeColor = color_ellipsoid
    ellipsoid_surf.diffuse = 0.9
    ellipsoid_surf.specular = 0.9

    mu_pt = vv.Point(mu[0], mu[1], mu[2] + z_offset)
    pt_mu = vv.plot(mu_pt,
                    ms='.',
                    mc="k",
                    mw=pt_size,
                    ls='',
                    mew=0,
                    axesAdjust=True)
 def calculatePulsation(self, contour, deltas):
     """ Given the contour points and their motion vectors, calculate
     the minimum and maximum of the area and circumference.
     """
     
     # Init
     areas = []
     circs = []
     
     # For each time instance in the motion ...
     for delta in deltas:
         
         # Get closed contour points for this motion phase
         pp = contour + delta
         pp.append(pp[0])
         
         # Get a point in the centre
         cp = vv.Point(0,0,0)
         for p in pp[:-1]:
             cp += p
         cp *= 1.0 / (len(pp)-1)
         
         # Area
         if True:
             area = 0.0
             for i in range(len(contour)):
                 # Get triangle points and lengths of the sides
                 p1, p2 = pp[i], pp[i+1]
                 a, b, c = cp.distance(p1), cp.distance(p2), p1.distance(p2)
                 # Approximate area of this triangle
                 area += 0.5 * 0.5*(a+b) * c
             areas.append(float(area))
         
         # Circumference
         if True:
             circ = 0.0
             for i in range(len(contour)):
                 # Get triangle points and length between them
                 p1, p2 = pp[i], pp[i+1]
                 circ += p1.distance(p2)
             circs.append(float(circ))
     
     
     # Post process: look for smallest and largest
     return min(areas), max(areas), min(circs), max(circs)
 def calculateMotionMagnitude(self, contour, deltas):
     """ Calculate the mean motion magnitude (i.e. amplitude in principal
     direction).
     """
     
     # Init a list that contains the mean z-position for each time unit
     # Note that this is a relative z-position, but that doesnt matter
     meanPositions = vv.Pointset(3)
     
     # delta is a pointset, there is such a pointsets for each time unit
     for delta in deltas: 
         meanPosition = vv.Point(0,0,0)
         for p in delta:
             meanPosition += p
         meanPosition *= 1.0 / len(delta)
         meanPositions.append(meanPosition)
     
     return self._calculateMagnitude(meanPositions)
# Apply the deform to the images
im_forward = deform_forward.apply_deformation(im)
im_forward2 = deform_forward2.apply_deformation(im)
im_backward = deform_backward.apply_deformation(im)
im_backward2 = deform_backward2.apply_deformation(im)

# Calculate vectors
vecstep = 20
pp = vv.Pointset(2)
vvf, vvb = vv.Pointset(2), vv.Pointset(2)
vvf2, vvb2 = vv.Pointset(2), vv.Pointset(2)
for y in np.arange(0, im.shape[0], vecstep):
    for x in np.arange(0, im.shape[1], vecstep):
        # Center point
        p1 = vv.Point(x, y)
        pp.append(p1)
        # Vector for forward
        deform = deform_forward
        vvf.append(vv.Point(deform[1][y, x], deform[0][y, x]))
        deform = deform_forward2
        vvf2.append(vv.Point(deform[1][y, x], deform[0][y, x]))
        # Vector for backward
        deform = deform_backward
        vvb.append(vv.Point(deform[1][y, x], deform[0][y, x]))
        deform = deform_backward2
        vvb2.append(vv.Point(deform[1][y, x], deform[0][y, x]))

# Show

f = vv.figure(1)