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)
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)
def __applyTorsion(self, node, parent_mtx): """Transform the subtree rooted at node. The new torsion angle must be pre-set. Children of the node are transformed recursively. """ # get rotation matrix for node # my_mtx = self.rotax(node) mtx = rotax( Numeric.array(node.a.coords), Numeric.array(node.b.coords), node.angle * self.rads_per_degree, transpose=1) # node_mtx = Numeric.dot(parent_mtx, mtx) node_mtx = self.mult4_3Mat(parent_mtx, mtx) # set-up for the transformation mm11 = node_mtx[0][0]; mm12 = node_mtx[0][1]; mm13 = node_mtx[0][2] mm21 = node_mtx[1][0]; mm22 = node_mtx[1][1]; mm23 = node_mtx[1][2] mm31 = node_mtx[2][0]; mm32 = node_mtx[2][1]; mm33 = node_mtx[2][2] mm41 = node_mtx[3][0]; mm42 = node_mtx[3][1]; mm43 = node_mtx[3][2] atomSet = node.atomSet # transform the coordinates for the node for i in node.atomRange: x,y,z = node.coords[i][:3] # get origin-subtracted originals c = atomSet[i].coords c[0] = x*mm11 + y*mm21 + z*mm31 + mm41 c[1] = x*mm12 + y*mm22 + z*mm32 + mm42 c[2] = x*mm13 + y*mm23 + z*mm33 + mm43 # recurse through children for child in node.children: self.__applyTorsion(child, node_mtx)
def setValue(self, value): #print 'Rotate by', value mat = rotax((0, 0, 0), self.axis, value * math.pi / 180.) object = self.object object.ConcatRotation(mat.flatten()) if isinstance(object, Camera): object.Redraw()
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
def setValue(self, value): #print 'Rotate by', value mat = rotax( (0,0,0), self.axis, value*math.pi/180.) object = self.object object.ConcatRotation(mat.flatten()) if isinstance(object, Camera): object.Redraw()
def mouseMove(self, event): # simple trackball, only works inside cirle # creates an XY rotation defined by pts intersecting the spheres xc = event.x - self.xm yc = self.ym - event.y # compute the intersection point between xc2 = xc*xc yc2 = yc*yc z2 = self.r2-xc2-yc2 if z2 < 0: lInvMag = 1./math.sqrt(xc2 + yc2) xc *= lInvMag * (self.r) yc *= lInvMag * (self.r) z2 = 0 # compute rotation angle a = self.lastPt3D b = (xc, yc, math.sqrt(z2)) ang = math.acos((a[0]*b[0]+a[1]*b[1]+a[2]*b[2])/self.r2) if self.mode=='XY': #compute rotation axis rotaxis = Numeric.array( (a[1]*b[2] - a[2]*b[1], a[2]*b[0] - a[0]*b[2], a[0]*b[1] - a[1]*b[0] ), 'f' ) elif self.mode=='X': rotaxis = Numeric.array( (1.,0.,0.), 'f') elif self.mode=='Y': rotaxis = Numeric.array( (0.,1.,0.), 'f') elif self.mode=='Z': rotaxis = Numeric.array( (0.,0.,1.), 'f') mat = rotax( self.zeros, rotaxis, ang ) self.lastPt3D = b self.updateVector(mat)
def mouseMove(self, event): # simple trackball, only works inside cirle # creates an XY rotation defined by pts intersecting the spheres xc = event.x - self.xm yc = self.ym - event.y # compute the intersection point between xc2 = xc * xc yc2 = yc * yc z2 = self.r2 - xc2 - yc2 if z2 < 0: lInvMag = 1. / math.sqrt(xc2 + yc2) xc *= lInvMag * (self.r) yc *= lInvMag * (self.r) z2 = 0 # compute rotation angle a = self.lastPt3D b = (xc, yc, math.sqrt(z2)) ang = math.acos((a[0] * b[0] + a[1] * b[1] + a[2] * b[2]) / self.r2) if self.mode == 'XY': #compute rotation axis rotaxis = numpy.array( (a[1] * b[2] - a[2] * b[1], a[2] * b[0] - a[0] * b[2], a[0] * b[1] - a[1] * b[0]), 'f') elif self.mode == 'X': rotaxis = numpy.array((1., 0., 0.), 'f') elif self.mode == 'Y': rotaxis = numpy.array((0., 1., 0.), 'f') elif self.mode == 'Z': rotaxis = numpy.array((0., 0., 1.), 'f') mat = rotax(self.zeros, rotaxis, ang) self.lastPt3D = b self.updateVector(mat)
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
def rotateObject(): from mglutil.math.rotax import rotax from math import sin, cos, pi, sqrt, fabs import random degtorad = pi/180. point1 = [random.random()*8-4, random.random()*8-4.,random.random()*10-5] point2 = [random.random()*8-4, random.random()*8-4.,random.random()*10-5.] angle = random.random()*360. transf = rotax(point1, point2, angle*degtorad, transpose=1) from mglutil.math.rotax import mat_to_axis_angle vector , pp, angle = mat_to_axis_angle(transf) from FlexTree.FTMotions import FTMotion_Hinge motion = FTMotion_Hinge(axis={'vector':vector,'point':pp}) motion.configure(angle=angle) m1=Numeric.array(motion.getMatrix()).ravel() m2=transf.ravel() bSame = True for i in range(len(m1)): if fabs(m1[i]-m2[i]) > 1e-4: bSame = False assert (bSame, True)
def getRotMatrix(self, shape=(4,4), transpose = None): """return the rotation matrix as a array of shape shape. """ try: assert( shape in [ (3,3), (4,4), (9,), (16,)] ) except: raise ValueError('shape must be (3,3), (4,4), (9,) or (16,)') # get the inverse 4x4 from rotax mtx = rotax.rotax(numpy.array([0.,0.,0.],'f'),self.pure,2*numpy.arccos(self.real)) # strip if necessary if shape in ((3,3),(9,)): mtx = [x[:3] for x in mtx] mtx = mtx[:3] if not transpose: return numpy.reshape(numpy.transpose(mtx),shape) else: return numpy.reshape(mtx,shape)
def setRelativeTorsion(atom1, atom2, angle): #mov_atoms=None): #rat1, rat2, ??30degrees?? 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()
def setRelativeTorsion(atom1, atom2, angle): #mov_atoms=None): #rat1, rat2, ??30degrees?? 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()
def getRotMatrix(self, shape=(4,4), transpose = None): """return the rotation matrix as a Numeric array of shape shape. """ try: assert( shape in [ (3,3), (4,4), (9,), (16,)] ) except: raise ValueError('shape must be (3,3), (4,4), (9,) or (16,)') # get the inverse 4x4 from rotax mtx = rotax.rotax(N.array([0.,0.,0.],'f'),self.pure,2*N.arccos(self.real)) # strip if necessary if shape in ((3,3),(9,)): mtx = map(lambda x: x[:3],mtx) mtx = mtx[:3] if not transpose: return N.reshape(N.transpose(mtx),shape) else: return N.reshape(mtx,shape)
def getMatrices(self): matrices = [] r = self.hrise v = self.vector p = self.point rv = (r*v[0], r*v[1], r*v[2]) ## does not work .. some weird problem with the angle (MS) # build one increment of transformation ## R = Transformation( ## trans=[rv[0], rv[1], rv[2]], ## quaternion=[v[0], v[1], v[2], self.angle*180/math.pi]) ## T = Transformation(trans=self.point) ## transform1 = T * R * T.inverse() ## transform = T * R * T.inverse() ## matrices.append( transform.getMatrix() ) ## for i in range(self.copies-1): ## transform = transform*transform1 ## matrices.append( transform.getMatrix() ) # build rotation and translation matrix about helical axis going # rot matrix C style R = rotax( p, [p[0]+v[0], p[1]+v[1], p[2]+v[2]], self.angle, False) riseMat = Numeric.identity(4).astype('f') riseMat[:3, 3] = rv # add the rise transform = Numeric.dot(riseMat, R) N = Numeric matrices.append( N.identity(4).astype('f')) for i in range(1,self.copies): mat = matrices[i-1] mat = Numeric.dot(mat, transform) matrices.append(mat) return matrices
## Automatically adapted for numpy.oldnumeric Jul 23, 2007 by # # collection of standard 4x4 rotation matrices # about the X, Y and Z axis of 10, 30, 45, 90, 180 degrees # rotations = { } import math, numpy.oldnumeric as Numeric from mglutil.math.rotax import rotax orig = Numeric.array( (0,0,0), 'f') X = Numeric.array( (1,0,0), 'f') Y = Numeric.array( (0,1,0), 'f') Z = Numeric.array( (0,0,1), 'f') for angle in [1, 5, 10, 30, 45, 90, 180]: rotations['X'+str(angle)] = rotax( orig, X, angle*math.pi/180.) rotations['X-'+str(angle)] = rotax( orig, X, -angle*math.pi/180.) for angle in [1, 5, 10, 30, 45, 90, 180]: rotations['Y'+str(angle)] = rotax( orig, Y, angle*math.pi/180.) rotations['Y-'+str(angle)] = rotax( orig, Y, -angle*math.pi/180.) for angle in [1, 5, 10, 30, 45, 90, 180]: rotations['Z'+str(angle)] = rotax( orig, Z, angle*math.pi/180.) rotations['Z-'+str(angle)] = rotax( orig, Z, -angle*math.pi/180.)
else: print 'Sorry! Unable to write this filetype->', filetype center = Numeric.add.reduce(mol.allAtoms.coords)/len(mol.allAtoms) crds = Numeric.array(mol.allAtoms.coords) center = Numeric.add.reduce(crds)/len(mol.allAtoms) crds = crds - center crds = crds.tolist() mol.allAtoms.updateCoords(crds) lenCoords = len(crds) #rotate the atoms here if axis is not None and angle is not None: rot = (float(angle)* 3.14159/180.)%(2 * Numeric.pi) x = Numeric.array([0.,0.,0.]) y = Numeric.array(map(float,axis.split(','))) matrix = rotax(x,y, rot) _ones = Numeric.ones(lenCoords, 'f') _ones.shape = (lenCoords,1) mov_coords = Numeric.concatenate((crds, _ones),1) newcoords = Numeric.dot(mov_coords, matrix) nc = newcoords[:,:3].astype('f') for i in range(lenCoords): mol.allAtoms[i]._coords[0] = nc[i].tolist() else: if rotation=='z': #for rotation around z-axis: for a in mol.allAtoms: a._coords[0][0] = -1.*a._coords[0][0] a._coords[0][1] = -1.*a._coords[0][1] elif rotation=='y': #for rotation around y-axis:
def getMatrices(self): pt1 = self.point v1 = self.vector r1 = self.hrise pt2 = self.point2 v2 = self.vector2 r2 = self.hrise2 nbCopies = self.copies matrices1 = [] # overall helical transfomations matrices2 = [] # local helical transformations rv1 = (r1*v1[0], r1*v1[1], r1*v1[2]) # tanslation vector 1 rv2 = (r2*v2[0], r2*v2[1], r2*v2[2]) # tanslation vector 2 # rotation matrix for helix 1 R = rotax( pt1, [pt1[0]+v1[0], pt1[1]+v1[1], pt1[2]+v1[2]], self.angle, False) # rise transformation for helix 1 riseMat1 = numpy.identity(4).astype('f') riseMat1[:3, 3] = rv1 # add the rise # helical step for helix 1 transform1 = numpy.dot(riseMat1, R) # first transformation is didentity for both helices matrices1.append( numpy.identity(4).astype('f') ) matrices2.append( numpy.identity(4).astype('f') ) ang2 = self.angle2 # angle for helix 2 # loop over number of copies for i in range(1,nbCopies): # take previous transfromation mat = matrices1[i-1] # add 1 helic step for overall helix mat = numpy.dot(mat, transform1) # save this in transformation for overall helix matrices1.append(mat) # move the point defining local helix along first helical axis p2t = (pt2[0]+(i*rv1[0]), pt2[1]+(i*rv1[1]), pt2[2]+(i*rv1[2])) # build local helix rotation R = rotax( p2t, [p2t[0]+v2[0], p2t[1]+v2[1], p2t[2]+v2[2]], ang2, False) # build local helix raise riseMat2 = numpy.identity(4).astype('f') riseMat2[:3, 3] = rv2 # add the rise # build helical step for local helix transform2 = numpy.dot(riseMat2, R) mat = matrices2[i-1] # apply step to previous helical step mat = numpy.dot(mat, transform2) matrices2.append(mat) # combine the overall helix wioth the local helix results = [] results.append(numpy.identity(4).astype('f') ) for i in range(1,nbCopies): results.append( numpy.dot(matrices2[i], matrices1[i]) ) return results
else: print('Sorry! Unable to write this filetype->', filetype) center = numpy.add.reduce(mol.allAtoms.coords) / len(mol.allAtoms) crds = numpy.array(mol.allAtoms.coords) center = numpy.add.reduce(crds) / len(mol.allAtoms) crds = crds - center crds = crds.tolist() mol.allAtoms.updateCoords(crds) lenCoords = len(crds) #rotate the atoms here if axis is not None and angle is not None: rot = (float(angle) * 3.14159 / 180.) % (2 * numpy.pi) x = numpy.array([0., 0., 0.]) y = numpy.array(list(map(float, axis.split(',')))) matrix = rotax(x, y, rot) _ones = numpy.ones(lenCoords, 'f') _ones.shape = (lenCoords, 1) mov_coords = numpy.concatenate((crds, _ones), 1) newcoords = numpy.dot(mov_coords, matrix) nc = newcoords[:, :3].astype('f') for i in range(lenCoords): mol.allAtoms[i]._coords[0] = nc[i].tolist() else: if rotation == 'z': #for rotation around z-axis: for a in mol.allAtoms: a._coords[0][0] = -1. * a._coords[0][0] a._coords[0][1] = -1. * a._coords[0][1] elif rotation == 'y': #for rotation around y-axis:
## Automatically adapted for numpy.oldnumeric Jul 23, 2007 by # # collection of standard 4x4 rotation matrices # about the X, Y and Z axis of 10, 30, 45, 90, 180 degrees # rotations = {} import math, numpy.oldnumeric as Numeric from mglutil.math.rotax import rotax orig = Numeric.array((0, 0, 0), 'f') X = Numeric.array((1, 0, 0), 'f') Y = Numeric.array((0, 1, 0), 'f') Z = Numeric.array((0, 0, 1), 'f') for angle in [1, 5, 10, 30, 45, 90, 180]: rotations['X' + str(angle)] = rotax(orig, X, angle * math.pi / 180.) rotations['X-' + str(angle)] = rotax(orig, X, -angle * math.pi / 180.) for angle in [1, 5, 10, 30, 45, 90, 180]: rotations['Y' + str(angle)] = rotax(orig, Y, angle * math.pi / 180.) rotations['Y-' + str(angle)] = rotax(orig, Y, -angle * math.pi / 180.) for angle in [1, 5, 10, 30, 45, 90, 180]: rotations['Z' + str(angle)] = rotax(orig, Z, angle * math.pi / 180.) rotations['Z-' + str(angle)] = rotax(orig, Z, -angle * math.pi / 180.)