Esempio n. 1
0
    def _snapEndPointHorizontalOrVertical(self):
        """
        Snap the second endpoint of the line (and thus the whole line) to the
        screen horizontal or vertical vectors. 
        @return: The new endPoint2 i.e. the moving endpoint of the rubberband 
                 line . This value may be same as previous or snapped so that 
                 line is horizontal or vertical depending upon the angle it 
                 makes with the horizontal and vertical. 
        @rtype: B{A}
        """
        up = self.glpane.up
        down = self.glpane.down
        left = self.glpane.left
        right = self.glpane.right  

        endPoint2 = self.endPoint2

        snapVector = V(0, 0, 0)

        currentLineVector = norm(self.endPoint2 - self.endPoint1)

        theta_horizontal = angleBetween(right, currentLineVector) 
        theta_vertical = angleBetween(up, currentLineVector) 

        theta_horizontal_old = theta_horizontal
        theta_vertical_old = theta_vertical

        if theta_horizontal != 90.0:            
            theta_horizontal = min(theta_horizontal, 
                                   (180.0 - theta_horizontal))

        if theta_vertical != 90.0:            
            theta_vertical = min(theta_vertical, 
                                 180.0 - theta_vertical)

        theta = min(theta_horizontal, theta_vertical)

        if theta <= 2.0 and theta != 0.0:
            self._snapOn = True
            if theta == theta_horizontal:
                self._snapType = 'HORIZONTAL'
                if theta_horizontal == theta_horizontal_old:
                    snapVector = right                   
                else:
                    snapVector = left
            elif theta == theta_vertical:
                self._snapType = 'VERTICAL'
                if theta_vertical == theta_vertical_old:
                    snapVector = up
                else:
                    snapVector = down

            endPoint2 = self.endPoint1 + \
                      vlen(self.endPoint1 - self.endPoint2)*snapVector

        else:                
            self._snapOn = False

        return endPoint2
Esempio n. 2
0
    def _snapEndPointHorizontalOrVertical(self):
        """
        Snap the second endpoint of the line (and thus the whole line) to the
        screen horizontal or vertical vectors. 
        @return: The new endPoint2 i.e. the moving endpoint of the rubberband 
                 line . This value may be same as previous or snapped so that 
                 line is horizontal or vertical depending upon the angle it 
                 makes with the horizontal and vertical. 
        @rtype: B{A}
        """
        up = self.glpane.up
        down = self.glpane.down
        left = self.glpane.left
        right = self.glpane.right  

        endPoint2 = self.endPoint2

        snapVector = V(0, 0, 0)

        currentLineVector = norm(self.endPoint2 - self.endPoint1)

        theta_horizontal = angleBetween(right, currentLineVector) 
        theta_vertical = angleBetween(up, currentLineVector) 

        theta_horizontal_old = theta_horizontal
        theta_vertical_old = theta_vertical

        if theta_horizontal != 90.0:            
            theta_horizontal = min(theta_horizontal, 
                                   (180.0 - theta_horizontal))

        if theta_vertical != 90.0:            
            theta_vertical = min(theta_vertical, 
                                 180.0 - theta_vertical)

        theta = min(theta_horizontal, theta_vertical)

        if theta <= 2.0 and theta != 0.0:
            self._snapOn = True
            if theta == theta_horizontal:
                self._snapType = 'HORIZONTAL'
                if theta_horizontal == theta_horizontal_old:
                    snapVector = right                   
                else:
                    snapVector = left
            elif theta == theta_vertical:
                self._snapType = 'VERTICAL'
                if theta_vertical == theta_vertical_old:
                    snapVector = up
                else:
                    snapVector = down

            endPoint2 = self.endPoint1 + \
                      vlen(self.endPoint1 - self.endPoint2)*snapVector

        else:                
            self._snapOn = False

        return endPoint2
Esempio n. 3
0
 def get_dihedral(self):
     """
     Returns the dihedral between two atoms (nuclei)
     """
     wx = self.atoms[0].posn()-self.atoms[1].posn()
     yx = self.atoms[2].posn()-self.atoms[1].posn()
     xy = -yx
     zy = self.atoms[3].posn()-self.atoms[2].posn()
     u = cross(wx, yx)
     v = cross(xy, zy)
     if dot(zy, u) < 0:   # angles go from -180 to 180, wware 051101
         return -angleBetween(u, v)  # use new acos(dot) func, wware 051103
     else:
         return angleBetween(u, v)
Esempio n. 4
0
 def get_dihedral(self):
     """
     Returns the dihedral between two atoms (nuclei)
     """
     wx = self.atoms[0].posn() - self.atoms[1].posn()
     yx = self.atoms[2].posn() - self.atoms[1].posn()
     xy = -yx
     zy = self.atoms[3].posn() - self.atoms[2].posn()
     u = cross(wx, yx)
     v = cross(xy, zy)
     if dot(zy, u) < 0:  # angles go from -180 to 180, wware 051101
         return -angleBetween(u, v)  # use new acos(dot) func, wware 051103
     else:
         return angleBetween(u, v)
Esempio n. 5
0
 def get_angle(self):
     """
     Returns the angle between two atoms (nuclei)
     """
     v01 = self.atoms[0].posn() - self.atoms[1].posn()
     v21 = self.atoms[2].posn() - self.atoms[1].posn()
     return angleBetween(v01, v21)
Esempio n. 6
0
 def get_angle(self):
     """
     Returns the angle between two atoms (nuclei)
     """
     v01 = self.atoms[0].posn()-self.atoms[1].posn()
     v21 = self.atoms[2].posn()-self.atoms[1].posn()
     return angleBetween(v01, v21)
Esempio n. 7
0
    def _snapEndPointToStandardAxis(self):
        """
        Snap the second endpoint of the line so that it lies on the nearest
        axis vector. (if its close enough) . This functions keeps the uses the
        current rubberband line vector and just extends the second end point 
        so that it lies at the intersection of the nearest axis vector and the 
        rcurrent rubberband line vector. 
        @return: The new endPoint2 i.e. the moving endpoint of the rubberband 
                 line . This value may be same as previous or snapped to lie on
                 the nearest axis (if one exists) 
        @rtype: B{A}
        """
        x_axis = V(1, 0, 0)
        y_axis = V(0, 1, 0)
        z_axis = V(0, 0, 1)

        endPoint2 = self.endPoint2
        currentLineVector = norm(self.endPoint2 - self.endPoint1)

        theta_x = angleBetween(x_axis, self.endPoint2)
        theta_y = angleBetween(y_axis, self.endPoint2)
        theta_z = angleBetween(z_axis, self.endPoint2)

        theta_x = min(theta_x, (180 - theta_x))
        theta_y = min(theta_y, (180 - theta_y))
        theta_z = min(theta_z, (180 - theta_z))

        theta = min(theta_x, theta_y, theta_z)

        if theta < 2.0:    
            if theta == theta_x:                
                self._standardAxisVectorForDrawingSnapReference = x_axis
            elif theta == theta_y:
                self._standardAxisVectorForDrawingSnapReference = y_axis
            elif theta == theta_z:                
                self._standardAxisVectorForDrawingSnapReference = z_axis

            endPoint2 = ptonline(self.endPoint2, 
                                 V(0, 0, 0), 
                                 self._standardAxisVectorForDrawingSnapReference)
        else:
            self._standardAxisVectorForDrawingSnapReference = None            

        return endPoint2
Esempio n. 8
0
    def _snapEndPointToStandardAxis(self):
        """
        Snap the second endpoint of the line so that it lies on the nearest
        axis vector. (if its close enough) . This functions keeps the uses the
        current rubberband line vector and just extends the second end point 
        so that it lies at the intersection of the nearest axis vector and the 
        rcurrent rubberband line vector. 
        @return: The new endPoint2 i.e. the moving endpoint of the rubberband 
                 line . This value may be same as previous or snapped to lie on
                 the nearest axis (if one exists) 
        @rtype: B{A}
        """
        x_axis = V(1, 0, 0)
        y_axis = V(0, 1, 0)
        z_axis = V(0, 0, 1)

        endPoint2 = self.endPoint2
        currentLineVector = norm(self.endPoint2 - self.endPoint1)

        theta_x = angleBetween(x_axis, self.endPoint2)
        theta_y = angleBetween(y_axis, self.endPoint2)
        theta_z = angleBetween(z_axis, self.endPoint2)

        theta_x = min(theta_x, (180 - theta_x))
        theta_y = min(theta_y, (180 - theta_y))
        theta_z = min(theta_z, (180 - theta_z))

        theta = min(theta_x, theta_y, theta_z)

        if theta < 2.0:
            if theta == theta_x:
                self._standardAxisVectorForDrawingSnapReference = x_axis
            elif theta == theta_y:
                self._standardAxisVectorForDrawingSnapReference = y_axis
            elif theta == theta_z:
                self._standardAxisVectorForDrawingSnapReference = z_axis

            endPoint2 = ptonline(
                self.endPoint2, V(0, 0, 0),
                self._standardAxisVectorForDrawingSnapReference)
        else:
            self._standardAxisVectorForDrawingSnapReference = None

        return endPoint2
Esempio n. 9
0
    def _orient(self, cntChunk, pt1, pt2):
        """
        Orients the CNT I{cntChunk} based on two points. I{pt1} is
        the first endpoint (origin) of the nanotube. The vector I{pt1}, I{pt2}
        defines the direction and central axis of the nanotube.
        
        @param pt1: The starting endpoint (origin) of the nanotube.
        @type  pt1: L{V}
        
        @param pt2: The second point of a vector defining the direction
                    and central axis of the nanotube.
        @type  pt2: L{V}
        """

        a = V(0.0, 0.0, -1.0)
        # <a> is the unit vector pointing down the center axis of the default
        # DNA structure which is aligned along the Z axis.
        bLine = pt2 - pt1
        bLength = vlen(bLine)
        b = bLine / bLength
        # <b> is the unit vector parallel to the line (i.e. pt1, pt2).
        axis = cross(a, b)
        # <axis> is the axis of rotation.
        theta = angleBetween(a, b)
        # <theta> is the angle (in degress) to rotate about <axis>.
        scalar = bLength * 0.5
        rawOffset = b * scalar

        if 0:  # Debugging code.
            print ""
            print "uVector  a = ", a
            print "uVector  b = ", b
            print "cross(a,b) =", axis
            print "theta      =", theta
            print "cntRise   =", self.getCntRise()
            print "# of cells =", self.getNumberOfCells()
            print "scalar     =", scalar
            print "rawOffset  =", rawOffset

        if theta == 0.0 or theta == 180.0:
            axis = V(0, 1, 0)
            # print "Now cross(a,b) =", axis

        rot = (pi / 180.0) * theta  # Convert to radians
        qrot = Q(axis, rot)  # Quat for rotation delta.

        # Move and rotate the nanotube into final orientation.
        cntChunk.move(
            qrot.rot(cntChunk.center) - cntChunk.center + rawOffset + pt1)
        cntChunk.rot(qrot)

        # Bruce suggested I add this. It works here, but not if its
        # before move() and rot() above. Mark 2008-04-11
        cntChunk.full_inval_and_update()
        return
Esempio n. 10
0
 def _orient(self, cntChunk, pt1, pt2):
     """
     Orients the CNT I{cntChunk} based on two points. I{pt1} is
     the first endpoint (origin) of the nanotube. The vector I{pt1}, I{pt2}
     defines the direction and central axis of the nanotube.
     
     @param pt1: The starting endpoint (origin) of the nanotube.
     @type  pt1: L{V}
     
     @param pt2: The second point of a vector defining the direction
                 and central axis of the nanotube.
     @type  pt2: L{V}
     """
     
     a = V(0.0, 0.0, -1.0)
     # <a> is the unit vector pointing down the center axis of the default
     # DNA structure which is aligned along the Z axis.
     bLine = pt2 - pt1
     bLength = vlen(bLine)
     b = bLine/bLength
     # <b> is the unit vector parallel to the line (i.e. pt1, pt2).
     axis = cross(a, b)
     # <axis> is the axis of rotation.
     theta = angleBetween(a, b)
     # <theta> is the angle (in degress) to rotate about <axis>.
     scalar = bLength * 0.5
     rawOffset = b * scalar
     
     if 0: # Debugging code.
         print ""
         print "uVector  a = ", a
         print "uVector  b = ", b
         print "cross(a,b) =", axis
         print "theta      =", theta
         print "cntRise   =", self.getCntRise()
         print "# of cells =", self.getNumberOfCells()
         print "scalar     =", scalar
         print "rawOffset  =", rawOffset
     
     if theta == 0.0 or theta == 180.0:
         axis = V(0, 1, 0)
         # print "Now cross(a,b) =", axis
         
     rot =  (pi / 180.0) * theta  # Convert to radians
     qrot = Q(axis, rot) # Quat for rotation delta.
     
     # Move and rotate the nanotube into final orientation.
     cntChunk.move(qrot.rot(cntChunk.center) - cntChunk.center + rawOffset + pt1)
     cntChunk.rot(qrot)
     
     # Bruce suggested I add this. It works here, but not if its 
     # before move() and rot() above. Mark 2008-04-11
     cntChunk.full_inval_and_update()
     return
Esempio n. 11
0
 def _orientRawDnaGroup(self, rawDnaGroup, pt1, pt2):
     """
     Orients the raw DNA group based on two endpoints.
     
     @param rawDnaGroup: The raw DNA group created by make().
     @type  rawDnaGroup: L{Group}
     
     @param pt1: The first endpoint of the DNA strand.
     @type  pt1: L{V}
     
     @param pt2: The second endpoint of the DNA strand.
     @type  pt2: L{V}
     
     @attention: Only works for PAM5 models.
     """
     
     a = V(0.0, 0.0, -1.0)
     # <a> is the unit vector pointing down the center axis of the default
     # rawDnaGroup structure which is aligned along the Z axis.
     bLine = pt2 - pt1
     bLength = vlen(bLine)
     b = bLine/bLength
     # <b> is the unit vector parallel to the line (i.e. pt1, pt2).
     axis = cross(a, b)
     # <axis> is the axis of rotation.
     theta = angleBetween(a, b)
     # <theta> is the angle (in degress) to rotate about <axis>.
     scalar = self.dna.getBaseRise() * self.getSequenceLength() * 0.5
     rawOffset = b * scalar
     
     if 0: # Debugging code.
         print ""
         print "uVector  a = ", a
         print "uVector  b = ", b
         print "cross(a,b) =", axis
         print "theta      =", theta
         print "baserise   =", self.dna.getBaseRise()
         print "seqLength  =", self.getSequenceLength()
         print "scalar     =", scalar
         print "rawOffset  =", rawOffset
     
     if theta == 0.0 or theta == 180.0:
         axis = V(0, 1, 0)
         # print "Now cross(a,b) =", axis
         
     rot =  (pi / 180.0) * theta  # Convert to radians
     qrot = Q(axis, rot) # Quat for rotation delta.
     
     # Move and rotate the base chunks into final orientation.
     for m in rawDnaGroup.members:
         m.move(qrot.rot(m.center) - m.center + rawOffset + pt1)
         m.rot(qrot)
Esempio n. 12
0
    def _are_crossover_atompairs(self, atomPair1, atomPair2,
                                 orthogonal_vector):
        """
        """
        atm1, neighbor1 = atomPair1
        center_1 = (atm1.posn() + neighbor1.posn()) / 2.0
        atm2, neighbor2 = atomPair2
        center_2 = (atm2.posn() + neighbor2.posn()) / 2.0

        distance = vlen(center_1 - center_2)
        if distance > MAX_DISTANCE_BETWEEN_CROSSOVER_SITES:
            return False, distance, ()

        #@NOTE: In self._filter_neighbor_atompairs() where we create the
        #atompairlists, we make sure that the atoms are ordered in +ve bond_direction
        #Below, we just check the relative direction of atoms.

        #@@@@@METHOD TO BE WRITTEN FURTHER

        centerVec = center_1 - center_2

        if self.graphicsMode.DEBUG_DRAW_AVERAGE_CENTER_PAIRS_OF_POTENTIAL_CROSSOVERS:
            self._DEBUG_avg_center_pairs_of_potential_crossovers.append(
                (center_1, center_2))

        theta = angleBetween(orthogonal_vector, centerVec)

        if dot(centerVec, orthogonal_vector) < 1:
            theta = 180.0 - theta

        if abs(
                theta
        ) > MAX_ANGLE_BET_PLANE_NORMAL_AND_AVG_CENTER_VECTOR_OF_CROSSOVER_PAIRS:
            return False, distance, ()

        crossoverPairs = (atm1, neighbor1, atm2, neighbor2)

        for a in crossoverPairs:
            if not self._final_crossover_atoms_dict.has_key(id(a)):
                self._final_crossover_atoms_dict[id(a)] = a

        #important to sort this to create a unique id. Makes sure that same
        #crossover pairs are not added to the self.final_crossover_pairs_dict
        crossoverPairs_id = self._create_crossoverPairs_id(crossoverPairs)

        if not self.final_crossover_pairs_dict.has_key(crossoverPairs_id):
            self._final_avg_center_pairs_for_crossovers_dict[
                crossoverPairs_id] = (center_1, center_2)
            self.final_crossover_pairs_dict[crossoverPairs_id] = crossoverPairs

        return True, distance, crossoverPairs
    def _orient(self, chunk, pt1, pt2):
        """
        Orients the Peptide I{chunk} based on two points. I{pt1} is
        the first endpoint (origin) of the Peptide. The vector I{pt1}, I{pt2}
        defines the direction and central axis of the Peptide.

        piotr 080801: I copied this method from Nanotube Builder.

        @param pt1: The starting endpoint (origin) of the Peptide.
        @type  pt1: L{V}

        @param pt2: The second point of a vector defining the direction
                    and central axis of the Peptide.
        @type  pt2: L{V}
        """

        a = V(0.0, 0.0, -1.0)
        # <a> is the unit vector pointing down the center axis of the default
        # structure which is aligned along the Z axis.
        bLine = pt2 - pt1
        bLength = vlen(bLine)
        if bLength == 0:
            return
        b = bLine / bLength
        # <b> is the unit vector parallel to the line (i.e. pt1, pt2).
        axis = cross(a, b)
        # <axis> is the axis of rotation.
        theta = angleBetween(a, b)
        # <theta> is the angle (in degress) to rotate about <axis>.
        scalar = bLength * 0.5
        rawOffset = b * scalar

        if theta == 0.0 or theta == 180.0:
            axis = V(0, 1, 0)
            # print "Now cross(a,b) =", axis

        rot =  (pi / 180.0) * theta  # Convert to radians
        qrot = Q(axis, rot) # Quat for rotation delta.

        # Move and rotate the Peptide into final orientation.

        chunk.move(-chunk.center)

        chunk.rot(qrot)

        # Bruce suggested I add this. It works here, but not if its
        # before move() and rot() above. Mark 2008-04-11
        chunk.full_inval_and_update()
        return
    def _are_crossover_atompairs(self,
                                 atomPair1,
                                 atomPair2,
                                 orthogonal_vector):
        """
        """
        atm1, neighbor1 = atomPair1
        center_1 = (atm1.posn() + neighbor1.posn())/2.0
        atm2, neighbor2 = atomPair2
        center_2 = (atm2.posn() + neighbor2.posn())/2.0

        distance = vlen(center_1 - center_2)
        if  distance > MAX_DISTANCE_BETWEEN_CROSSOVER_SITES:
            return False, distance, ()

        #@NOTE: In self._filter_neighbor_atompairs() where we create the
        #atompairlists, we make sure that the atoms are ordered in +ve bond_direction
        #Below, we just check the relative direction of atoms.

        #@@@@@METHOD TO BE WRITTEN FURTHER

        centerVec = center_1 - center_2

        if self.graphicsMode.DEBUG_DRAW_AVERAGE_CENTER_PAIRS_OF_POTENTIAL_CROSSOVERS:
            self._DEBUG_avg_center_pairs_of_potential_crossovers.append((center_1, center_2))

        theta = angleBetween(orthogonal_vector, centerVec)

        if dot(centerVec, orthogonal_vector) < 1:
            theta = 180.0 - theta

        if abs(theta) > MAX_ANGLE_BET_PLANE_NORMAL_AND_AVG_CENTER_VECTOR_OF_CROSSOVER_PAIRS:
            return False, distance, ()

        crossoverPairs = (atm1, neighbor1, atm2, neighbor2)

        for a in crossoverPairs:
            if not self._final_crossover_atoms_dict.has_key(id(a)):
                self._final_crossover_atoms_dict[id(a)] = a

        #important to sort this to create a unique id. Makes sure that same
        #crossover pairs are not added to the self.final_crossover_pairs_dict
        crossoverPairs_id = self._create_crossoverPairs_id(crossoverPairs)

        if not self.final_crossover_pairs_dict.has_key(crossoverPairs_id):
            self._final_avg_center_pairs_for_crossovers_dict[crossoverPairs_id] = (center_1, center_2)
            self.final_crossover_pairs_dict[crossoverPairs_id] = crossoverPairs

        return True, distance, crossoverPairs
Esempio n. 15
0
    def _orient(self, chunk, pt1, pt2):
        """
        Orients the Peptide I{chunk} based on two points. I{pt1} is
        the first endpoint (origin) of the Peptide. The vector I{pt1}, I{pt2}
        defines the direction and central axis of the Peptide.

        piotr 080801: I copied this method from Nanotube Builder.

        @param pt1: The starting endpoint (origin) of the Peptide.
        @type  pt1: L{V}

        @param pt2: The second point of a vector defining the direction
                    and central axis of the Peptide.
        @type  pt2: L{V}
        """

        a = V(0.0, 0.0, -1.0)
        # <a> is the unit vector pointing down the center axis of the default
        # structure which is aligned along the Z axis.
        bLine = pt2 - pt1
        bLength = vlen(bLine)
        if bLength == 0:
            return
        b = bLine / bLength
        # <b> is the unit vector parallel to the line (i.e. pt1, pt2).
        axis = cross(a, b)
        # <axis> is the axis of rotation.
        theta = angleBetween(a, b)
        # <theta> is the angle (in degress) to rotate about <axis>.
        scalar = bLength * 0.5
        rawOffset = b * scalar

        if theta == 0.0 or theta == 180.0:
            axis = V(0, 1, 0)
            # print "Now cross(a,b) =", axis

        rot = (pi / 180.0) * theta  # Convert to radians
        qrot = Q(axis, rot)  # Quat for rotation delta.

        # Move and rotate the Peptide into final orientation.

        chunk.move(-chunk.center)

        chunk.rot(qrot)

        # Bruce suggested I add this. It works here, but not if its
        # before move() and rot() above. Mark 2008-04-11
        chunk.full_inval_and_update()
        return
Esempio n. 16
0
 def get_angle_made_with_screen_right(self, vec):
     """
     Returns the angle (in degrees) between screen right direction
     and the given vector. It returns positive angles (between 0 and
     180 degrees) if the vector lies in first or second quadrants
     (i.e. points more up than down on the screen). Otherwise the
     angle returned is negative.
     """
     #Ninad 2008-04-17: This method was added AFTER rattlesnake rc2.
     #bruce 080912 bugfix: don't give theta the wrong sign when
     # dot(vec, self.up) < 0 and dot(vec, self.right) == 0.
     vec = norm(vec)        
     theta = angleBetween(vec, self.right)
     if dot(vec, self.up) < 0:
         theta = - theta
     return theta
Esempio n. 17
0
 def get_angle_made_with_screen_right(self, vec):
     """
     Returns the angle (in degrees) between screen right direction
     and the given vector. It returns positive angles (between 0 and
     180 degrees) if the vector lies in first or second quadrants
     (i.e. points more up than down on the screen). Otherwise the
     angle returned is negative.
     """
     #Ninad 2008-04-17: This method was added AFTER rattlesnake rc2.
     #bruce 080912 bugfix: don't give theta the wrong sign when
     # dot(vec, self.up) < 0 and dot(vec, self.right) == 0.
     vec = norm(vec)
     theta = angleBetween(vec, self.right)
     if dot(vec, self.up) < 0:
         theta = -theta
     return theta
Esempio n. 18
0
 def updateControlPoints_EXPERIMENTAL(self, hdl, hdl_NewPt):
     """
     Experimental stuff in this method. Not used anywhere. Ignore
     """
     movedHandle = hdl
     handle_NewPt = hdl_NewPt
     
     if len(self.handles) > 1:            
         self.controlPoints = []
         if movedHandle in self.handles[1:-1]:
             for h in self.handles:        
                 self.controlPoints.append(h.center)
         else:
             offsetVector = handle_NewPt - movedHandle.center
             movedHandle.center = handle_NewPt
             
             for h in self.handles[1:-1]:
                 vect = movedHandle.center - h.center
                 
                 theta = angleBetween( vect, offsetVector)
                 theta = theta*pi/180.0
          
                 offsetVecForHandle = offsetVector / cos(theta)
                 ##offsetVecForHandle = offsetVector* len(vect)/len(offsetVector)
                 h.center += offsetVecForHandle
             for h in self.handles:
                 self.controlPoints.append(h.center)
                 
                     
             if 0:
                 oldCenter = V(0.0, 0.0, 0.0)
                 for h in self.handles:
                     oldCenter += h.center                    
                 oldCenter /= len(self.handles)
                 movedHandle.center = handle_NewPt
                 
                 newCenter = V(0.0, 0.0, 0.0)
                 for h in self.handles:
                     newCenter += h.center
                 
                 newCenter /= len(self.handles)
                 
                 for h in self.handles:
                     if h in self.handles[1:-1]:
                         h.center += newCenter - oldCenter
                     self.controlPoints.append(h.center)