#copyright Mikael Matveinen 2008 import operator import math class Vector2D: def __init__(self, x, y): self.x = x self.y = y def __copy__(self): return self.__class__(self.x, self.y) copy = __copy__ def __eq__(self, other): assert isinstance(other, Vector2D) return self.x == other.x and self.y == other.y def __ne__(self, other): return not self.__eq__(other) def __nonzero__(self): return self.x != 0 or self.y != 0 def __add__(self, other): assert isinstance(other, Vector2D) return Vector2D(self.x + other.x, self.y + other.y) __radd__ = __add__ def __iadd__(self, other): assert isinstance(other, Vector2D) self.x += other.x self.y += other.y return self def __sub__(self, other): assert isinstance(other, Vector2D) return Vector2D(self.x - other.x, self.y - other.y) def __rsub__(self, other): assert isinstance(other, Vector2D) return Vector2D(other.x - self.x, other.y - self.y) def __mul__(self, number): return Vector2D(self.x * number, self.y * number) __rmul__ = __mul__ def __imul__(self, number): self.x *= number self.y *= number return self def __div__(self, number): return Vector2D(operator.truediv(self.x, number), operator.truediv(self.y, number)) def __rdiv__(self, number): return Vector2D(operator.truediv(number, self.x), operator.truediv(number, self.y)) def __neg__(self): return Vector2D(-self.x, -self.y) __pos__ = __copy__ def __abs__(self): return math.sqrt(self.x ** 2 + self.y ** 2) magnitude = __abs__ #magnitude squared if you don't need the absolute value, only the relative length def magnitude_sq(self): return self.x ** 2 + self.y ** 2 #normalized vector def normalize(self): m = self.magnitude() if m != 0: return Vector2D(self.x / m, self.y / m) #dot product def dot(self, other): assert isinstance(other, Vector2D) return self.x * other.x + self.y * other.y #get the vector perpendicular to self def perp(self): return Vector2D(-self.y, self.x) #truncate to a certain maximum length def trunc(self, len): if self.magnitude_sq() > len**2: return self.normalized() * len else: return self