Example #1
0
    def rotation(self,n,angles=False):
        """
        Rotate around two axes:
        first around 'unit cell axis' for chirality
        and then around 'torus axis' for twisting..
        Returns the rotation matrix.

        If angles==True, return (theta,phi,angle), where (theta,phi)
        gives the rotation axis and 'angle' the rotation angle.

        Approximate tangential vector by a mean tangential vector
        (-sin(angle/2),cos(angle/2),0)
        """
        if n[2]==0:
            return np.eye(3)
        bend,twist = [self.get(k) for k in ['bend_angle','twist_angle']]
        rot1 = rotation_matrix(self.baxis,n[2]*bend)
        a = self.get('bend_angle')
        taxis = np.array([-sin(a/2),cos(a/2),0])
        rot2 = rotation_matrix(taxis,n[2]*twist)
        R = np.dot(rot2,rot1)
        if angles:
            angle, dir = rotation_from_matrix(R)
            theta = np.arccos(dir[2])
            if np.abs(theta)<1E-12 or np.abs(theta-np.pi)<1E-12:
                phi = 0.
            else:
                cosp, sinp = dir[0]/np.sin(theta), dir[1]/np.sin(theta)
                phi = phival(cosp,sinp)
            return (theta,phi,angle)
        else:
            return R
Example #2
0
    def rotation(self, n, angles=False):
        """
        Rotate around two axes:
        first around 'unit cell axis' for chirality
        and then around 'torus axis' for twisting..
        Returns the rotation matrix.

        If angles==True, return (theta,phi,angle), where (theta,phi)
        gives the rotation axis and 'angle' the rotation angle.

        Approximate tangential vector by a mean tangential vector
        (-sin(angle/2),cos(angle/2),0)
        """
        if n[2] == 0:
            return np.eye(3)
        bend, twist = [self.get(k) for k in ['bend_angle', 'twist_angle']]
        rot1 = rotation_matrix(self.baxis, n[2] * bend)
        a = self.get('bend_angle')
        taxis = np.array([-sin(a / 2), cos(a / 2), 0])
        rot2 = rotation_matrix(taxis, n[2] * twist)
        R = np.dot(rot2, rot1)
        if angles:
            angle, dir = rotation_from_matrix(R)
            theta = np.arccos(dir[2])
            if np.abs(theta) < 1E-12 or np.abs(theta - np.pi) < 1E-12:
                phi = 0.
            else:
                cosp, sinp = dir[0] / np.sin(theta), dir[1] / np.sin(theta)
                phi = phival(cosp, sinp)
            return (theta, phi, angle)
        else:
            return R
Example #3
0
    def transform_arbitrary(self,r,bend,twist):
        """ The basic symmetry transformation with arbitrary angles b (bend angle) and t (twist angle) """
        r = np.array(r)
        R = self.get('R')
        Rp = np.array([r[0],r[1],0.])     # vector on xy-plane
        Rv = R*Rp/np.linalg.norm(Rp)      # vector to 'center' of tube
        rho = r-Rv                        # vector from tube center to r
        t = np.cross(np.array([0,0,1]),r) # tangential vector

        Rtwist = rotation_matrix(t,twist)
        Rbend  = rotation_matrix(self.baxis,bend)
        return np.dot( Rbend,Rv+np.dot(Rtwist,rho) )
Example #4
0
 def transform_arbitrary(self,r,bend,twist):
     """ The basic symmetry transformation with arbitrary angles b (bend angle) and t (twist angle) """
     r = np.array(r)
     R = self.get('R')
     Rp = np.array([r[0],r[1],0.])
     Rv = R*Rp/np.linalg.norm(Rp)
     rho = r-Rv
     t = np.cross(np.array([0,0,1]),r)
     Rtwist = rotation_matrix(t,twist)
     Rbend = rotation_matrix(self.baxis,bend)
     
     return np.dot( Rbend(Rv+np.dot(Rtwist,rho)),r )
Example #5
0
    def transform_arbitrary(self, r, bend, twist):
        """ The basic symmetry transformation with arbitrary angles b (bend angle) and t (twist angle) """
        r = np.array(r)
        R = self.get('R')
        Rp = np.array([r[0], r[1], 0.])  # vector on xy-plane
        Rv = R * Rp / np.linalg.norm(Rp)  # vector to 'center' of tube
        rho = r - Rv  # vector from tube center to r
        t = np.cross(np.array([0, 0, 1]), r)  # tangential vector

        Rtwist = rotation_matrix(t, twist)
        Rbend = rotation_matrix(self.baxis, bend)
        return np.dot(Rbend, Rv + np.dot(Rtwist, rho))
Example #6
0
 def rotation(self,n):
     """
     Rotate around two axes:
     first around 'unit cell axis' for chirality
     and then around 'torus axis' for twisting..
     Returns the rotation matrix.
     """
     if n[2]==0:
         return np.eye(3)
     a1,a2 = [self.get(k) for k in ['bend_angle','twist_angle']]
     rot1 = rotation_matrix(self.baxis,n[2]*a1)
     rot2 = rotation_matrix(self.taxis,n[2]*a2)
     return np.dot(rot2,rot1)
Example #7
0
 def transform(self,r,n):
     """ Symmetry transformation n for position r. """
     if n[0]==n[1]==0:
         return r.copy()
     A = np.array( [0,0,2*self.R] )
     
     a1,a2 = self.angle1*n[0], self.angle2*n[1]
     rot1 = rotation_matrix(self.n1,a1/self.M)
     rot2 = rotation_matrix(self.n2,a2/self.M)
     
     rp = r.copy()        
     for i in range(self.M):
         rp = np.dot(rot1,rp)
         rp = A + np.dot( rot2,rp-A )
     return rp        
Example #8
0
    def transform(self, r, n):
        """ Symmetry transformation n for position r. """
        if n[0] == n[1] == 0:
            return r.copy()
        A = np.array([0, 0, 2 * self.R])

        a1, a2 = self.angle1 * n[0], self.angle2 * n[1]
        rot1 = rotation_matrix(self.n1, a1 / self.M)
        rot2 = rotation_matrix(self.n2, a2 / self.M)

        rp = r.copy()
        for i in range(self.M):
            rp = np.dot(rot1, rp)
            rp = A + np.dot(rot2, rp - A)
        return rp
Example #9
0
 def rotation(self,n,angles=False):
     """ Rotate around two axes, ordering depending on mode. """
     if n[0]==n[1]==0:
         return np.eye(3)
     else:
         a1,a2 = self.angle1*n[0], self.angle2*n[1]
         #rot21 = np.dot( rotation_matrix(self.n2,a2/self.M),rotation_matrix(self.n1,a1/self.M) )
         rot1 = rotation_matrix(self.n1,a1/self.M)
         rot2 = rotation_matrix(self.n2,a2/self.M)
         rot21 = np.dot(rot2,rot1)
         
         rot = np.eye(3)       
         for i in range(self.M):
             #rot = np.dot( rot1,rot )
             #rot = np.dot( rot2,rot ) 
             rot = np.dot( rot21,rot )
         return rot
Example #10
0
    def rotation(self, n, angles=False):
        """ Rotate around two axes, ordering depending on mode. """
        if n[0] == n[1] == 0:
            return np.eye(3)
        else:
            a1, a2 = self.angle1 * n[0], self.angle2 * n[1]
            #rot21 = np.dot( rotation_matrix(self.n2,a2/self.M),rotation_matrix(self.n1,a1/self.M) )
            rot1 = rotation_matrix(self.n1, a1 / self.M)
            rot2 = rotation_matrix(self.n2, a2 / self.M)
            rot21 = np.dot(rot2, rot1)

            rot = np.eye(3)
            for i in range(self.M):
                #rot = np.dot( rot1,rot )
                #rot = np.dot( rot2,rot )
                rot = np.dot(rot21, rot)
            return rot
Example #11
0
 def rotation(self, n, angles=False):
     """ Rotate around two axes, ordering depending on mode. """
     if n[0] == n[1] == 0:
         return np.eye(3)
     angle1, angle2, n1, n2, mode = [
         self.get(k) for k in ['angle1', 'angle2', 'n1', 'n2', 'mode']
     ]
     if angles and mode != 4:
         raise NotImplementedError(
             'Sphere rotation implemented only for mode 4 so far.')
     if self.mode == 1 or self.mode == 2:
         R1n = rotation_matrix(n1, n[0] * angle1)
         R2n = rotation_matrix(n2, n[1] * angle2)
         if mode == 1:
             return np.dot(R2n, R1n)
         else:
             return np.dot(R1n, R2n)
     elif mode == 3:
         # rotate R2**l2 * R1**l1 * (R2*R2)**m
         na = (abs(n[0]), abs(n[1]), 0)
         m = min(na[:2])
         R1 = rotation_matrix(n1, np.sign(n[0]) * angle1)
         R2 = rotation_matrix(n2, np.sign(n[1]) * angle2)
         R21 = np.dot(R2, R1)
         R = np.eye(3)
         for i in range(m):
             R = np.dot(R, R21)
         # now rotate with the 'left-over'
         l1 = na[0] - m
         l2 = na[1] - m
         for i in range(l1):
             R = np.dot(R1, R)
         for i in range(l2):
             R = np.dot(R2, R)
         return R
     elif self.mode == 4:
         axis = angle1 * n[0] * n1 + angle2 * n[1] * n2
         a1, a2 = angle1 * n[0], angle2 * n[1]
         angle = np.sqrt(a1**2 + a2**2 + 2 * a1 * a2 * np.dot(n1, n2))
         if angles:
             axis = axis / np.linalg.norm(axis)
             return np.pi / 2., np.arctan2(axis[1], axis[0]), angle
         else:
             return rotation_matrix(axis, angle)
Example #12
0
 def rotation(self,n,angles=False):
     """ Rotate around two axes, ordering depending on mode. """
     if n[0]==n[1]==0:
         return np.eye(3)
     angle1, angle2, n1, n2, mode = [self.get(k) for k in ['angle1','angle2','n1','n2','mode']]
     if angles and mode!=4:
         raise NotImplementedError('Sphere rotation implemented only for mode 4 so far.')
     if self.mode==1 or self.mode==2:
         R1n = rotation_matrix( n1,n[0]*angle1 )
         R2n = rotation_matrix( n2,n[1]*angle2 )
         if mode==1:
             return np.dot(R2n,R1n)
         else:
             return np.dot(R1n,R2n)
     elif mode==3:
         # rotate R2**l2 * R1**l1 * (R2*R2)**m
         na = (abs(n[0]),abs(n[1]),0)
         m = min(na[:2])            
         R1 = rotation_matrix( n1,np.sign(n[0])*angle1 )
         R2 = rotation_matrix( n2,np.sign(n[1])*angle2 )
         R21 = np.dot(R2,R1)
         R = np.eye(3)
         for i in range(m):
             R = np.dot(R,R21)
         # now rotate with the 'left-over'
         l1 = na[0]-m
         l2 = na[1]-m
         for i in range(l1):
             R = np.dot(R1,R)
         for i in range(l2):
             R = np.dot(R2,R)
         return R
     elif self.mode==4:
         axis = angle1*n[0]*n1 + angle2*n[1]*n2
         a1,a2 = angle1*n[0], angle2*n[1]
         angle = np.sqrt( a1**2 + a2**2 + 2*a1*a2*np.dot(n1,n2) )
         if angles:
             axis = axis/np.linalg.norm(axis)
             return np.pi/2.,np.arctan2(axis[1],axis[0]),angle
         else:
             return rotation_matrix( axis,angle )
Example #13
0
    def rotation(self,n,angles=False):
        """ Rotate around two axes, ordering depending on mode. """
        if n[0]==n[1]==0:
            return np.eye(3)
        else:
            R1, R2 = self.R1, self.R2
            a,b = self.angle1*n[0], self.angle2*n[1]
            R = ( (a*R1)**2+(b*R2)**2 )/( a**2*R1+b**2*R2 )

            axis = np.array( [R2*b,R1*a,0] )
            angle = ( a**2*R1+b**2*abs(R2) )/np.sqrt( (a*R1)**2+(b*R2)**2 )
            return rotation_matrix( axis,angle )
Example #14
0
    def rotation(self, n, angles=False):
        """ Rotate around two axes, ordering depending on mode. """
        if n[0] == n[1] == 0:
            return np.eye(3)
        else:
            R1, R2 = self.R1, self.R2
            a, b = self.angle1 * n[0], self.angle2 * n[1]
            R = ((a * R1)**2 + (b * R2)**2) / (a**2 * R1 + b**2 * R2)

            axis = np.array([R2 * b, R1 * a, 0])
            angle = (a**2 * R1 + b**2 * abs(R2)) / np.sqrt((a * R1)**2 +
                                                           (b * R2)**2)
            return rotation_matrix(axis, angle)
Example #15
0
    def transform(self,r,n):
        """ Symmetry transformation n for position r. """
        if n[2]==0:
            return r.copy()

        a1, a2, R, mode = [self.get(k) for k in ['bend_angle','twist_angle','R','mode']]
        
        n1 = self.n1
        
        if mode == 2:
            orig_chir = np.cross(n2,n1)
            orig_chir = orig_chir/np.linalg.norm(orig_chir)
            A = np.dot(R,orig_chir)

            rot1 = rotation_matrix(n1,n[2]*a1)
            rot2 = rotation_matrix(n2,-n[2]*a2)

            Rot = np.dot( rot2,rot1 )

            rp = r.copy()
            rp = np.dot( Rot,rp-A ) + np.dot( rot2,A )
            return rp

        elif mode == 1:
            x, y, z = r
            x,y,z = x,z,-y
            alpha1 = phival(x,y)
            Rr = np.sqrt(x**2+y**2)
            R1 = R * np.array([np.cos(alpha1),np.sin(alpha1),np.zeros_like(alpha1)])
            rho = np.linalg.norm(r-R1)
            beta1 = phival(Rr-R,z)

            alpha2 = alpha1 + n[2]*a1 
            beta2  = beta1  + n[2]*a2 

            Rrp = R + rho*np.cos(beta2)
            return np.array( [Rrp*np.cos(alpha2),Rrp*np.sin(alpha2),-rho*np.sin(beta2)] )
        else:
            raise AssertionError('TwistAndTurn mode is not set')