77 lines
1.8 KiB
Python
77 lines
1.8 KiB
Python
from __future__ import annotations
|
|
import math
|
|
from functools import lru_cache
|
|
from typing import NamedTuple
|
|
|
|
CACHE_SIZE = None
|
|
|
|
|
|
def hypotenuse(leg: float,
|
|
other_leg: float) -> float:
|
|
"""Returns hypotenuse for given legs"""
|
|
return math.sqrt(leg ** 2 + other_leg ** 2)
|
|
|
|
|
|
class Vector(NamedTuple):
|
|
slope: float
|
|
length: float
|
|
|
|
@property
|
|
@lru_cache(CACHE_SIZE)
|
|
def angle(self) -> float:
|
|
return math.atan(self.slope)
|
|
|
|
@property
|
|
@lru_cache(CACHE_SIZE)
|
|
def x(self) -> float:
|
|
return self.length * math.sin(self.angle)
|
|
|
|
@property
|
|
@lru_cache(CACHE_SIZE)
|
|
def y(self) -> float:
|
|
return self.length * math.cos(self.angle)
|
|
|
|
def __add__(self, other: Vector) -> Vector:
|
|
"""Returns self + other"""
|
|
new_x = self.x + other.x
|
|
new_y = self.y + other.y
|
|
new_length = hypotenuse(new_x, new_y)
|
|
new_slope = new_y / new_x
|
|
return Vector(new_slope, new_length)
|
|
|
|
def __neg__(self) -> Vector:
|
|
"""Returns -self"""
|
|
return Vector(self.slope, -self.length)
|
|
|
|
def __sub__(self, other: Vector) -> Vector:
|
|
"""Returns self - other"""
|
|
return self + (-other)
|
|
|
|
def __mul__(self, scalar: float) -> Vector:
|
|
"""Returns self * scalar"""
|
|
return Vector(self.slope, self.length * scalar)
|
|
|
|
def __truediv__(self, scalar: float) -> Vector:
|
|
"""Returns self / scalar"""
|
|
return self * (1 / scalar)
|
|
|
|
|
|
if __name__ == '__main__':
|
|
v1 = Vector(1, 1)
|
|
|
|
print("Pretty print:")
|
|
print(v1, end='\n' * 2)
|
|
|
|
print("Addition:")
|
|
v2 = v1 + v1
|
|
print(v1 + v1, end='\n' * 2)
|
|
|
|
print("Subtraction:")
|
|
print(v2 - v1, end='\n' * 2)
|
|
|
|
print("Multiplication:")
|
|
print(v1 * 2, end='\n' * 2)
|
|
|
|
print("Division:")
|
|
print(v2 / 2)
|