1 """
2 Vector3 is a three dimensional vector class.
3
4 Below are examples of Vector3 use.
5
6 >>> from vector3 import Vector3
7 >>> origin = Vector3()
8 >>> origin
9 0.0, 0.0, 0.0
10 >>> pythagoras = Vector3( 3, 4, 0 )
11 >>> pythagoras
12 3.0, 4.0, 0.0
13 >>> pythagoras.magnitude()
14 5.0
15 >>> pythagoras.magnitudeSquared()
16 25
17 >>> triplePythagoras = pythagoras * 3.0
18 >>> triplePythagoras
19 9.0, 12.0, 0.0
20 >>> plane = pythagoras.dropAxis()
21 >>> plane
22 (3+4j)
23 """
24 from fabmetheus_utilities import xml_simple_writer
25 import math
26 import operator
27
28
29 __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
30 __credits__ = 'Nophead <http://forums.reprap.org/profile.php?12,28>\nArt of Illusion <http://www.artofillusion.org/>'
31 __date__ = '$Date: 2008/21/04 $'
32 __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
33
34
36 'A three dimensional vector index class.'
37 __slots__ = ['index', 'x', 'y', 'z']
38
39 - def __init__( self, index, x = 0.0, y = 0.0, z = 0.0 ):
40 self.index = index
41 self.x = x
42 self.y = y
43 self.z = z
44
46 'Get the magnitude of the Vector3.'
47 return math.sqrt( self.x * self.x + self.y * self.y + self.z * self.z )
48
49 magnitude = __abs__
50
52 'Get the sum of this Vector3 and other one.'
53 return Vector3Index( self.index, self.x + other.x, self.y + other.y, self.z + other.z )
54
56 'Get the copy of this Vector3.'
57 return Vector3Index( self.index, self.x, self.y, self.z )
58
59 __pos__ = __copy__
60
61 copy = __copy__
62
64 'Get a new Vector3 by dividing each component of this one.'
65 return Vector3Index( self.index, self.x / other, self.y / other, self.z / other )
66
68 'Determine whether this vector is identical to other one.'
69 if other == None:
70 return False
71 if other.__class__ != self.__class__:
72 return False
73 return self.x == other.x and self.y == other.y and self.z == other.z
74
76 'Get a new Vector3 by floor dividing each component of this one.'
77 return Vector3Index( self.index, self.x // other, self.y // other, self.z // other )
78
85
87 'Determine whether this vector is identical to other one.'
88 return self.__repr__().__hash__()
89
91 'Add other Vector3 to this one.'
92 self.x += other.x
93 self.y += other.y
94 self.z += other.z
95 return self
96
98 'Divide each component of this Vector3.'
99 self.x /= other
100 self.y /= other
101 self.z /= other
102 return self
103
105 'Floor divide each component of this Vector3.'
106 self.x //= other
107 self.y //= other
108 self.z //= other
109 return self
110
112 'Multiply each component of this Vector3.'
113 self.x *= other
114 self.y *= other
115 self.z *= other
116 return self
117
119 'Subtract other Vector3 from this one.'
120 self.x -= other.x
121 self.y -= other.y
122 self.z -= other.z
123 return self
124
126 'True divide each component of this Vector3.'
127 self.x = operator.truediv( self.x, other )
128 self.y = operator.truediv( self.y, other )
129 self.z = operator.truediv( self.z, other )
130 return self
131
133 'Get a new Vector3 by multiplying each component of this one.'
134 return Vector3Index( self.index, self.x * other, self.y * other, self.z * other )
135
137 'Determine whether this vector is not identical to other one.'
138 return not self.__eq__(other)
139
142
144 return self.x != 0 or self.y != 0 or self.z != 0
145
147 'Get the string representation of this Vector3 index.'
148 return '(%s, %s, %s, %s)' % (self.index, self.x, self.y, self.z)
149
151 'Get a new Vector3 by dividing each component of this one.'
152 return Vector3Index( self.index, other / self.x, other / self.y, other / self.z )
153
155 'Get a new Vector3 by floor dividing each component of this one.'
156 return Vector3Index( self.index, other // self.x, other // self.y, other // self.z )
157
159 'Get a new Vector3 by multiplying each component of this one.'
160 return Vector3Index( self.index, self.x * other, self.y * other, self.z * other )
161
163 'Get a new Vector3 by true dividing each component of this one.'
164 return Vector3Index( self.index, operator.truediv( other , self.x ), operator.truediv( other, self.y ), operator.truediv( other, self.z ) )
165
170
172 'Get the difference between the Vector3 and other one.'
173 return Vector3Index( self.index, self.x - other.x, self.y - other.y, self.z - other.z )
174
176 'Get a new Vector3 by true dividing each component of this one.'
177 return Vector3Index( self.index, operator.truediv( self.x, other ), operator.truediv( self.y, other ), operator.truediv( self.z, other ) )
178
180 'Calculate the cross product of this vector with other one.'
181 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 )
182
184 'Get the Euclidean distance between this vector and other one.'
185 return math.sqrt( self.distanceSquared(other) )
186
188 'Get the square of the Euclidean distance between this vector and other one.'
189 separationX = self.x - other.x
190 separationY = self.y - other.y
191 separationZ = self.z - other.z
192 return separationX * separationX + separationY * separationY + separationZ * separationZ
193
194 - def dot(self, other):
195 'Calculate the dot product of this vector with other one.'
196 return self.x * other.x + self.y * other.y + self.z * other.z
197
199 'Get a complex by removing one axis of the vector3.'
200 if which == 0:
201 return complex( self.y, self.z )
202 if which == 1:
203 return complex( self.x, self.z )
204 if which == 2:
205 return complex( self.x, self.y )
206
208 'Get the vector as a list of floats.'
209 return [ float( self.x ), float( self.y ), float( self.z ) ]
210
212 'Determine if this is the zero vector.'
213 if self.x != 0.0:
214 return False
215 if self.y != 0.0:
216 return False
217 return self.z == 0.0
218
220 'Get the normalized Vector3.'
221 magnitude = abs(self)
222 if magnitude == 0.0:
223 return self.copy()
224 return self / magnitude
225
227 'Get the square of the magnitude of the Vector3.'
228 return self.x * self.x + self.y * self.y + self.z * self.z
229
231 'Maximize the Vector3.'
232 self.x =max(other.x, self.x)
233 self.y =max(other.y, self.y)
234 self.z =max(other.z, self.z)
235
237 'Minimize the Vector3.'
238 self.x =min(other.x, self.x)
239 self.y =min(other.y, self.y)
240 self.z =min(other.z, self.z)
241
243 '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.'
244 magnitude = abs(self)
245 if magnitude != 0.0:
246 self /= magnitude
247
249 'Reflect the Vector3 across the normal, which is assumed to be normalized.'
250 distance = 2 * ( self.x * normal.x + self.y * normal.y + self.z * normal.z )
251 return Vector3Index( self.index, self.x - distance * normal.x, self.y - distance * normal.y, self.z - distance * normal.z )
252
254 'Set this Vector3 to be identical to other one.'
255 self.x = other.x
256 self.y = other.y
257 self.z = other.z
258
260 'Set the x, y, and z components of this Vector3.'
261 self.x = x
262 self.y = y
263 self.z = z
264
265
266 globalGetAccessibleAttributeSet = 'x y z'.split()
267 globalSetAccessibleAttributeSet = globalGetAccessibleAttributeSet
268