burbomath 0.0.1

Burbokop's rust math library
Documentation
use super::{Abs, Angle, Atan2, Sq, Sqrt};
use crate::math::{Complex, Cos, Sin};
use core::ops::{Add, Div, Mul, Sub};

#[derive(Debug, Clone, Copy, PartialEq)]
pub struct Vector<T> {
    x: T,
    y: T,
}

impl<T> From<(T, T)> for Vector<T> {
    fn from(value: (T, T)) -> Self {
        Self {
            x: value.0,
            y: value.1,
        }
    }
}

impl<T> From<Vector<T>> for (T, T) {
    fn from(value: Vector<T>) -> Self {
        (value.x, value.y)
    }
}

impl<T> Add for Vector<T>
where
    T: Add,
{
    type Output = Vector<<T as Add>::Output>;

    fn add(self, rhs: Self) -> Self::Output {
        Self::Output {
            x: self.x + rhs.x,
            y: self.y + rhs.y,
        }
    }
}

impl<T> Sub for Vector<T>
where
    T: Sub,
{
    type Output = Vector<<T as Sub>::Output>;

    fn sub(self, rhs: Self) -> Self::Output {
        Self::Output {
            x: self.x - rhs.x,
            y: self.y - rhs.y,
        }
    }
}

impl<T> Mul<T> for Vector<T>
where
    T: Mul + Clone,
{
    type Output = Vector<<T as Mul>::Output>;

    fn mul(self, rhs: T) -> Self::Output {
        Self::Output {
            x: self.x * rhs.clone(),
            y: self.y * rhs,
        }
    }
}

impl<T> Mul<Complex<T>> for Vector<T>
where
    T: Mul<Output = T>,
    T: Add<Output = T>,
    T: Sub<Output = T>,
    T: Clone,
{
    type Output = Vector<T>;
    fn mul(self, rhs: Complex<T>) -> Self::Output {
        let (a, b) = self.into();
        let (c, d) = rhs.into_cartesian().into();

        (a.clone() * c.clone() - b.clone() * d.clone(), a * d + b * c).into()
    }
}

impl<T> Mul<Vector<T>> for Complex<T>
where
    T: Mul<Output = T>,
    T: Add<Output = T>,
    T: Sub<Output = T>,
    T: Clone,
{
    type Output = Vector<T>;
    fn mul(self, rhs: Vector<T>) -> Self::Output {
        let (a, b) = self.into_cartesian().into();
        let (c, d) = rhs.into();
        (a.clone() * c.clone() - b.clone() * d.clone(), a * d + b * c).into()
    }
}

impl<T> Div<T> for Vector<T>
where
    T: Div + Clone,
{
    type Output = Vector<<T as Div>::Output>;

    fn div(self, rhs: T) -> Self::Output {
        Self::Output {
            x: self.x / rhs.clone(),
            y: self.y / rhs,
        }
    }
}

impl<T> Vector<T> {
    pub fn from_polar(r: T, a: Angle<T>) -> Self
    where
        T: Clone + Cos<Output = T> + Sin<Output = T> + Mul<Output = T>,
    {
        Self {
            x: a.clone().cos() * r.clone(),
            y: a.clone().sin() * r.clone(),
        }
    }

    pub fn len(self) -> <<<T as Sq>::Output as Add>::Output as Sqrt>::Output
    where
        T: Sq,
        <T as Sq>::Output: Add,
        <<T as Sq>::Output as Add>::Output: Sqrt,
    {
        (self.x.sq() + self.y.sq()).sqrt()
    }

    pub fn manhattan_len(self) -> <<T as Abs>::Output as Add>::Output
    where
        T: Abs,
        <T as Abs>::Output: Add,
    {
        self.x.abs() + self.y.abs()
    }

    pub fn len_sqr(self) -> <<T as Sq>::Output as Add>::Output
    where
        T: Sq,
        <T as Sq>::Output: Add,
    {
        self.x.sq() + self.y.sq()
    }

    pub fn norm(self) -> Vector<T>
    where
        T: Sq<Output = T>,
        T: Add<Output = T>,
        T: Sqrt<Output = T>,
        T: Div<Output = T>,
        T: Clone,
    {
        self.clone() / self.len()
    }

    pub fn dot(self, rhs: Self) -> T
    where
        T: Mul<Output = T>,
        T: Add<Output = T>,
    {
        let (x0, y0) = self.into();
        let (x1, y1) = rhs.into();
        x0 * x1 + y0 * y1
    }

    pub fn cross(self, rhs: Self) -> T
    where
        T: Mul<Output = T>,
        T: Sub<Output = T>,
    {
        let (x0, y0) = self.into();
        let (x1, y1) = rhs.into();
        x0 * y1 - y0 * x1
    }

    pub fn rotor(self) -> Complex<T>
    where
        T: Sq<Output = T>,
        T: Add<Output = T>,
        T: Sqrt<Output = T>,
        T: Div<Output = T>,
        T: Clone,
    {
        let (r, i) = self.norm().into();
        Complex::from_cartesian(r, i)
    }
}

impl<T> Vector<T>
where
    T: Atan2,
{
    pub fn angle(self) -> Angle<<T as Atan2>::Output> {
        self.y.atan2(self.x)
    }
}

impl<T> Vector<T> {
    pub fn x(&self) -> &T {
        &self.x
    }
    pub fn y(&self) -> &T {
        &self.y
    }
}