149 lines
3.8 KiB
Python
149 lines
3.8 KiB
Python
from math import pi, degrees
|
|
|
|
class Vector(list):
|
|
|
|
def __init__(self, x=0, y=0):
|
|
list.__init__(self, (x, y))
|
|
|
|
def __repr__(self):
|
|
message = "<%f" % self[0]
|
|
for value in self[1:]:
|
|
message += ", %f" % value
|
|
return message + ">"
|
|
|
|
def __getattr__(self, name):
|
|
if name == "x":
|
|
return self[0]
|
|
elif name == "y":
|
|
return self[1]
|
|
else:
|
|
raise AttributeError
|
|
|
|
def __setattr__(self, name, value):
|
|
if name == "x":
|
|
self[0] = value
|
|
elif name == "y":
|
|
self[1] = value
|
|
else:
|
|
list.__setattr__(self, name, value)
|
|
|
|
def __add__(self, other):
|
|
return Vector(self.x + other[0], self.y + other[1])
|
|
|
|
__radd__ = __add__
|
|
|
|
def __iadd__(self, other):
|
|
self.x += other[0]
|
|
self.y += other[1]
|
|
return self
|
|
|
|
def __sub__(self, other):
|
|
return Vector(self.x - other[0], self.y - other[1])
|
|
|
|
def __rsub__(self, other):
|
|
return Vector(other[0] - self.x, other[1] - self.y)
|
|
|
|
def __isub__(self, other):
|
|
self.x -= other[0]
|
|
self.y -= other[1]
|
|
return self
|
|
|
|
def __mul__(self, other):
|
|
return Vector(self.x * other, self.y * other)
|
|
|
|
__rmul__ = __mul__
|
|
|
|
def __imul__(self, other):
|
|
self.x *= other
|
|
self.y *= other
|
|
return self
|
|
|
|
def __eq__(self, other):
|
|
for sv, ov in zip(self, other):
|
|
if sv != ov:
|
|
return False
|
|
return True
|
|
|
|
def __ne__(self, other):
|
|
for sv, ov in zip(self, other):
|
|
if sv == ov:
|
|
return False
|
|
return True
|
|
|
|
def __nonzero__(self):
|
|
for value in self:
|
|
if bool(value):
|
|
return True
|
|
return False
|
|
|
|
def apply_to_components(self, function):
|
|
self.x = function(self.x)
|
|
self.y = function(self.y)
|
|
|
|
def place(self, x=None, y=None):
|
|
if x is not None:
|
|
self.x = x
|
|
if y is not None:
|
|
self.y = y
|
|
|
|
def move(self, dx=0, dy=0):
|
|
if dx:
|
|
self.x += dx
|
|
if dy:
|
|
self.y += dy
|
|
|
|
def get_moved(self, dx=0, dy=0):
|
|
return Vector(self.x + dx, self.y + dy)
|
|
|
|
def place_at_origin(self):
|
|
self.place(0, 0)
|
|
|
|
def vol(self):
|
|
return self.x * self.y
|
|
|
|
def copy(self):
|
|
return Vector(self.x, self.y)
|
|
|
|
|
|
class EVector(Vector):
|
|
|
|
def __init__(self, x=0, y=0, dx=0, dy=0, magnitude=None, angle=0):
|
|
Vector.__init__(self, x, y)
|
|
self.angle = None
|
|
self.set_step(dx, dy, magnitude, angle)
|
|
|
|
def set_step(self, dx=0, dy=0, magnitude=None, angle=0):
|
|
"""specify angle in radians, counter-clockwise, 0 is up"""
|
|
if magnitude is not None:
|
|
from .extension import get_delta
|
|
self.magnitude = magnitude
|
|
self.angle = angle
|
|
self.dx, self.dy = get_delta(angle, magnitude, False)
|
|
else:
|
|
self.dx = dx
|
|
self.dy = dy
|
|
if dx == 0 and dy == 0:
|
|
self.magnitude = 0
|
|
self.angle = 0
|
|
else:
|
|
from .extension import get_angle, get_distance
|
|
end = self.x + dx, self.y + dy
|
|
self.angle = get_angle(self, end, True)
|
|
self.magnitude = get_distance(self, end)
|
|
|
|
def __repr__(self):
|
|
return "<dx=%.2f, dy=%.2f, m=%.2f, ang=%.2f>" % \
|
|
(self.dx, self.dy, self.magnitude, self.angle)
|
|
|
|
def __nonzero__(self):
|
|
return bool(self.magnitude)
|
|
|
|
def __setattr__(self, name, value):
|
|
list.__setattr__(self, name, value)
|
|
if name == "magnitude" and self.angle is not None:
|
|
from .extension import get_delta
|
|
self.dx, self.dy = get_delta(self.angle, value, False)
|
|
|
|
def move(self):
|
|
self += self.dx, self.dy
|