diff --git a/src/maths.py b/src/maths.py new file mode 100644 index 0000000..8a92934 --- /dev/null +++ b/src/maths.py @@ -0,0 +1,99 @@ +""" +Module contenant des utilitaires mathématiques. +""" + + +import math +from typing import SupportsFloat, Union + + +class Vec2: + """ + Un vecteur 2D + """ + + def __init__(self, *args: Union[SupportsFloat, "Vec2"]): + if ( + len(args) == 2 + and isinstance(args[0], SupportsFloat) + and isinstance(args[1], SupportsFloat) + ): + self.x = float(args[0]) + self.y = float(args[1]) + elif len(args) == 1: + if isinstance(args[0], Vec2): + self.x = args[0].x + self.y = args[0].y + else: + self.x = float(args[0]) + self.y = float(args[0]) + elif len(args) == 0: + self.x = 0.0 + self.y = 0.0 + else: + raise ValueError("Invalid number of arguments") + + def __add__(self, other: object) -> "Vec2": + if isinstance(other, Vec2): + return Vec2(self.x + other.x, self.y + other.y) + elif isinstance(other, SupportsFloat): + return Vec2(self.x + float(other), self.y + float(other)) + raise ValueError( + f"Unsupported operand type(s) for +: 'Vec2' and '{type(other)}'" + ) + + def __sub__(self, other: object) -> "Vec2": + if isinstance(other, Vec2): + return Vec2(self.x - other.x, self.y - other.y) + elif isinstance(other, SupportsFloat): + return Vec2(self.x - float(other), self.y - float(other)) + raise ValueError( + f"Unsupported operand type(s) for -: 'Vec2' and '{type(other)}'" + ) + + def __mul__(self, other: object) -> "Vec2": + if isinstance(other, Vec2): + return Vec2(self.x * other.x, self.y * other.y) + elif isinstance(other, SupportsFloat): + return Vec2(self.x * float(other), self.y * float(other)) + raise ValueError( + f"Unsupported operand type(s) for *: 'Vec2' and '{type(other)}'" + ) + + def __truediv__(self, other: object) -> "Vec2": + if isinstance(other, Vec2): + return Vec2(self.x / other.x, self.y / other.y) + elif isinstance(other, SupportsFloat): + return Vec2(self.x / float(other), self.y / float(other)) + raise ValueError( + f"Unsupported operand type(s) for /: 'Vec2' and '{type(other)}'" + ) + + def __eq__(self, other: object) -> bool: + if isinstance(other, Vec2): + return self.x == other.x and self.y == other.y + return False + + def __hash__(self) -> int: + return hash((self.x, self.y)) + + def __neg__(self) -> "Vec2": + return Vec2(-self.x, -self.y) + + @property + def length(self) -> float: + """ + Retourne la longueur du vecteur. + """ + return math.sqrt(self.x**2 + self.y**2) + + @property + def normalized(self) -> "Vec2": + """ + Retourne une version normalisé du vecteur. + """ + length = self.length + return Vec2(self.x / length, self.y / length) + + def __repr__(self) -> str: + return f"Vec2({self.x}, {self.y})"