Package VisionEgg :: Module ThreeDeeMath |
[frames] | no frames]

# Source Code for Module VisionEgg.ThreeDeeMath

     1  # The Vision Egg: ThreeDeeMath
     2  #
     3  # Copyright (C) 2001-2003 Andrew Straw.
     4  # Copyright (C) 2008 California Institute of Technology
     5  #
     6  # URL: <http://www.visionegg.org/>
     7  #
     8  # Distributed under the terms of the GNU Lesser General Public License
     9  # (LGPL). See LICENSE.TXT that came with this file.
    10
    11  """
    12  Vertex and matrix operations - simulate OpenGL transforms.
    13
    14  """
    15
    16  import math
    17  import numpy
    18  import numpy.oldnumeric as Numeric, numpy.oldnumeric.mlab as MLab
    19
    20 -def make_homogeneous_coord_rows(v):
    21      """Convert vertex (or row-wise vertices) into homogeneous coordinates."""
    22      v = Numeric.array(v,typecode=Numeric.Float) # copy
    23      if len(v.shape) == 1:
    24          v = v[Numeric.NewAxis,:] # make a rank-2 array
    25      if v.shape[1] == 3:
    26          ws = Numeric.ones((v.shape[0],1),typecode=Numeric.Float)
    27          v = Numeric.concatenate( (v,ws), axis=1 )
    28      return v
    29
    30 -def normalize_homogeneous_rows(v):
    31      v = Numeric.asarray(v)
    32      homog = make_homogeneous_coord_rows(v)
    33      r = (homog/homog[:,3,Numeric.NewAxis])[:,:3]
    34      if len(homog.shape) > len(v.shape):
    35          r = Numeric.reshape(r,(3,))
    36      return r
    37
    38 -class TransformMatrix:
    39 -    def __init__(self,matrix=None):
    40          if matrix is None:
    41              self.matrix = MLab.eye(4,typecode=Numeric.Float)
    42          else:
    43              self.matrix = matrix
    44
    45 -    def __make_normalized_vert3(self, x, y, z ):
    46          mag = math.sqrt( x**2 + y**2 + z**2 )
    47          return Numeric.array((x,y,z))/mag
    48
    49 -    def rotate(self, angle_degrees, axis_x, axis_y, axis_z ):
    50          """Follows the right hand rule.
    51
    52          I visualize the right hand rule most easily as follows:
    53          Naturally, using your right hand, wrap it around the axis of
    54          rotation. Your fingers now point in the direction of rotation.
    55
    56          """
    57          angleRadians = angle_degrees / 180.0 * math.pi
    58          u = self.__make_normalized_vert3(axis_x, axis_y, axis_z )
    59          u=-u #follow right hand rule
    60          S = Numeric.zeros( (3,3), Numeric.Float )
    61          S[0,1] = -u[2]
    62          S[0,2] = u[1]
    63          S[1,0] = u[2]
    64          S[1,2] = -u[0]
    65          S[2,0] = -u[1]
    66          S[2,1] = u[0]
    67          U = Numeric.outerproduct(u,u)
    68          R = U + math.cos(angleRadians)*(MLab.eye(3)-U) + math.sin(angleRadians)*S
    69          R = Numeric.concatenate( (R,Numeric.zeros( (3,1), Numeric.Float)), axis=1)
    70          R = Numeric.concatenate( (R,Numeric.zeros( (1,4), Numeric.Float)), axis=0)
    71          R[3,3] = 1.0
    72          self.matrix = numpy.dot(R,self.matrix)
    73
    74 -    def translate(self, x, y, z):
    75          T = MLab.eye(4,typecode=Numeric.Float)
    76          T[3,0] = x
    77          T[3,1] = y
    78          T[3,2] = z
    79          self.matrix = numpy.dot(T,self.matrix)
    80
    81 -    def scale(self, x, y, z):
    82          T = MLab.eye(4,typecode=Numeric.Float)
    83          T[0,0] = x
    84          T[1,1] = y
    85          T[2,2] = z
    86          self.matrix = numpy.dot(T,self.matrix)
    87
    88 -    def get_matrix(self):
    89          return self.matrix
    90
    91 -    def transform_vertices(self,verts):
    92          v = Numeric.asarray(verts)
    93          homog = make_homogeneous_coord_rows(v)
    94          r = numpy.dot(homog,self.matrix)
    95          if len(homog.shape) > len(v.shape):
    96              r = Numeric.reshape(r,(4,))
    97          return r
    98