/SFACT/fabmetheus_utilities/vector3index.py

https://github.com/eagleapex/BBstuff · Python · 277 lines · 200 code · 53 blank · 24 comment · 16 complexity · 9e0cec2192fa8c35ab43feb1dc519b96 MD5 · raw file

  1. """
  2. Vector3 is a three dimensional vector class.
  3. Below are examples of Vector3 use.
  4. >>> from vector3 import Vector3
  5. >>> origin = Vector3()
  6. >>> origin
  7. 0.0, 0.0, 0.0
  8. >>> pythagoras = Vector3( 3, 4, 0 )
  9. >>> pythagoras
  10. 3.0, 4.0, 0.0
  11. >>> pythagoras.magnitude()
  12. 5.0
  13. >>> pythagoras.magnitudeSquared()
  14. 25
  15. >>> triplePythagoras = pythagoras * 3.0
  16. >>> triplePythagoras
  17. 9.0, 12.0, 0.0
  18. >>> plane = pythagoras.dropAxis()
  19. >>> plane
  20. (3+4j)
  21. """
  22. from __future__ import absolute_import
  23. try:
  24. import psyco
  25. psyco.full()
  26. except:
  27. pass
  28. #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module.
  29. import __init__
  30. from fabmetheus_utilities import xml_simple_writer
  31. import math
  32. import operator
  33. __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
  34. __credits__ = 'Nophead <http://forums.reprap.org/profile.php?12,28>\nArt of Illusion <http://www.artofillusion.org/>'
  35. __date__ = '$Date: 2008/21/04 $'
  36. __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
  37. class Vector3Index:
  38. 'A three dimensional vector index class.'
  39. __slots__ = ['index', 'x', 'y', 'z']
  40. def __init__( self, index, x = 0.0, y = 0.0, z = 0.0 ):
  41. self.index = index
  42. self.x = x
  43. self.y = y
  44. self.z = z
  45. def __abs__(self):
  46. 'Get the magnitude of the Vector3.'
  47. return math.sqrt( self.x * self.x + self.y * self.y + self.z * self.z )
  48. magnitude = __abs__
  49. def __add__(self, other):
  50. 'Get the sum of this Vector3 and other one.'
  51. return Vector3Index( self.index, self.x + other.x, self.y + other.y, self.z + other.z )
  52. def __copy__(self):
  53. 'Get the copy of this Vector3.'
  54. return Vector3Index( self.index, self.x, self.y, self.z )
  55. __pos__ = __copy__
  56. copy = __copy__
  57. def __div__(self, other):
  58. 'Get a new Vector3 by dividing each component of this one.'
  59. return Vector3Index( self.index, self.x / other, self.y / other, self.z / other )
  60. def __eq__(self, other):
  61. 'Determine whether this vector is identical to other one.'
  62. if other == None:
  63. return False
  64. if other.__class__ != self.__class__:
  65. return False
  66. return self.x == other.x and self.y == other.y and self.z == other.z
  67. def __floordiv__(self, other):
  68. 'Get a new Vector3 by floor dividing each component of this one.'
  69. return Vector3Index( self.index, self.x // other, self.y // other, self.z // other )
  70. def _getAccessibleAttribute(self, attributeName):
  71. 'Get the accessible attribute.'
  72. global globalGetAccessibleAttributeSet
  73. if attributeName in globalGetAccessibleAttributeSet:
  74. return getattr(self, attributeName, None)
  75. return None
  76. def __hash__(self):
  77. 'Determine whether this vector is identical to other one.'
  78. return self.__repr__().__hash__()
  79. def __iadd__(self, other):
  80. 'Add other Vector3 to this one.'
  81. self.x += other.x
  82. self.y += other.y
  83. self.z += other.z
  84. return self
  85. def __idiv__(self, other):
  86. 'Divide each component of this Vector3.'
  87. self.x /= other
  88. self.y /= other
  89. self.z /= other
  90. return self
  91. def __ifloordiv__(self, other):
  92. 'Floor divide each component of this Vector3.'
  93. self.x //= other
  94. self.y //= other
  95. self.z //= other
  96. return self
  97. def __imul__(self, other):
  98. 'Multiply each component of this Vector3.'
  99. self.x *= other
  100. self.y *= other
  101. self.z *= other
  102. return self
  103. def __isub__(self, other):
  104. 'Subtract other Vector3 from this one.'
  105. self.x -= other.x
  106. self.y -= other.y
  107. self.z -= other.z
  108. return self
  109. def __itruediv__(self, other):
  110. 'True divide each component of this Vector3.'
  111. self.x = operator.truediv( self.x, other )
  112. self.y = operator.truediv( self.y, other )
  113. self.z = operator.truediv( self.z, other )
  114. return self
  115. def __mul__(self, other):
  116. 'Get a new Vector3 by multiplying each component of this one.'
  117. return Vector3Index( self.index, self.x * other, self.y * other, self.z * other )
  118. def __ne__(self, other):
  119. 'Determine whether this vector is not identical to other one.'
  120. return not self.__eq__(other)
  121. def __neg__(self):
  122. return Vector3Index( self.index, - self.x, - self.y, - self.z )
  123. def __nonzero__(self):
  124. return self.x != 0 or self.y != 0 or self.z != 0
  125. def __repr__(self):
  126. 'Get the string representation of this Vector3 index.'
  127. return '(%s, %s, %s, %s)' % (self.index, self.x, self.y, self.z)
  128. def __rdiv__(self, other):
  129. 'Get a new Vector3 by dividing each component of this one.'
  130. return Vector3Index( self.index, other / self.x, other / self.y, other / self.z )
  131. def __rfloordiv__(self, other):
  132. 'Get a new Vector3 by floor dividing each component of this one.'
  133. return Vector3Index( self.index, other // self.x, other // self.y, other // self.z )
  134. def __rmul__(self, other):
  135. 'Get a new Vector3 by multiplying each component of this one.'
  136. return Vector3Index( self.index, self.x * other, self.y * other, self.z * other )
  137. def __rtruediv__(self, other):
  138. 'Get a new Vector3 by true dividing each component of this one.'
  139. return Vector3Index( self.index, operator.truediv( other , self.x ), operator.truediv( other, self.y ), operator.truediv( other, self.z ) )
  140. def _setAccessibleAttribute(self, attributeName, value):
  141. 'Set the accessible attribute.'
  142. if attributeName in globalSetAccessibleAttributeSet:
  143. setattr(self, attributeName, value)
  144. def __sub__(self, other):
  145. 'Get the difference between the Vector3 and other one.'
  146. return Vector3Index( self.index, self.x - other.x, self.y - other.y, self.z - other.z )
  147. def __truediv__(self, other):
  148. 'Get a new Vector3 by true dividing each component of this one.'
  149. return Vector3Index( self.index, operator.truediv( self.x, other ), operator.truediv( self.y, other ), operator.truediv( self.z, other ) )
  150. def cross(self, other):
  151. 'Calculate the cross product of this vector with other one.'
  152. return Vector3Index( self.index, self.y * other.z - self.z * other.y, - self.x * other.z + self.z * other.x, self.x * other.y - self.y * other.x )
  153. def distance(self, other):
  154. 'Get the Euclidean distance between this vector and other one.'
  155. return math.sqrt( self.distanceSquared(other) )
  156. def distanceSquared(self, other):
  157. 'Get the square of the Euclidean distance between this vector and other one.'
  158. separationX = self.x - other.x
  159. separationY = self.y - other.y
  160. separationZ = self.z - other.z
  161. return separationX * separationX + separationY * separationY + separationZ * separationZ
  162. def dot(self, other):
  163. 'Calculate the dot product of this vector with other one.'
  164. return self.x * other.x + self.y * other.y + self.z * other.z
  165. def dropAxis( self, which = 2 ):
  166. 'Get a complex by removing one axis of the vector3.'
  167. if which == 0:
  168. return complex( self.y, self.z )
  169. if which == 1:
  170. return complex( self.x, self.z )
  171. if which == 2:
  172. return complex( self.x, self.y )
  173. def getFloatList(self):
  174. 'Get the vector as a list of floats.'
  175. return [ float( self.x ), float( self.y ), float( self.z ) ]
  176. def getIsDefault(self):
  177. 'Determine if this is the zero vector.'
  178. if self.x != 0.0:
  179. return False
  180. if self.y != 0.0:
  181. return False
  182. return self.z == 0.0
  183. def getNormalized(self):
  184. 'Get the normalized Vector3.'
  185. magnitude = abs(self)
  186. if magnitude == 0.0:
  187. return self.copy()
  188. return self / magnitude
  189. def magnitudeSquared(self):
  190. 'Get the square of the magnitude of the Vector3.'
  191. return self.x * self.x + self.y * self.y + self.z * self.z
  192. def maximize(self, other):
  193. 'Maximize the Vector3.'
  194. self.x =max(other.x, self.x)
  195. self.y =max(other.y, self.y)
  196. self.z =max(other.z, self.z)
  197. def minimize(self, other):
  198. 'Minimize the Vector3.'
  199. self.x =min(other.x, self.x)
  200. self.y =min(other.y, self.y)
  201. self.z =min(other.z, self.z)
  202. def normalize(self):
  203. 'Scale each component of this Vector3 so that it has a magnitude of 1. If this Vector3 has a magnitude of 0, this method has no effect.'
  204. magnitude = abs(self)
  205. if magnitude != 0.0:
  206. self /= magnitude
  207. def reflect( self, normal ):
  208. 'Reflect the Vector3 across the normal, which is assumed to be normalized.'
  209. distance = 2 * ( self.x * normal.x + self.y * normal.y + self.z * normal.z )
  210. return Vector3Index( self.index, self.x - distance * normal.x, self.y - distance * normal.y, self.z - distance * normal.z )
  211. def setToVector3(self, other):
  212. 'Set this Vector3 to be identical to other one.'
  213. self.x = other.x
  214. self.y = other.y
  215. self.z = other.z
  216. def setToXYZ( self, x, y, z ):
  217. 'Set the x, y, and z components of this Vector3.'
  218. self.x = x
  219. self.y = y
  220. self.z = z
  221. globalGetAccessibleAttributeSet = 'x y z'.split()
  222. globalSetAccessibleAttributeSet = globalGetAccessibleAttributeSet