Package gameobjects :: Module vector2
[hide private]
[frames] | no frames]

Source Code for Module gameobjects.vector2

  1  from math import sqrt 
  2  from util import format_number 
  3   
4 -class Vector2(object):
5 6 __slots__ = ('_v',) 7 8 _gameobjects_vector = 2 9 10
11 - def __init__(self, x=0., y=0.):
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
26 - def _get_length(self):
27 x, y = self._v 28 return sqrt(x*x + y*y)
29 - def _set_length(self, length):
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
44 - def from_floats(cls, x, y):
45 vec = cls.__new__(cls, object) 46 vec._v = [x, y] 47 return vec
48 49 50 @classmethod
51 - def from_iter(cls, iterable):
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
64 - def from_points(cls, p1, p2):
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
77 - def _from_float_sequence(cls, sequence):
78 v = cls.__new__(cls, object) 79 v._v = list(sequence[:2]) 80 return v
81 82
83 - def copy(self):
84 """Returns a copy of this object.""" 85 vec = self.__new__(self.__class__, object) 86 vec._v = self._v[:] 87 return vec
88
89 - def get_x(self):
90 return self._v[0]
91 - def set_x(self, x):
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
98 - def get_y(self):
99 return self._v[1]
100 - def set_y(self, y):
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
110 - def __str__(self):
111 112 x, y = self._v 113 return "(%s, %s)" % (format_number(x), format_number(y))
114
115 - def __repr__(self):
116 117 x, y = self._v 118 return "Vector2(%s, %s)" % (x, y)
119
120 - def __iter__(self):
121 122 return iter(self._v[:])
123
124 - def __len__(self):
125 126 return 2
127 128
129 - def __getitem__(self, index):
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
136 - def __setitem__(self, index, value):
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
147 - def __eq__(self, rhs):
148 x, y = self._v 149 xx, yy = rhs 150 return x == xx and y == yy
151
152 - def __ne__(self, rhs):
153 x, y = self._v 154 xx, yy, = rhs 155 return x != xx or y != yy
156
157 - def __hash__(self):
158 159 return hash(tuple(self._v))
160
161 - def __add__(self, rhs):
162 x, y = self._v 163 xx, yy = rhs 164 return Vector2.from_floats(x+xx, y+yy)
165 166
167 - def __iadd__(self, rhs):
168 xx, yy = rhs 169 v = self._v 170 v[0] += xx 171 v[1] += yy 172 return self
173
174 - def __radd__(self, lhs):
175 x, y = self._v 176 xx, yy = lhs 177 return self.from_floats(x+xx, y+yy)
178
179 - def __sub__(self, rhs):
180 x, y = self._v 181 xx, yy = rhs 182 return Vector2.from_floats(x-xx, y-yy)
183
184 - def __rsub__(self, lhs):
185 x, y = self._v 186 xx, yy = lhs 187 return self.from_floats(xx-x, yy-y)
188
189 - def _isub__(self, rhs):
190 191 xx, yy = rhs 192 v = self._v 193 v[0] -= xx 194 v[1] -= yy 195 return self
196 197
198 - def __mul__(self, rhs):
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
208 - def __imul__(self, rhs):
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
221 - def __rmul__(self, lhs):
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
232 - def __div__(self, rhs):
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
242 - def __idiv__(self, rhs):
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
255 - def __rdiv__(self, lhs):
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
265 - def __neg__(self):
266 """Return the negation of this vector.""" 267 x, y = self._v 268 return Vector2.from_floats(-x, -y)
269
270 - def __pos__(self):
271 272 return self.copy()
273
274 - def __nonzero__(self):
275 276 x, y = self._v 277 return x and y
278
279 - def __call__(self, keys):
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
296 - def as_tuple(self):
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
305 - def get_length(self):
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
312 - def normalise(self):
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
326 - def get_normalised(self):
327 x, y = self._v 328 l = sqrt(x*x +y*y) 329 return Vector2.from_floats(x/l, y/l)
330 get_normalized = get_normalised 331
332 - def get_distance_to(self, p):