Beispiel #1
0
    def test_interpolate3D(self):
        mat1 = rotax([0, 0, 0], [0, 0, 1], 30.0 * degtorad)
        mat2 = rotax([0, 0, 0], [0, 0, 1], 60.0 * degtorad)
        mat3 = rotax([0, 0, 0], [0, 0, 1], 90.0 * degtorad)
        # add translation (0,1,0) to mat2
        mat2 = N.array([[0.5, 0.86602539, 0., 0.], [-0.86602539, 0.5, 0., 0.],
                        [0., 0., 1., 0.], [0., 1., 0., 1.]], 'f')

        matList = [mat1, mat2, mat3]
        indexList = [0.33333333, 0.66666666667, 1.0]
        data = [[0., 0., 0., 1.], [1.0, 0.0, 0.0, 1.0], [2., 0., 0., 1.]]
        p = 0.5
        M = interpolate3DTransform(matList, indexList, p)

        res = N.dot(data, M)[1]

        self.assertEqual(self.diff(res[0], 0.70710677), True)
        self.assertEqual(self.diff(res[1], 1.20710677),
                         True)  # 50% translation along Y axis
        self.assertEqual(self.diff(res[2], 0.0), True)

        p = 1.5
        M = interpolate3DTransform(matList, indexList, p)
        res = N.dot(data, M)[1]
        self.assertEqual(self.diff(res[0], -0.70710677), True)
        self.assertEqual(self.diff(res[1], 0.70710677), True)
        self.assertEqual(self.diff(res[2], 0.0), True)
Beispiel #2
0
 def __init__(self, point1 = None, point2 = None, slab = None):
     # Huaicai 4/23/05: added some comments below to help understand the code.
     if slab:
         # convert from 2d (x, y) coordinates into its 3d world (x, y, 0) 
         #coordinates(the lower-left and upper-right corner). 
         #In another word, the 3d coordinates minus the z offset of the plane
         x = dot(A(point1), A(point2))
         # Get the vector from upper-right point to the lower-left point
         dx = subtract.reduce(x)
         # Get the upper-left and lower right corner points
         oc = x[1] + V(point2[0]*dot(dx,point2[0]), 
                       point2[1]*dot(dx,point2[1]))
         # Get the four 3d cooridinates on the bottom crystal-cutting plane
         sq1 = cat(x,oc) + slab.normal*dot(slab.point, slab.normal)
         # transfer the above 4 3d coordinates in parallel to get that on
         #the top plane, put them together
         sq1 = cat(sq1, sq1+slab.thickness*slab.normal)
         self.data = V(maximum.reduce(sq1), minimum.reduce(sq1))
     elif point2:
         # just 2 3d points
         self.data = V(maximum(point1, point2), minimum(point1, point2))
     elif point1:
         # list of points: could be 2d or 3d?  +/- 1.8 to make the bounding 
         #box enclose the vDw ball of an atom?
         self.data = V(maximum.reduce(point1) + BBOX_MARGIN, 
                       minimum.reduce(point1) - BBOX_MARGIN)
     else:
         # a null bbox
         self.data = None
    def getMatrices(self, matA, matB):

        matInA, matInB = self.set(matA, matB)

        #assert that matrices have either size 1, or equal size
        assert len(matInA) == 1 or len(matInB) == 1 or \
               len(matInA) == len(matInB)

        matrixOut = []

        #now the actual multiplication
	if len(matInA) == 1:
            for i in range(len(matInB)): #loop over node's incoming matrices
                matrixOut.append(Numeric.dot(matInA[0],
                                                           matInB[i]))

        elif len(matInB) == 1:
            for i in range(len(matInA)): #loop over node's incoming matrices
                matrixOut.append(Numeric.dot(matInA[i],
                                                           matInB[0]))


        else:
            for i in range(len(matInA)): #loop over node's incoming matrices
                matrixOut.append(Numeric.dot(matInA[i],
                                                           matInB[i]))

        return matrixOut
Beispiel #4
0
    def __findTransformation(self, x, y):
        """
        Match two arrays by rotation and translation. Returns the
        rotation matrix and the translation vector.
        Back transformation:
        for atom i new coordinates will be::
            y_new[i] = N.dot(r, y[i]) + t
            
        for all atoms in one step::
            y_new = N.dot(y, N.transpose(r)) + t

        @param x: coordinates
        @type  x: array
        @param y: coordinates
        @type  y: array

        @return: rotation matrix, translation vector
        @rtype: array, array      
        
        @author: Michael Habeck
        """
        from numpy.oldnumeric.linear_algebra import singular_value_decomposition as svd

        ## center configurations
        x_av = N.sum(x) / len(x)
        y_av = N.sum(y) / len(y)
        x = x - x_av
        y = y - y_av
        ## svd of correlation matrix
        v, l, u = svd(N.dot(N.transpose(x), y))
        ## build rotation matrix and translation vector
        r = N.dot(v, u)
        t = x_av - N.dot(r, y_av)

        return r, t
Beispiel #5
0
    def __pairwiseDistances(self, u, v):
        """
        pairwise distance between 2 3-D numpy arrays of atom coordinates.

        @param u: coordinates
        @type  u: array
        @param v: coordinates
        @type  v: array
        
        @return: Numpy array len(u) x len(v)
        @rtype:array
        
        @author: Wolfgang Rieping.
        """
        ## check input
        if not type( u ) == arraytype or\
           not type( v ) == arraytype:
            raise ComplexError('unsupported argument type ' + \
                               str( type(u) ) + ' or ' + str( type(v) ) )

        diag1= N.diagonal(N.dot(u,N.transpose(u)))
        diag2= N.diagonal(N.dot(v,N.transpose(v)))
        dist= -N.dot(v,N.transpose(u))-N.transpose(N.dot(u,N.transpose(v)))
        dist= N.transpose(N.asarray(map(lambda column,a:column+a, \
                                   N.transpose(dist), diag1)))

        return N.transpose(N.sqrt(N.asarray(
            map(lambda row,a: row+a, dist, diag2))))
 def test_interpolate3D(self):
     mat1=rotax([0,0,0], [0,0,1],30.0*degtorad)
     mat2=rotax([0,0,0], [0,0,1],60.0*degtorad)
     mat3=rotax([0,0,0], [0,0,1],90.0*degtorad)
     # add translation (0,1,0) to mat2 
     mat2 = N.array([
            [ 0.5       ,  0.86602539,  0.        ,  0.        ],
            [-0.86602539,  0.5       ,  0.        ,  0.        ],
            [ 0.        ,  0.        ,  1.        ,  0.        ],
            [ 0.        ,  1.        ,  0.        ,  1.        ]],'f')
 
     matList=[mat1, mat2, mat3]
     indexList = [0.33333333, 0.66666666667, 1.0]
     data = [[0.,0.,0.,1.],[1.0, 0.0, 0.0,1.0],[2.,0.,0.,1.]]
     p=0.5
     M = interpolate3DTransform(matList, indexList, p)
     
     res=N.dot(data, M)[1]
     
     self.assertEqual( self.diff(res[0], 0.70710677 ),True)
     self.assertEqual(self.diff(res[1], 1.20710677 ),True) # 50% translation along Y axis
     self.assertEqual(self.diff(res[2], 0.0),True)
 
     p=1.5
     M = interpolate3DTransform(matList, indexList, p)
     res=N.dot(data, M)[1]
     self.assertEqual(self.diff(res[0], -0.70710677 ),True)
     self.assertEqual(self.diff(res[1],  0.70710677 ),True)
     self.assertEqual(self.diff(res[2],  0.0),True)
Beispiel #7
0
def angleBetween(vec1, vec2):
    """
    Return the angle between two vectors, in degrees,
    but try to cover all the weird cases where numerical
    anomalies could pop up.
    """
    # paranoid acos(dotproduct) function, wware 051103
    # [TODO: should merge with threepoint_angle_in_radians]
    TEENY = 1.0e-10
    lensq1 = Numeric.dot(vec1, vec1)
    if lensq1 < TEENY:
        return 0.0
    lensq2 = Numeric.dot(vec2, vec2)
    if lensq2 < TEENY:
        return 0.0
    
    #Replaced earlier formula "vec1 /= lensq1 ** .5" to fix the 
    #following bug:  
    #The above formula was modifying the arguments using the /= statement. 
    #Numeric.array objects (V objects) are mutable, and op= operators modify 
    #them so replacing  [--ninad 20070614 comments, based on an email 
    #conversation with Bruce where he noticed the real problem.] 
    
    vec1 = vec1 / lensq1 ** .5
    vec2 = vec2 / lensq2 ** .5
    # The case of nearly-equal vectors will be covered by the >= 1.0 clause.
    #diff = vec1 - vec2
    #if dot(diff, diff) < TEENY:
    #    return 0.0
    dprod = Numeric.dot(vec1, vec2)
    if dprod >= 1.0:
        return 0.0
    if dprod <= -1.0:
        return 180.0
    return (180 / math.pi) * math.acos(dprod)
Beispiel #8
0
 def rtz(self, pt):
     d = pt - self.p0
     z = dot(d, self.zn)
     d = d - z * self.zn
     r = vlen(d)
     theta = Numeric.arctan2(dot(d, self.v), dot(d, self.u))
     return Numeric.array((r, theta, z), 'd')
Beispiel #9
0
def findTransformation(x, y):
    """
    Match two arrays by rotation and translation. Returns the
    rotation matrix and the translation vector.

    @param x: first set of coordinates
    @type  x: array('f')
    @param y: second set of coordinates
    @type  y: array('f')

    @return: rotation matrix (3x3) and translation vector (1x3)
    @rtype:  array, array
    """
    ## center configurations
    x_av = N.average(x)
    y_av = N.average(y)

    x = x - x_av
    y = y - y_av

    ## svd of correlation matrix
    v, l, u = svd(N.dot(N.transpose(x), y))

    ## build rotation matrix and translation vector
    r = N.dot(v, u)

    t = x_av - N.dot(r, y_av)

    return r, t
Beispiel #10
0
 def __init__(self, point1=None, point2=None, slab=None):
     # Huaicai 4/23/05: added some comments below to help understand the code.
     if slab:
         # convert from 2d (x, y) coordinates into its 3d world (x, y, 0)
         #coordinates(the lower-left and upper-right corner).
         #In another word, the 3d coordinates minus the z offset of the plane
         x = dot(A(point1), A(point2))
         # Get the vector from upper-right point to the lower-left point
         dx = subtract.reduce(x)
         # Get the upper-left and lower right corner points
         oc = x[1] + V(point2[0] * dot(dx, point2[0]),
                       point2[1] * dot(dx, point2[1]))
         # Get the four 3d cooridinates on the bottom crystal-cutting plane
         sq1 = cat(x, oc) + slab.normal * dot(slab.point, slab.normal)
         # transfer the above 4 3d coordinates in parallel to get that on
         #the top plane, put them together
         sq1 = cat(sq1, sq1 + slab.thickness * slab.normal)
         self.data = V(maximum.reduce(sq1), minimum.reduce(sq1))
     elif point2:
         # just 2 3d points
         self.data = V(maximum(point1, point2), minimum(point1, point2))
     elif point1:
         # list of points: could be 2d or 3d?  +/- 1.8 to make the bounding
         #box enclose the vDw ball of an atom?
         self.data = V(
             maximum.reduce(point1) + BBOX_MARGIN,
             minimum.reduce(point1) - BBOX_MARGIN)
     else:
         # a null bbox
         self.data = None
Beispiel #11
0
    def drawVector(self):
        coords3D = self.vector + [1]
        # apply viewing transformation to vector
        newPtsWithView = Numeric.dot([coords3D], self.viewingMat)[0]
        # compute 2D projection of vector (broken on 2 segments for
        # depth cueing
        x1 = self.xm + int(newPtsWithView[0] * (self.xm))
        y1 = self.ym + int(newPtsWithView[1] * (self.ym))

        # change vector's segments coordinates
        self.canvas.coords(self.lId1, self.xm, self.ym, x1, y1)

        # update vector shadows
        # Y=0 plane
        if self.drawShadowY:
            pt = [coords3D[0], 0, coords3D[2], 1.]
            newPtsWithView = Numeric.dot([pt], self.viewingMat)[0]
            xm = self.xm + int(newPtsWithView[0] * (self.xm))
            ym = self.ym + int(newPtsWithView[1] * (self.ym))
            if self.fillShadowPlanes:
                self.canvas.coords(self.shadowPY, self.xm, self.ym, xm, ym, x1,
                                   y1)
            self.canvas.coords(self.shadowY, self.xm, self.ym, xm, ym, x1, y1)

# X=0 plane
        if self.drawShadowX:
            pt = [0, coords3D[1], coords3D[2], 1.]
            newPtsWithView = Numeric.dot([pt], self.viewingMat)[0]
            xm = self.xm + int(newPtsWithView[0] * (self.xm))
            ym = self.ym + int(newPtsWithView[1] * (self.ym))
            if self.fillShadowPlanes:
                self.canvas.coords(self.shadowPX, self.xm, self.ym, xm, ym, x1,
                                   y1)
            self.canvas.coords(self.shadowX, self.xm, self.ym, xm, ym, x1, y1)

# Z=0 plane
        if self.drawShadowZ:
            pt = [coords3D[0], coords3D[1], 0, 1.]
            newPtsWithView = Numeric.dot([pt], self.viewingMat)[0]
            xm = self.xm + int(newPtsWithView[0] * (self.xm))
            ym = self.ym + int(newPtsWithView[1] * (self.ym))
            if self.fillShadowPlanes:
                self.canvas.coords(self.shadowPZ, self.xm, self.ym, xm, ym, x1,
                                   y1)
            self.canvas.coords(self.shadowZ, self.xm, self.ym, xm, ym, x1, y1)

        if self.vector[0] < 0.0:
            self.canvas.tag_raise('verticalCircle', 'moving')
        else:
            self.canvas.tag_lower('verticalCircle', 'moving')

        if self.vector[1] < 0.0:
            self.canvas.tag_raise('horizontalCircle', 'moving')
        else:
            self.canvas.tag_lower('horizontalCircle', 'moving')

        if self.vector[2] < 0.0 or self.vector[1] < 0.0:
            self.canvas.tag_raise('axis', 'moving')
        else:
            self.canvas.tag_lower('axis', 'moving')
Beispiel #12
0
 def rtz(self, pt):
     d = pt - self.p0
     z = dot(d, self.zn)
     d = d - z * self.zn
     r = vlen(d)
     theta = Numeric.arctan2(dot(d, self.v), dot(d, self.u))
     return Numeric.array((r, theta, z), 'd')
Beispiel #13
0
    def createCanvas(self, master, size=200):

        self.frame = Tkinter.Frame(self, relief = 'sunken', borderwidth=5)

        if self.name is not None:
            self.title = Tkinter.Label(self.frame, text=self.name)
            self.title.pack(side=self.labelSide)

	self.canvas = Tkinter.Canvas(self.frame, width=size, height=size)

        # set the focus so that we get keyboard events, and add callbacks
        self.canvas.bind('<KeyPress>', self.modifierDown)
        self.canvas.bind("<KeyRelease>", self.modifierUp)

        xm = self.xm = ym = self.ym = self.r
	self.canvas.create_oval(0, 0, size, size)
	self.canvas.create_oval(xm-(xm/4), 0, xm+(xm/4), size,
				tags='verticalCircle')
	self.canvas.create_oval(0, ym-(ym/4), size, ym+(ym/4),
				tags='horizontalCircle')

        # apply viewing transformation to vector
        XaxisWithView = Numeric.dot([(1.,0.,0.,1.)],self.viewingMat)[0]
        x1 = self.xm+int(XaxisWithView[0]*(self.xm))
        y1 = self.ym+int(XaxisWithView[1]*(self.ym))
        self.canvas.create_line(xm, ym, x1, y1, fill='red', tags='axis')

        XaxisWithView = Numeric.dot([(0.,1.,0.,1.)],self.viewingMat)[0]
        x2 = self.xm+int(XaxisWithView[0]*(self.xm))
        y2 = self.ym+int(XaxisWithView[1]*(self.ym))
        self.canvas.create_line(xm, ym, x2, y2, fill='green', tags='axis')

        XaxisWithView = Numeric.dot([(0.,0.,1.,1.)],self.viewingMat)[0]
        x3 = self.xm+int(XaxisWithView[0]*(self.xm))
        y3 = self.ym+int(XaxisWithView[1]*(self.ym))
        self.canvas.create_line(xm, ym, x3, y3, fill='blue', tags='axis')

	self.textId = self.canvas.create_text(0, size, anchor='sw', text="XY")

	# shadow line in X=0 plane
	self.shadowPX = self.canvas.create_polygon(0,0,0,0,0,0, fill='red',
					       tag='moving')
	self.shadowPY = self.canvas.create_polygon(0,0,0,0,0,0, fill='green',
					       tag='moving')
	self.shadowPZ = self.canvas.create_polygon(0,0,0,0,0,0, fill='blue',
					       tag='moving')

	self.shadowX = self.canvas.create_line(0, 0, 0, 0, fill='black',
					       tag='moving')
	self.shadowY = self.canvas.create_line(0, 0, 0, 0, fill='black',
					       tag='moving')
	self.shadowZ = self.canvas.create_line(0, 0, 0, 0, fill='black',
					       tag='moving')

	self.lId1 = self.canvas.create_line(0, 0, 0, 0, fill='black', width=3,
					    arrow='last')
	self.canvas.pack(side='top')
        self.frame.pack(expand=1, fill='x')
        self.xm = self.ym = self.r
        self.drawVector()
Beispiel #14
0
def findTransformation(x, y):
    """
    Match two arrays by rotation and translation. Returns the
    rotation matrix and the translation vector.

    @param x: first set of coordinates
    @type  x: array('f')
    @param y: second set of coordinates
    @type  y: array('f')

    @return: rotation matrix (3x3) and translation vector (1x3)
    @rtype:  array, array
    """
    ## center configurations
    x_av = N.average(x)
    y_av = N.average(y)

    x = x - x_av
    y = y - y_av


    ## svd of correlation matrix
    v, l, u = svd(N.dot(N.transpose(x), y))

    ## build rotation matrix and translation vector
    r = N.dot(v, u)

    t = x_av - N.dot(r, y_av)

    return r, t
Beispiel #15
0
def drawLinearDimension(color,      # what color are we drawing this in
                        right, up,  # screen directions mapped to xyz coords
                        bpos,       # position of the handle for moving the text
                        p0, p1,     # positions of the ends of the dimension
                        text, highlighted=False):
    outOfScreen = cross(right, up)
    bdiff = bpos - 0.5 * (p0 + p1)
    csys = CylindricalCoordinates(p0, p1 - p0, bdiff, right)
    # This works OK until we want to keep the text right side up, then the
    # criterion for right-side-up-ness changes because we've changed 'up'.
    br, bt, bz = csys.rtz(bpos)
    e0 = csys.xyz((br + 0.5, 0, 0))
    e1 = csys.xyz((br + 0.5, 0, 1))
    drawline(color, p0, e0)
    drawline(color, p1, e1)
    v0 = csys.xyz((br, 0, 0))
    v1 = csys.xyz((br, 0, 1))
    if highlighted:
        drawline(color, v0, v1, width=THICKLINEWIDTH)
    else:
        drawline(color, v0, v1)
    # draw arrowheads at the ends
    a1, a2 = 0.25, 1.0 * csys.zinv
    arrow00 = csys.xyz((br + a1, 0, a2))
    arrow01 = csys.xyz((br - a1, 0, a2))
    drawline(color, v0, arrow00)
    drawline(color, v0, arrow01)
    arrow10 = csys.xyz((br + a1, 0, 1-a2))
    arrow11 = csys.xyz((br - a1, 0, 1-a2))
    drawline(color, v1, arrow10)
    drawline(color, v1, arrow11)
    # draw the text for the numerical measurement, make
    # sure it goes from left to right
    xflip = dot(csys.z, right) < 0
    # then make sure it's right side up
    theoreticalRight = (xflip and -csys.z) or csys.z
    theoreticalOutOfScreen = cross(theoreticalRight, bdiff)
    yflip = dot(theoreticalOutOfScreen, outOfScreen) < 0
    if debug_flags.atom_debug:
        print "DEBUG INFO FROM drawLinearDimension"
        print csys
        print theoreticalRight, theoreticalOutOfScreen
        print xflip, yflip
    if yflip:
        def fx(y):
            return br + 1.5 - y / (1. * HEIGHT)
    else:
        def fx(y):
            return br + 0.5 + y / (1. * HEIGHT)
    if xflip:
        def fz(x):
            return 0.9 - csys.zinv * x / (1. * WIDTH)
    else:
        def fz(x):
            return 0.1 + csys.zinv * x / (1. * WIDTH)
    def tfm(x, y, fx=fx, fz=fz):
        return csys.xyz((fx(y), 0, fz(x)))
    f3d = Font3D()
    f3d.drawString(text, tfm=tfm, color=color)
Beispiel #16
0
    def drawVector(self):
        coords3D = self.vector + [1]
	# apply viewing transformation to vector
        newPtsWithView = Numeric.dot( [coords3D],
                                                 self.viewingMat)[0]
	# compute 2D projection of vector (broken on 2 segments for
	# depth cueing
        x1 = self.xm+int(newPtsWithView[0]*(self.xm))
        y1 = self.ym+int(newPtsWithView[1]*(self.ym))

	# change vector's segments coordinates
        self.canvas.coords(self.lId1, self.xm, self.ym, x1, y1)

	# update vector shadows
	# Y=0 plane
	if self.drawShadowY:
	    pt = [coords3D[0], 0, coords3D[2], 1.]
	    newPtsWithView = Numeric.dot( [pt], self.viewingMat)[0]
	    xm = self.xm+int(newPtsWithView[0]*(self.xm))
	    ym = self.ym+int(newPtsWithView[1]*(self.ym))
	    if self.fillShadowPlanes:
		self.canvas.coords(self.shadowPY,self.xm,self.ym,xm,ym,x1,y1)
	    self.canvas.coords(self.shadowY,self.xm,self.ym,xm,ym,x1,y1)

	# X=0 plane
	if self.drawShadowX:
	    pt = [0, coords3D[1], coords3D[2], 1.]
	    newPtsWithView = Numeric.dot( [pt], self.viewingMat)[0]
	    xm = self.xm+int(newPtsWithView[0]*(self.xm))
	    ym = self.ym+int(newPtsWithView[1]*(self.ym))
	    if self.fillShadowPlanes:
		self.canvas.coords(self.shadowPX,self.xm,self.ym,xm,ym,x1,y1)
	    self.canvas.coords(self.shadowX, self.xm, self.ym, xm, ym, x1,y1)

	# Z=0 plane
	if self.drawShadowZ:
	    pt = [coords3D[0], coords3D[1], 0, 1.]
	    newPtsWithView = Numeric.dot( [pt], self.viewingMat)[0]
	    xm = self.xm+int(newPtsWithView[0]*(self.xm))
	    ym = self.ym+int(newPtsWithView[1]*(self.ym))
	    if self.fillShadowPlanes:
		self.canvas.coords(self.shadowPZ,self.xm,self.ym,xm,ym,x1,y1)
	    self.canvas.coords(self.shadowZ, self.xm, self.ym, xm, ym, x1,y1)

	if self.vector[0]<0.0:
	    self.canvas.tag_raise('verticalCircle', 'moving')
	else:
	    self.canvas.tag_lower('verticalCircle', 'moving')

	if self.vector[1]<0.0:
	    self.canvas.tag_raise('horizontalCircle', 'moving')
	else:
	    self.canvas.tag_lower('horizontalCircle', 'moving')

	if self.vector[2]<0.0 or self.vector[1]<0.0:
	    self.canvas.tag_raise('axis', 'moving')
	else:
	    self.canvas.tag_lower('axis', 'moving')
Beispiel #17
0
def squared_distance_matrix(x, y):

    d1 = N.diagonal(N.dot(x, N.transpose(x)))
    d2 = N.diagonal(N.dot(y, N.transpose(y)))

    a1 = N.add.outer(d1,d2)
    a2 = N.dot(x, N.transpose(y))

    return a1 - 2 * a2
 def constrainedPosition(self):
     a = self.atoms
     p0, p1, p2, p3 = a[0].posn(), a[1].posn(), a[2].posn(), a[3].posn()
     axis = norm(p2 - p1)
     midpoint = 0.5 * (p1 + p2)
     return _constrainHandleToAngle(self.center() + self.handle_offset,
                                    p0 - dot(p0 - midpoint, axis) * axis,
                                    midpoint,
                                    p3 - dot(p3 - midpoint, axis) * axis)
Beispiel #19
0
 def constrainedPosition(self):
     a = self.atoms
     p0, p1, p2, p3 = a[0].posn(), a[1].posn(), a[2].posn(), a[3].posn()
     axis = norm(p2 - p1)
     midpoint = 0.5 * (p1 + p2)
     return _constrainHandleToAngle(self.center() + self.handle_offset,
                                    p0 - dot(p0 - midpoint, axis) * axis,
                                    midpoint,
                                    p3 - dot(p3 - midpoint, axis) * axis)
Beispiel #20
0
def squared_distance_matrix(x, y):

    d1 = N.diagonal(N.dot(x, N.transpose(x)))
    d2 = N.diagonal(N.dot(y, N.transpose(y)))

    a1 = N.add.outer(d1, d2)
    a2 = N.dot(x, N.transpose(y))

    return a1 - 2 * a2
Beispiel #21
0
    def rotateAboutPoint(self):
        """
        Rotates the selected entities along the specified vector, about the
        specified pivot point (pivot point it the starting point of the
        drawn vector.
        """
        
        if len(self.mouseClickPoints) != self.mouseClickLimit:
            print_compact_stack("Rotate about point bug: mouseclick points != mouseclicklimit: ")
            return
            
        
        pivotPoint = self.mouseClickPoints[0]
        ref_vec_endPoint = self.mouseClickPoints[1]
        rot_vec_endPoint = self.mouseClickPoints[2]
        
        reference_vec = norm(ref_vec_endPoint - pivotPoint)
        
        lineVector = norm(rot_vec_endPoint - pivotPoint)
                           
            
        #lineVector = endPoint - startPoint

        quat1 = Q(lineVector, reference_vec)
                
        #DEBUG Disabled temporarily . will not be used
        if dot(lineVector, reference_vec) < 0:
            theta = math.pi - quat1.angle
        else:
            theta = quat1.angle

        #TEST_DEBUG-- Works fine
        theta = quat1.angle

        rot_axis = cross(lineVector, reference_vec)
        
        
        if dot(lineVector, reference_vec) < 0:
            rot_axis = - rot_axis

        cross_prod_1 = norm(cross(reference_vec, rot_axis))
        cross_prod_2 = norm(cross(lineVector, rot_axis))

        if dot(cross_prod_1, cross_prod_2) < 0:
            quat2 = Q(rot_axis, theta)
        else:
            quat2 = Q(rot_axis, - theta)

        movables = self.graphicsMode.getMovablesForLeftDragging()
        self.assy.rotateSpecifiedMovables(
            quat2,
            movables = movables,
            commonCenter = pivotPoint)

        self.glpane.gl_update()
        return
Beispiel #22
0
def interpolate3DTransform(matrixList, indexList, percent):
    """ This function gets input of two list and a percent value.
Return value is a 4x4 matrix corresponding to percent% of the transformation.

matrixList: a list of 4x4 transformation matrix
indexList : a list of sorted index (positive float number)
percent   : a positive float number.
if only one matrix in the matrix list:
percent =   0.0  means no transformation (identity)
            1.0  means 100% of the transformation (returns mat)
            0.58 means 58% of translation and rotatetion 58% of rotation angle
            along the same rotation axis
percent can go above 1.0

If matrixList has more than one matrix:
matrixList=[M1,  M2,  M3]     #Attention: All M uses the same reference frame
indexList =[0.2, 0.5, 1.0]    #Attention: assume the list sorted ascendingly
p = 0.5 means apply M2
p = 0.8 means apply M3
p = 0.9 means apply M2 first, then apply 50% of M'.  M' is the transformation
                    from M2 to M3.   50% = (0.9-0.8) / (1.0-0.8)
                    M2 x M' = M3
                    -->  M2.inverse x M2 x M'= M2.inverse x M3 
                    -->  M'= M2.inverse x M
"""
    listLen = len(matrixList)
    if listLen != len(indexList):
        raise ValueError("matrix list should have same length of index list")
    if listLen == 0:
        raise ValueError("no matrix found in the matrix list")

    offset = -1
    for i in range(listLen):
        if indexList[i] >= percent:
            offset = i
            break

    prevMat = nextMat = N.identity(4, 'f')
    if offset == -1:
        prevMat = matrixList[-1]
        p = percent / indexList[-1]
        return _interpolateMat(matrixList[-1], p)
    elif offset == 0:
        nextMat = matrixList[0]
        p = percent / indexList[0]
        return _interpolateMat(N.array(matrixList[0]), p)
    else:
        prevMat = matrixList[offset - 1]
        nextMat = matrixList[offset]
        p = (percent - indexList[offset - 1]) / (indexList[offset] -
                                                 indexList[offset - 1])
        from numpy.oldnumeric.linear_algebra import inverse
        M = N.dot(inverse(prevMat), nextMat)
        Mat = _interpolateMat(M, p)
        return N.dot(prevMat, Mat)
Beispiel #23
0
def interpolate3DTransform(matrixList, indexList, percent):
    """ This function gets input of two list and a percent value.
Return value is a 4x4 matrix corresponding to percent% of the transformation.

matrixList: a list of 4x4 transformation matrix
indexList : a list of sorted index (positive float number)
percent   : a positive float number.
if only one matrix in the matrix list:
percent =   0.0  means no transformation (identity)
            1.0  means 100% of the transformation (returns mat)
            0.58 means 58% of translation and rotatetion 58% of rotation angle
            along the same rotation axis
percent can go above 1.0

If matrixList has more than one matrix:
matrixList=[M1,  M2,  M3]     #Attention: All M uses the same reference frame
indexList =[0.2, 0.5, 1.0]    #Attention: assume the list sorted ascendingly
p = 0.5 means apply M2
p = 0.8 means apply M3
p = 0.9 means apply M2 first, then apply 50% of M'.  M' is the transformation
                    from M2 to M3.   50% = (0.9-0.8) / (1.0-0.8)
                    M2 x M' = M3
                    -->  M2.inverse x M2 x M'= M2.inverse x M3 
                    -->  M'= M2.inverse x M
"""
    listLen = len(matrixList)
    if listLen != len(indexList):
        raise ValueError("matrix list should have same length of index list")
    if listLen == 0:
        raise ValueError("no matrix found in the matrix list")

    offset = -1
    for i in range(listLen):
        if indexList[i] >= percent:
            offset = i
            break

    prevMat = nextMat = N.identity(4,'f')
    if offset == -1:
        prevMat = matrixList[-1]
        p = percent/indexList[-1]
        return _interpolateMat(matrixList[-1], p)
    elif offset == 0:
        nextMat = matrixList[0]
        p = percent/indexList[0]
        return _interpolateMat(N.array(matrixList[0]), p)
    else:
        prevMat = matrixList[offset-1]
        nextMat = matrixList[offset]
        p = (percent-indexList[offset-1])/(
                                    indexList[offset]-indexList[offset-1])
        from numpy.oldnumeric.linear_algebra import inverse
        M = N.dot(inverse(prevMat), nextMat)
        Mat = _interpolateMat(M, p)
        return N.dot(prevMat, Mat)
Beispiel #24
0
 def project_2d_noeyeball(self, pt):
     """
     Bruce: Project a point into our plane (ignoring eyeball). Warning: arbitrary origin!
        
     Huaicai 4/20/05: This is just to project pt into a 2d coordinate 
     system (self.right, self.up) on a plane through pt and parallel to the screen 
     plane. For perspective projection, (x, y) on this plane is different than that on the plane 
     through pov.
     """
     x, y = self.right, self.up
     return V(dot(pt, x), dot(pt, y))
Beispiel #25
0
def calc_torsion_angle(atom_list):
    """
    Calculates torsional angle defined by four atoms, A1-A2-A3-A4,
    Return torsional angle value between atoms A2 and A3.
    
    @param atom_list: list of four atoms describing the torsion bond
    @type atom_list: list
    
    @return: value of the torsional angle (float)
    """
    # Note: this appears to be very general and perhaps ought to be moved to a more
    # general place (someday), perhaps VQT.py or nearby. [bruce 080828 comment]
    
    from numpy.oldnumeric import dot
    from math import atan2, pi, sqrt
    from geometry.VQT import cross
    
    if len(atom_list) != 4:
        # The list has to have four members.
        return 0.0
    
    # Calculate pairwise distances
    v12 = atom_list[0].posn() - atom_list[1].posn()
    v43 = atom_list[3].posn() - atom_list[2].posn()
    v23 = atom_list[1].posn() - atom_list[2].posn()

    # p is a vector perpendicular to the plane defined by atoms 1,2,3
    # p is perpendicular to v23_v12 plane
    p = cross(v23, v12)
    
    # x is a vector perpendicular to the plane defined by atoms 2,3,4.
    # x is perpendicular to v23_v43 plane
    x = cross(v23, v43)
    
    # y is perpendicular to v23_x plane
    y = cross(v23, x)
    
    # Calculate lengths of the x, y vectors.
    u1 = dot(x, x)
    v1 = dot(y, y)
    
    if u1 < 0.0 or \
       v1 < 0.0:
        return 360.0
    
    u2 = dot(p, x) / sqrt(u1)
    v2 = dot(p, y) / sqrt(v1)
    
    if u2 != 0.0 and \
       v2 != 0.0:
        # calculate the angle
        return atan2(v2, u2) * (180.0 / pi)
    else:
        return 360.0
Beispiel #26
0
    def rotateAboutPoint(self):
        """
        Rotates the selected entities along the specified vector, about the
        specified pivot point (pivot point it the starting point of the
        drawn vector.
        """

        if len(self.mouseClickPoints) != self.mouseClickLimit:
            print_compact_stack(
                "Rotate about point bug: mouseclick points != mouseclicklimit: "
            )
            return

        pivotPoint = self.mouseClickPoints[0]
        ref_vec_endPoint = self.mouseClickPoints[1]
        rot_vec_endPoint = self.mouseClickPoints[2]

        reference_vec = norm(ref_vec_endPoint - pivotPoint)

        lineVector = norm(rot_vec_endPoint - pivotPoint)

        #lineVector = endPoint - startPoint

        quat1 = Q(lineVector, reference_vec)

        #DEBUG Disabled temporarily . will not be used
        if dot(lineVector, reference_vec) < 0:
            theta = math.pi - quat1.angle
        else:
            theta = quat1.angle

        #TEST_DEBUG-- Works fine
        theta = quat1.angle

        rot_axis = cross(lineVector, reference_vec)

        if dot(lineVector, reference_vec) < 0:
            rot_axis = -rot_axis

        cross_prod_1 = norm(cross(reference_vec, rot_axis))
        cross_prod_2 = norm(cross(lineVector, rot_axis))

        if dot(cross_prod_1, cross_prod_2) < 0:
            quat2 = Q(rot_axis, theta)
        else:
            quat2 = Q(rot_axis, -theta)

        movables = self.graphicsMode.getMovablesForLeftDragging()
        self.assy.rotateSpecifiedMovables(quat2,
                                          movables=movables,
                                          commonCenter=pivotPoint)

        self.glpane.gl_update()
        return
Beispiel #27
0
def norm (A):
    """     Return normalized vector A.
"""
    if type(A) == types.ListType:
        A=Numeric.array(A,'f')
        res= A/Numeric.sqrt(Numeric.dot(A,A))
        return res.tolist()    
    elif type(A)==Numeric.ArrayType:    
        return A/Numeric.sqrt(Numeric.dot(A,A))    
    else:
        print "Need a list or Numeric array"
        return None
Beispiel #28
0
def norm(A):
    """     Return normalized vector A.
"""
    if type(A) == list:
        A = Numeric.array(A, 'f')
        res = A / Numeric.sqrt(Numeric.dot(A, A))
        return res.tolist()
    elif type(A) == Numeric.ArrayType:
        return A / Numeric.sqrt(Numeric.dot(A, A))
    else:
        print("Need a list or Numeric array")
        return None
Beispiel #29
0
def planeXline(ppt, pv, lpt, lv):
    """
    Find the intersection of a line (point lpt on line, unit vector lv along line)
    with a plane (point ppt on plane, unit vector pv perpendicular to plane).
    Return the intersection point, or None if the line and plane are (almost) parallel.
       WARNING: don't use a boolean test on the return value, since V(0,0,0) is a real point
    but has boolean value False. Use "point is not None" instead.
    """
    d = Numeric.dot(lv, pv)
    if abs(d) < 0.000001:
        return None
    return lpt + lv * (Numeric.dot(ppt - lpt, pv) / d)
Beispiel #30
0
 def test4Embed(self):
   arr = Numeric.array([[0,1.0,5.0],
                        [1.0,0,1.0],
                        [0.0,1.0,0]],Numeric.Float)
   self.failUnless(DG.DoTriangleSmoothing(arr))
   coords = DG.EmbedBoundsMatrix(arr,randomSeed=100);
   v1 = coords[0]-coords[1]
   v2 = coords[1]-coords[2]
   d1 = Numeric.dot(v1,v1)
   self.failUnless(feq(d1,1.0, 0.001));
   d2 = Numeric.dot(v2,v2)
   self.failUnless(feq(d2,1.0, 0.001));
Beispiel #31
0
 def test4Embed(self):
   arr = Numeric.array([[0,1.0,5.0],
                        [1.0,0,1.0],
                        [0.0,1.0,0]],Numeric.Float)
   self.assertTrue(DG.DoTriangleSmoothing(arr))
   coords = DG.EmbedBoundsMatrix(arr,randomSeed=100);
   v1 = coords[0]-coords[1]
   v2 = coords[1]-coords[2]
   d1 = Numeric.dot(v1,v1)
   self.assertTrue(feq(d1,1.0, 0.001));
   d2 = Numeric.dot(v2,v2)
   self.assertTrue(feq(d2,1.0, 0.001));
Beispiel #32
0
def ptonline(xpt, lpt, ldr):
    """
    return the point on a line (point lpt, direction ldr)
    nearest to point xpt
    """
    ldr = norm(ldr)
    return Numeric.dot(xpt - lpt, ldr) * ldr + lpt
Beispiel #33
0
    def setup_quat_center(self, atomList=None):
        """
        Setup the plane's quat using a list of atoms.

        If no atom list is supplied, the plane is centered in the glpane
        and parallel to the screen.

        @param atomList: A list of atoms.
        @type  atomList: list

        """
        if atomList:
            self.atomPos = []
            for a in atomList:
                self.atomPos += [a.posn()]
            planeNorm = self._getPlaneOrientation(self.atomPos)
            if dot(planeNorm, self.glpane.lineOfSight) < 0:
                planeNorm = -planeNorm
            self.center = add.reduce(self.atomPos) / len(self.atomPos)
            self.quat = Q(V(0.0, 0.0, 1.0), planeNorm)
        else:
            self.center = V(0.0, 0.0, 0.0)
            # Following makes sure that Plane edges are parallel to
            # the 3D workspace borders. Fixes bug 2448
            x, y, z = self.glpane.right, self.glpane.up, self.glpane.out
            self.quat = Q(x, y, z)
            self.quat += Q(self.glpane.right, pi)
Beispiel #34
0
def pca(data):

    transposed = 0

    if shape(data)[0] < shape(data)[1]:
        transposed = 1
        data = transpose(data)
        
    cov = dot(transpose(data), data)

    ## eigenvectors are row vectors
    val, vec = eigenvectors(cov)

    try:
        val = val.real
    except:
        pass

    try:
        vec = vec.real
    except:
        pass

    order = argsort(val)

    val = Numeric.take(val, order)
    vec = Numeric.take(vec, order)

    pc = Numeric.dot(data, transpose(vec))

    if transposed:
        pc = Numeric.transpose(pc)
    
    return val, vec, pc
Beispiel #35
0
def pca(data):

    transposed = 0

    if shape(data)[0] < shape(data)[1]:
        transposed = 1
        data = transpose(data)

    cov = dot(transpose(data), data)

    ## eigenvectors are row vectors
    val, vec = eigenvectors(cov)

    try:
        val = val.real
    except:
        pass

    try:
        vec = vec.real
    except:
        pass

    order = argsort(val)

    val = Numeric.take(val, order)
    vec = Numeric.take(vec, order)

    pc = Numeric.dot(data, transpose(vec))

    if transposed:
        pc = Numeric.transpose(pc)

    return val, vec, pc
Beispiel #36
0
    def _mapToSphere (self, NewPt):
        # Given a new window coordinate, will modify NewVec in place
        X = 0
        Y = 1
        Z = 2

        NewVec = Vector3fT ()
        # //Copy paramter into temp point
        TempPt = copy.copy (NewPt)
        # //Adjust point coords and scale down to range of [-1 ... 1]
        TempPt [X] = (NewPt [X] * self.m_AdjustWidth) - 1.0
        TempPt [Y] = 1.0 - (NewPt [Y] * self.m_AdjustHeight)
        # //Compute the square of the length of the vector to the point from the center
        
        length = Numeric.sum (Numeric.dot (TempPt, TempPt))
        # //If the point is mapped outside of the sphere... (length > radius squared)
        if (length > 1.0):
            # //Compute a normalizing factor (radius / sqrt(length))
            norm    = 1.0 / sqrt (length);

            # //Return the "normalized" vector, a point on the sphere
            NewVec [X] = TempPt [X] * norm;
            NewVec [Y] = TempPt [Y] * norm;
            NewVec [Z] = 0.0;
        else:            # //Else it's on the inside
            # //Return a vector to a point mapped inside the sphere sqrt(radius squared - length)
            NewVec [X] = TempPt [X]
            NewVec [Y] = TempPt [Y]
            NewVec [Z] = sqrt (1.0 - length)

        return NewVec
Beispiel #37
0
def inverse4X4(matrix):
    """ returns the inverse of the given 4x4 transformation matrix
t_1: the negetive of Translation vector
r_1: the inverse of rotation matrix

inversed transformation is
1) t_1 applied first
2) then r_1 is applied

to validate the result, N.dot(matrix, mat_inverse)==N.identity(4,'f')
"""
    # check the shape
    if matrix.shape != (4, 4) and matrix.shape != (16, ):
        raise ValueError("Argument must Numeric array of shape (4,4) or (16,)")
        return None
    if matrix.shape == (16, ):
        matrix = N.array(matrix, 'f')
        matrix = N.reshape(matrix, (4, 4))  # force the matrix to be (4,4)
    t_1 = N.identity(4, 'f')
    t_1[:2, 3] = -matrix[:2, 3]
    r_1 = N.identity(4, 'f')
    r_1[:3, :3] = N.transpose(matrix[:3, :3])
    mat_inverse = N.dot(r_1, t_1)
    #asert N.dot(matrix, mat_inverse) is N.identity(4,'f')
    return mat_inverse
    def update_numberOfBases(self):
        """
        Updates the numberOfBases in the PM while a resize handle is being 
        dragged. 
        @see: self.getCursorText() where it is called. 
        """
        #@Note: originally (before 2008-04-05, it was called in 
        #DnaStrand_ResizeHandle.on_drag() but that 'may' have some bugs 
        #(not verified) also see self.getCursorText() to know why it is
        #called there (basically a workaround for bug 2729
        if self.grabbedHandle is None:
            return

        currentPosition = self.grabbedHandle.currentPosition
        resize_end = self.grabbedHandle.origin

        new_duplexLength = vlen( currentPosition - resize_end )

        numberOfBasePairs_to_change = getNumberOfBasePairsFromDuplexLength('B-DNA', 
                                                                           new_duplexLength)

        original_numberOfBases = self.struct.getNumberOfBases()
        #If the dot product of handle direction and the direction in which it 
        #is dragged is negative, this means we need to subtract bases
        direction_of_drag = norm(currentPosition - resize_end)
        if dot(self.grabbedHandle.direction, direction_of_drag ) < 0:
            total_number_of_bases = original_numberOfBases - numberOfBasePairs_to_change
            self.propMgr.numberOfBasesSpinBox.setValue(total_number_of_bases)
        else:
            total_number_of_bases = original_numberOfBases + numberOfBasePairs_to_change
            self.propMgr.numberOfBasesSpinBox.setValue(total_number_of_bases - 1)
Beispiel #39
0
    def __CM_Align_to_chunk(self):
        """
        Rotary or Linear Motor context menu command: "Align to chunk"
        This uses the chunk connected to the first atom of the motor.
        """
        # I needed this when attempting to simulate the rotation of a long, skinny
        # chunk.  The axis computed from the attached atoms was not close to the axis
        # of the chunk.  I figured this would be a common feature that was easy to add.
        # 
        ##e it might be nice to dim this menu item if the chunk's axis hasn't moved since this motor was made or recentered;
        # first we'd need to extend the __CM_ API to make that possible. [mark 050717]

        cmd = greenmsg("Align to Chunk: ")

        chunk = self.atoms[0].molecule # Get the chunk attached to the motor's first atom.
        # wware 060116 bug 1330
        # The chunk's axis could have its direction exactly reversed and be equally valid.
        # We should choose between those two options for which one has the positive dot
        # product with the old axis, to avoid reversals of motor direction when going
        # between "align to chunk" and "recenter on atoms".
        #bruce 060116 modified this fix to avoid setting axis to V(0,0,0) if it's perpendicular to old axis.
        newAxis = chunk.getaxis()
        if dot(self.axis,newAxis) < 0:
            newAxis = - newAxis
        self.axis = newAxis
        self.assy.changed()   # wware 060116 bug 1331 - assembly changed when axis changed

        info = "Aligned motor [%s] on chunk [%s]" % (self.name, chunk.name) 
        env.history.message( cmd + info ) 
        self.assy.w.win_update()

        return
Beispiel #40
0
 def __init__(self, crv, vector):
     if not isinstance(crv, Crv.Crv):
         raise NURBSError, 'Parameter crv not derived from Crv class!'
     coefs = numerix.zeros((4, crv.cntrl.shape[1], 2), numerix.Float)
     coefs[:, :, 0] = crv.cntrl
     coefs[:, :, 1] = numerix.dot(translate(vector), crv.cntrl)
     Srf.__init__(self, coefs, crv.uknots, [0., 0., 1., 1.])
Beispiel #41
0
    def rotate(self, rot, coords):
        """Apply rotation to the coordinates. Rotation can be a 3x3 matrix or
        3 Euler angles"""

        if isinstance(rot[0], types.FloatType):
            rot = EulerAnglesToMat(rot)
        return Numeric.dot(coords, Numeric.transpose(rot)) 
Beispiel #42
0
    def viewParallelTo(self):
        """
        Set view parallel to the vector defined by 2 selected atoms.
        """
        cmd = greenmsg("Set View Parallel To: ")

        atoms = self.assy.selatoms_list()

        if len(atoms) != 2:
            msg = redmsg("You must select 2 atoms.")
            env.history.message(cmd + msg)
            return

        v = norm(atoms[0].posn() - atoms[1].posn())

        if vlen(v) < 0.0001:  # Atoms are on top of each other.
            info = 'The selected atoms are on top of each other.  No change in view.'
            env.history.message(cmd + info)
            return

        # If vec is pointing into the screen, negate (reverse) vec.
        if dot(v, self.glpane.lineOfSight) > 0:
            v = -v

        # Compute the destination quat (q2).
        q2 = Q(V(0, 0, 1), v)
        q2 = q2.conj()

        self.glpane.rotateView(q2)

        info = 'View set parallel to the vector defined by the 2 selected atoms.'
        env.history.message(cmd + info)
    def doit(self, atom1, atom2, angle, mov_atoms, returnVal=0):
        mol = atom1.top
        if mov_atoms is None:
            mov_atoms = mol.subTree(atom1, atom2, mol.allAtoms)
        assert len(mov_atoms)
        mov_coords = Numeric.array(mov_atoms.coords)
        lenCoords = len(mov_coords)
        x = Numeric.array(atom1.coords)
        y = Numeric.array(atom2.coords)
        rot = (angle * 3.14159/180.)%(2 * Numeric.pi)
        matrix = rotax(x, y, rot)
        _ones = Numeric.ones(lenCoords, 'f')
        _ones.shape = (lenCoords,1)
        mov_coords = Numeric.concatenate((mov_coords, _ones),1)
        newcoords = Numeric.dot(mov_coords, matrix)
        nc = newcoords[:,:3].astype('f')
        for i in range(lenCoords):
            at = mov_atoms[i]
            at._coords[at.conformation] = nc[i].tolist()

        event = EditAtomsEvent('coords', mov_atoms)
        self.vf.dispatchEvent(event)

        #have to return nc for setTorsionGC
        if returnVal:
            return nc
Beispiel #44
0
    def viewParallelTo(self):
        """
        Set view parallel to the vector defined by 2 selected atoms.
        """
        cmd = greenmsg("Set View Parallel To: ")

        atoms = self.assy.selatoms_list()

        if len(atoms) != 2:
            msg = redmsg("You must select 2 atoms.")
            env.history.message(cmd + msg)
            return

        v = norm(atoms[0].posn()-atoms[1].posn())

        if vlen(v) < 0.0001: # Atoms are on top of each other.
            info = 'The selected atoms are on top of each other.  No change in view.'
            env.history.message(cmd + info)
            return

        # If vec is pointing into the screen, negate (reverse) vec.
        if dot(v, self.glpane.lineOfSight) > 0:
            v = -v

        # Compute the destination quat (q2).
        q2 = Q(V(0,0,1), v)
        q2 = q2.conj()

        self.glpane.rotateView(q2)

        info = 'View set parallel to the vector defined by the 2 selected atoms.'
        env.history.message(cmd + info)
Beispiel #45
0
    def doit(self, nodes):
        if len(nodes) == 0:
            return 'ERROR'  # prevent logging if nothing was picked
        vt = self.vf.transformedCoordinatesWithInstances(nodes)
        g = [0., 0., 0.]
        i = 0
        for v in vt:
            g[0] += v[0]
            g[1] += v[1]
            g[2] += v[2]
            i += 1
        g[0] = g[0] / i
        g[1] = g[1] / i
        g[2] = g[2] / i

        vi = self.vf.GUI.VIEWER
        if vi.redirectTransformToRoot or vi.currentObject == vi.rootObject:
            self.vf.centerGeom(vi.rootObject,
                               g,
                               topCommand=0,
                               log=1,
                               setupUndo=1)
        else:
            m = vi.currentObject.GetMatrixInverse(root=vi.currentObject)
            g.append(1.0)
            g = Numeric.dot(m, g)[:3]
            self.vf.centerGeom(vi.currentObject,
                               g,
                               topCommand=0,
                               log=1,
                               setupUndo=1)
Beispiel #46
0
 def closest_pt_params_to_ray(self, ray):
     ""
     p2, v2 = ray.params # note: at first I wrote self.params() (using method not attr)
     p1, v1 = self.params
     # do some math, solve for k in p1 + k * v1 = that point (remember that the vecs can be of any length):
     # way 1: express p2-p1 as a weighted sum of v1, v2, cross(v1,v2), then take the v1 term in that sum and add it to p1.
     # way 2: There must be a NumPy function that would just do this in about one step...
     # way 3: or maybe we can mess around with dot(v1,v2) sort of like in corner_analyzer in demo_polygon...
     # way 4: or we could google for "closest points on two lines" or so...
     # way 5: or we could call it the intersection of self with the plane containing p2, and directions v2 and the cross prod,
     # and use a formula in VQT. Yes, that may not be self-contained but it's fastest to code!
     v1n = norm(v1)
     v2n = norm(v2)
     perp0 = cross(v1n, v2n)
     if vlen(perp0) < 0.01:
         ##k btw what if the lines are parallel, in what way should we fail?
         # and for that matter what if they are *almost* parallel so that we're too sensitive -- do we use an env param
         # to decide whether to fail in that case too? If we're an Instance we could do that from self.env... #e
         print "closest_pt_params_to_ray: too sensitive, returning None" ###### teach caller to handle this; let 0.01 be option
         return None
     perpn = norm(perp0)
     perpperp = cross(perpn,v2n)
     inter = planeXline(p2, perpperp, p1, v1n) # intersect plane (as plane point and normal) with line (as point and vector)
     if inter is None:
         print "inter is None (unexpected); data:",p1,v1,p2,v2,perp0
         return None
     # inter is the retval for a variant which just wants the closest point itself, i.e. closest_pt_to_ray
     return dot(inter - p1, v1n) / vlen(v1)
Beispiel #47
0
    def doit(self, atom1, atom2, angle, mov_atoms, returnVal=0):
        mol = atom1.top
        if mov_atoms is None:
            mov_atoms = mol.subTree(atom1, atom2, mol.allAtoms)
        assert len(mov_atoms)
        mov_coords = Numeric.array(mov_atoms.coords)
        lenCoords = len(mov_coords)
        x = Numeric.array(atom1.coords)
        y = Numeric.array(atom2.coords)
        rot = (angle * 3.14159 / 180.) % (2 * Numeric.pi)
        matrix = rotax(x, y, rot)
        _ones = Numeric.ones(lenCoords, 'f')
        _ones.shape = (lenCoords, 1)
        mov_coords = Numeric.concatenate((mov_coords, _ones), 1)
        newcoords = Numeric.dot(mov_coords, matrix)
        nc = newcoords[:, :3].astype('f')
        for i in range(lenCoords):
            at = mov_atoms[i]
            at._coords[at.conformation] = nc[i].tolist()

        event = EditAtomsEvent('coords', mov_atoms)
        self.vf.dispatchEvent(event)

        #have to return nc for setTorsionGC
        if returnVal:
            return nc
Beispiel #48
0
    def recompute_geom_both_ends_constrained(self):
        """
        Using self.b0L_pvec and self.chain_quat_cum and self.bm1R_pvec,
        figure out self.twist...
        [used for rings, and for linear chains with both ends constrained]
        """
        bonds = self.listb
        # what pvec would we have on the right end of the chain, if there were no per-bond twist?
        bm1R_pvec_no_twist = self.chain_quat_cum.rot( self.b0L_pvec ) # note, this is a vector perp to bond[-1]
        axism1 = self.axes[-1]
        # what twist is needed to put that vector over the actual one (or its neg), perhaps with 90-deg offset?
        i = len(bonds) - 1
##        if self.twist90 and i % 2 == 1:
##            bm1R_pvec_no_twist = norm(cross(axism1, bm1R_pvec_no_twist))
        # use negative if that fits better
        if dot(bm1R_pvec_no_twist, self.bm1R_pvec) < 0:
            bm1R_pvec_no_twist = - bm1R_pvec_no_twist
        # total twist is shared over every bond
        # note: we care which direction we rotate around axism1
        total_twist = twistor_angle( axism1, bm1R_pvec_no_twist, self.bm1R_pvec)
            # in radians; angular range is undefined, for now
            # [it's actually +- 2pi, twice what it would need to be in general],
            # so we need to coerce it into the range we want, +- pi/2 (90 degrees); here too we use the fact
            # that in this case, a twist of pi (180 degrees) is the same as 0 twist.
        while total_twist > math.pi/2:
            total_twist -= math.pi
        while total_twist <= - math.pi/2:
            total_twist += math.pi
        self.twist = total_twist / len(bonds)
        return
    def doit(self,mobAtoms):
        """
mobAtoms: AtomSet that is being frozen.
Assuming the AtomSet are from same molecule
        """

        # fixme: need checking for mat (matrix) and mobAtoms
        geomContainer = mobAtoms[0].top.geomContainer
        mGeom = geomContainer.masterGeom
        mat = mGeom.rotation
        mat = Numeric.reshape(mat, (4,4))

        # update coords
        mobAtoms = mobAtoms.findType(Atom)
        coords = mobAtoms.coords
        hCoords = Numeric.concatenate((coords,Numeric.ones((len(coords),1),\
                                                            'd')), 1)
        tCoords = Numeric.dot(hCoords, mat)[:,:3]
        tCoords = tCoords.tolist()
        mobAtoms.updateCoords(tCoords, 0) # overwritten the original coords
        
        # reset the rotation matrix of masterGeom
        identity = Numeric.identity(4,'f').ravel()
        mGeom.SetRotation(Numeric.identity(4,'f').ravel() ) 

        event = EditAtomsEvent('coords', mobAtoms)
        self.vf.dispatchEvent(event)
        
        mGeom.viewer.Redraw()
        
        return
Beispiel #50
0
 def __init__(self, crv, vector):
     if not isinstance(crv, Crv.Crv):
         raise NURBSError, 'Parameter crv not derived from Crv class!'
     coefs = numerix.zeros((4,crv.cntrl.shape[1],2), numerix.Float)
     coefs[:,:,0] = crv.cntrl
     coefs[:,:,1] = numerix.dot(translate(vector), crv.cntrl)
     Srf.__init__(self, coefs, crv.uknots, [0., 0., 1., 1.])
Beispiel #51
0
    def ConcatRotation(self, matrix):
        """Overwrite rotation methods"""

        self._modified = True
        Transformable.ConcatRotation(self, matrix)
        self.rotation.shape = (4, 4)
        #eqn = Numeric.array(self.rotation[0,:3]) # because direction is (1.,0.,0.)
        eqn = numpy.dot(self.direction, self.rotation)
        #print '================================================='
        #print 'eqn', eqn, eqn.shape

        #self.n = 1.0 / sqrt( Numeric.add.reduce(eqn*eqn) )
        x, y, z = eqn[:3]
        self.n = 1.0 / sqrt(x * x + y * y + z * z)
        self.eqn[:3] = eqn[:3]
        #print 'self.eqn',self.eqn
        self.eqn[3] = -Numeric.dot(self.eqn[:3], self.translation)
        #print self.eqn

        #get the value so that the plane is equivalent to having the proper
        #normal vector and a translation from the origin along the vector
        for o in self.copyXform:
            o._NormalizeN()
        self.rotation.shape = (16, )
        self.viewer.deleteOpenglList()
    def doit(self, mobAtoms):
        """
mobAtoms: AtomSet that is being frozen.
Assuming the AtomSet are from same molecule
        """

        # fixme: need checking for mat (matrix) and mobAtoms
        geomContainer = mobAtoms[0].top.geomContainer
        mGeom = geomContainer.masterGeom
        mat = mGeom.rotation
        mat = Numeric.reshape(mat, (4, 4))

        # update coords
        mobAtoms = mobAtoms.findType(Atom)
        coords = mobAtoms.coords
        hCoords = Numeric.concatenate((coords,Numeric.ones((len(coords),1),\
                                                            'd')), 1)
        tCoords = Numeric.dot(hCoords, mat)[:, :3]
        tCoords = tCoords.tolist()
        mobAtoms.updateCoords(tCoords, 0)  # overwritten the original coords

        # reset the rotation matrix of masterGeom
        identity = Numeric.identity(4, 'f').ravel()
        mGeom.SetRotation(Numeric.identity(4, 'f').ravel())

        event = EditAtomsEvent('coords', mobAtoms)
        self.vf.dispatchEvent(event)

        mGeom.viewer.Redraw()

        return