# This module defines 3d geometrical vectors with the standard # operations on them. The elements are stored in an # array. # # Written by Konrad Hinsen # last revision: 2005-9-5 # # Ported out of Scientific.Geometry by YW Huang # import math; _undocumented = 1 class Vector: """Vector in 3D space Constructor: - Vector(|x|, |y|, |z|) (from three coordinates) - Vector(|coordinates|) (from any sequence containing three coordinates) Vectors support the usual arithmetic operations ('v1', 'v2': vectors, 's': scalar): - 'v1+v2' (addition) - 'v1-v2' (subtraction) - 'v1*v2' (scalar product) - 's*v1', 'v1*s' (multiplication with a scalar) - 'v1/s' (division by a scalar) The three coordinates can be extracted by indexing. Vectors are *immutable*, i.e. their elements cannot be changed. Vector elements can be any objects on which the standard arithmetic operations plus the functions sqrt and arccos are defined. """ is_vector = 1 def __init__(self, x=None, y=None, z=None): if x is None: self.array = [0.0, 0.0, 0.0]; else: self.array = [x, y, z]; def __repr__(self): return 'Vector(%s,%s,%s)' % (`self.array[0]`, `self.array[1]`, `self.array[2]`); def __str__(self): return `list(self.array)`; def __add__(self, other): return Vector( self.array[0]+other.array[0], self.array[1]+other.array[1], self.array[2]+other.array[2] ); __radd__ = __add__; def __neg__(self): return Vector( -self.array[0], -self.array[1], -self.array[2] ); def __sub__(self, other): return Vector( self.array[0]-other.array[0], self.array[1]-other.array[1], self.array[2]-other.array[2] ); def __rsub__(self, other): return Vector( other.array[0]-self.array[0], other.array[1]-self.array[1], other.array[2]-self.array[2] ); def __mul__(self, other): if isVector(other): return self.dot(other) return Vector( other*self.array[0], other*self.array[1], other*self.array[2] ); __rmul__ = __mul__; def __div__(self, other): if isVector(other): raise TypeError("Can't divide by a vector"); else: other = other * 1.0; return Vector( self.array[0] / other, self.array[1] / other, self.array[2] / other ); def __rdiv__(self, other): raise TypeError("Can't divide by a vector"); def __len__(self): return 3; def __getitem__(self, index): return self.array[index]; def x(self): return self.array[0]; def y(self): return self.array[1]; def z(self): return self.array[2]; def length(self): return math.sqrt( self.array[0]**2 + self.array[1]**2 + self.array[2]**2 ); def normal(self): return self/self.length(); def cross(self, other): return Vector( self.array[1]*other.array[2] -self.array[2]*other.array[1], self.array[2]*other.array[0] -self.array[0]*other.array[2], self.array[0]*other.array[1] -self.array[1]*other.array[0]); def dot(self,other): return self.array[0]*other.array[0] + self.array[1]*other.array[1] + self.array[2]*other.array[2] def isVector(x): return hasattr(x, 'is_vector');