from __future__ import annotations from math import cos, sin, sqrt class Vec: def __init__(self, x: float = 0, y: float = 0) -> None: self.x: float = x self.y: float = y def __add__(self, other: float | Vec) -> Vec: if isinstance(other, Vec): return Vec(self.x + other.x, self.y + other.y) return Vec(self.x + other, self.y + other) def __sub__(self, other: float | Vec) -> Vec: if isinstance(other, Vec): return Vec(self.x - other.x, self.y - other.y) return Vec(self.x - other, self.y - other) def __mul__(self, value: float) -> Vec: return Vec(self.x * value, self.y * value) def __truediv__(self, value: float) -> Vec: return Vec(self.x / value, self.y / value) def dot(self, other: Vec) -> float: return self.x * other.x + self.y * other.y def mag(self) -> float: return sqrt(self.mag2()) def mag2(self) -> float: return self.dot(self) def cross(self, other: Vec) -> float: return self.x * other.y - self.y * other.x @property def normalized(self) -> Vec: mag: float = self.mag() if mag == 0: return Vec() return self / mag def __len__(self) -> int: return 2 def __getitem__(self, item): return [self.x, self.y][item] @property def perp(self) -> Vec: return Vec(-self.y, self.x) def __repr__(self) -> str: return f"Vec({self.x}, {self.y})" def rotate(self, angle: float) -> Vec: return Vec( cos(angle) * self.x - sin(angle) * self.y, sin(angle) * self.x + cos(angle) * self.y, ) def within(self, p1: Vec, p2: Vec) -> bool: x1, x2 = min(p1.x, p2.x), max(p1.x, p2.x) y1, y2 = min(p1.y, p2.y), max(p1.y, p2.y) return (x1 <= self.x <= x2) and (y1 <= self.y <= y2)