1 from math import sqrt
2 from util import format_number
3
5
6 __slots__ = ('_v',)
7
8 _gameobjects_vector = 2
9
10
12 """Initialise a vector
13
14 @type x: number
15 @param x: The x value (defaults to 0.), or a container of 2 values
16 @type x: number
17 @param y: The y value (defaults to 0.)
18
19 """
20 if hasattr(x, "__getitem__"):
21 x, y = x
22 self._v = [float(x), float(y)]
23 else:
24 self._v = [float(x), float(y)]
25
27 x, y = self._v
28 return sqrt(x*x + y*y)
30 v = self._v
31 try:
32 x, y = v
33 l = length / sqrt(x*x +y*y)
34 except ZeroDivisionError:
35 v[0] = 0.0
36 v[1] = 0.0
37 return self
38 v[0] *= l
39 v[1] *= l
40 length = property(_get_length, _set_length, None, "Length of the vector")
41
42
43 @classmethod
45 vec = cls.__new__(cls, object)
46 vec._v = [x, y]
47 return vec
48
49
50 @classmethod
52 """Creates a Vector2 object from an iterable.
53
54 @param iterable: An iterable of at least 2 numeric values
55
56 """
57 next = iter(iterable).next
58 vec = cls.__new__(cls, object)
59 vec._v = [float(next()), float(next())]
60 return vec
61
62
63 @classmethod
65 """Creates a Vector2 object between two points.
66 @param p1: First point
67 @param p2: Second point
68
69 """
70 v = cls.__new__(cls, object)
71 x, y = p1
72 xx, yy = p2
73 v._v = [float(xx-x), float(yy-y)]
74 return v
75
76 @classmethod
78 v = cls.__new__(cls, object)
79 v._v = list(sequence[:2])
80 return v
81
82
84 """Returns a copy of this object."""
85 vec = self.__new__(self.__class__, object)
86 vec._v = self._v[:]
87 return vec
88
92 try:
93 self._v[0] = 1.0 * x
94 except:
95 raise TypeError("Must be a number")
96 x = property(get_x, set_x, None, "x component.")
97
101 try:
102 self._v[1] = 1.0 * y
103 except:
104 raise TypeError("Must be a number")
105 y = property(get_y, set_y, None, "y component.")
106
107 u = property(get_x, set_y, None, "u component (alias for x).")
108 v = property(get_y, set_y, None, "v component (alias for y).")
109
114
116
117 x, y = self._v
118 return "Vector2(%s, %s)" % (x, y)
119
121
122 return iter(self._v[:])
123
127
128
130 """Gets a component as though the vector were a list."""
131 try:
132 return self._v[index]
133 except IndexError:
134 raise IndexError, "There are 2 values in this object, index should be 0 or 1"
135
137 """Sets a component as though the vector were a list."""
138
139 try:
140 self._v[index] = 1.0 * value
141 except IndexError:
142 raise IndexError, "There are 2 values in this object, index should be 0 or 1!"
143 except TypeError:
144 raise TypeError, "Must be a number"
145
146
148 x, y = self._v
149 xx, yy = rhs
150 return x == xx and y == yy
151
153 x, y = self._v
154 xx, yy, = rhs
155 return x != xx or y != yy
156
158
159 return hash(tuple(self._v))
160
165
166
168 xx, yy = rhs
169 v = self._v
170 v[0] += xx
171 v[1] += yy
172 return self
173
178
183
188
190
191 xx, yy = rhs
192 v = self._v
193 v[0] -= xx
194 v[1] -= yy
195 return self
196
197
199 """Return the result of multiplying this vector with a scalar or a vector-list object."""
200 x, y = self._v
201 if hasattr(rhs, "__getitem__"):
202 xx, yy = rhs
203 return Vector2.from_floats(x*xx, y*yy)
204 else:
205 return Vector2.from_floats(x*rhs, y*rhs)
206
207
209 """Multiplys this vector with a scalar or a vector-list object."""
210 if hasattr(rhs, "__getitem__"):
211 xx, yy = rhs
212 v = self._v
213 v[0] *= xx
214 v[1] *= yy
215 else:
216 v = self._v
217 v[0] *= rhs
218 v[1] *= rhs
219 return self
220
222
223 x, y = self._v
224 if hasattr(lhs, "__getitem__"):
225 xx, yy = lhs
226 else:
227 xx = lhs
228 yy = lhs
229 return self.from_floats(x*xx, y*yy)
230
231
233 """Return the result of dividing this vector by a scalar or a vector-list object."""
234 x, y = self._v
235 if hasattr(rhs, "__getitem__"):
236 xx, yy, = rhs
237 return Vector2.from_floats(x/xx, y/yy)
238 else:
239 return Vector2.from_floats(x/rhs, y/rhs)
240
241
243 """Divides this vector with a scalar or a vector-list object."""
244 if hasattr(rhs, "__getitem__"):
245 xx, yy = rhs
246 v = self._v
247 v[0] /= xx
248 v[1] /= yy
249 else:
250 v = self._v
251 v[0] /= rhs
252 v[1] /= rhs
253 return self
254
256
257 x, y = self._v
258 if hasattr(lhs, "__getitem__"):
259 xx, yy = lhs
260 else:
261 xx = lhs
262 yy = lhs
263 return self.from_floats(xx/x, yy/x)
264
269
271
272 return self.copy()
273
275
276 x, y = self._v
277 return x and y
278
280
281 """Used to swizzle a vector.
282
283 @type keys: string
284 @param keys: A string containing a list of component names
285 >>> vec = Vector(1, 2)
286 >>> vec('yx')
287 (1, 2)
288
289 """
290
291 ord_x = ord('x')
292 v = self._v
293 return tuple( v[ord(c) - ord_x] for c in keys )
294
295
297 """Converts this vector to a tuple.
298
299 @rtype: Tuple
300 @return: Tuple containing the vector components
301 """
302 return tuple(self._v)
303
304
306 """Returns the length of this vector."""
307 x, y = self._v
308 return sqrt(x*x + y*y)
309 get_magnitude = get_length
310
311
313 """Normalises this vector."""
314 v = self._v
315 x, y = v
316 l = sqrt(x*x +y*y)
317 try:
318 v[0] /= l
319 v[1] /= l
320 except ZeroDivisionError:
321 v[0] = 0.
322 v[1] = 0.
323 return self
324 normalize = normalise
325
330 get_normalized = get_normalised
331