#[MIT license:] # # Copyright (c) 2004 Dave Pape # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. from OpenGL.GL import * import operator, math, types # Vector class is based in part on public domain matfunc.py, by Raymond Hettinger, # from http://users.rcn.com/python/download/python.htm class Vector(list): concat = list.__add__ # A substitute for the overridden __add__ method def __getslice__( self, i, j ): return Vector( list.__getslice__(self,i,j) ) def __init__( self, elems ): list.__init__( self, elems ) def __str__( self ): return ' '.join( map(str, self) ) def map( self, op, rhs=None ): if rhs is None: # Unary case return Vector( map(op, self) ) elif isinstance(rhs, types.ListType): # List / List op assert len(self) == len(rhs), 'Vector operation requires lengths to agree' return Vector( map(op, self, rhs) ) else: # List / Scalar op return Vector( [op(e,rhs) for e in self] ) def __mul__( self, rhs ): return self.map( operator.mul, rhs ) def __div__( self, rhs ): return self.map( operator.div, rhs ) def __sub__( self, rhs ): return self.map( operator.sub, rhs ) def __add__( self, rhs ): return self.map( operator.add, rhs ) def __rmul__( self, lhs ): return self.map( operator.mul, lhs ) def __rdiv__( self, lhs ): return self.map( lambda x,y: y / x, lhs ) def __rsub__( self, lhs ): return self.map( lambda x,y: y - x, lhs ) def __radd__( self, lhs ): return self.map( operator.mul, lhs ) def __abs__( self ): return self.map( abs ) def __neg__( self ): return self.map( operator.neg ) def __iadd__( self, other ): self = self + other return self def __imul__( self, other ): self = self * other return self def dot( self, otherVec ): return reduce(operator.add, map(operator.mul, self, otherVec), 0.0) def length( self ): return math.sqrt(self.dot(self)) def lengthSquared( self ): return self.dot(self) def normalize( self ): s = 1.0/self.length() # For some Pythonic reason, doing "self *= s" doesn't work for i in range(0,len(self)): self[i] *= s def cross( self, otherVec ): 'Compute a cross product with another vector' assert len(self) == len(otherVec) == 3, 'Cross product only defined for 3-D vectors' u, v = self, otherVec return Vector([ u[1]*v[2]-u[2]*v[1], u[2]*v[0]-u[0]*v[2], u[0]*v[1]-u[1]*v[0] ]) def distance( self, otherVec ): return (self-otherVec).length() def distanceSquared( self, otherVec ): return (self-otherVec).lengthSquared() def drawLine( self ): glBegin(GL_LINES) glVertex3f(0, 0, 0) if len(self) > 2: glVertex3fv(self) elif len(self) == 2: glVertex2fv(self) glEnd() X_Axis = Vector([1, 0, 0]) Y_Axis = Vector([0, 1, 0]) Z_Axis = Vector([0, 0, 1])