Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import math
- from typing import Tuple
- VectorType = Tuple[float]
- class Vector:
- def __init__(self, *point: VectorType):
- self._vector = tuple(point)
- def scale(self, scalar: float) -> VectorType:
- self *= scalar
- return self
- @property
- def vector(self) -> tuple:
- return self._vector
- @property
- def dimension(self) -> int:
- return len(self.vector)
- @property
- def magnitude(self) -> float:
- return sum(map(lambda x: x**2, self.vector))**0.5
- @staticmethod
- def angle_between(vector1, vector2) -> float:
- return math.acos(sum(x * y for x, y in zip(vector1.vector, vector2.vector)) / (vector1.magnitude * vector2.magnitude))
- def _operator(self, oper, other):
- if isinstance(other, self.__class__) and self.dimension == other.dimension:
- return other.__class__(*[oper(x, y) for x, y in zip(self.vector, other.vector)])
- return NotImplemented
- def _ioperator(self, oper, other):
- if isinstance(other, self.__class__) and self.dimension == other.dimension:
- self.vector = tuple(oper(x, y) for x, y in zip(self.vector, other.vector))
- else:
- return NotImplemented
- return self
- def __repr__(self):
- return f'{self.__class__.__name__}{self.vector}'
- def __bool__(self):
- return bool(self.dimension)
- def __getitem__(self, index):
- return self.vector[index]
- def __iter__(self):
- for point in self.vector:
- yield point
- def __add__(self, other):
- return self._operator(lambda x, y: x + y, other)
- def __radd__(self, other):
- return self._operator(lambda x, y: y + x, other)
- def __iadd__(self, other):
- return self._ioperator(lambda x, y: y + x, other)
- def __sub__(self, other):
- return self._operator(lambda x, y: x - y, other)
- def __rsub__(self, other):
- return self._operator(lambda x, y: y - x, other)
- def __isub__(self, other):
- return self._ioperator(lambda x, y: y - x, other)
- def __mul__(self, other):
- if isinstance(other, (int, float)):
- return self.__class__(*[x * other for x in self.vector])
- elif isinstance(other, self.__class__) and self.dimension == other.dimension:
- return round(self.magnitude * other.magnitude * math.cos(Vector.angle_between(self, other)), 14)
- return NotImplemented
- def __rmul__(self, other):
- if isinstance(other, (int, float)) or isinstance(other, self.__class__) and self.dimension == other.dimension:
- return self * other
- return NotImplemented
- def __imul__(self, other):
- if isinstance(other, (int, float)):
- self.vector = tuple(x * other for x in self.vector)
- else:
- return NotImplemented
- return self
- class Vector2D(Vector):
- @property
- def direction(self) -> float:
- return math.atan2(self.vector[1], self.vector[0])
- if __name__ == '__main__':
- v = Vector(-1, 2)
- v2 = Vector2D(3, 4)
- print(v, v2, v*v2)
Add Comment
Please, Sign In to add comment