burbomath 0.0.1

Burbokop's rust math library
Documentation
use super::{Vector, Zero};
use crate::math::{self, Complex, Sq, Sqrt};
use core::ops::{Add, Mul, Sub};

#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};

#[derive(Debug, Clone, Copy, PartialEq)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct Point<T> {
    x: T,
    y: T,
}

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

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

impl<T> From<Point<T>> for [T; 2] {
    fn from(value: Point<T>) -> Self {
        [value.x, value.y]
    }
}

impl<T: Sub> Sub for Point<T> {
    type Output = Vector<<T as Sub>::Output>;
    fn sub(self, rhs: Self) -> Self::Output {
        (self.x - rhs.x, self.y - rhs.y).into()
    }
}

impl<T: Add> Add<Vector<T>> for Point<T> {
    type Output = Point<<T as Add>::Output>;
    fn add(self, rhs: Vector<T>) -> Self::Output {
        let (x, y) = rhs.into();
        (self.x + x, self.y + y).into()
    }
}

impl<T: Sub> Sub<Vector<T>> for Point<T> {
    type Output = Point<<T as Sub>::Output>;
    fn sub(self, rhs: Vector<T>) -> Self::Output {
        let (x, y) = rhs.into();
        (self.x - x, self.y - y).into()
    }
}

impl<T> Point<T> {
    pub fn origin() -> Self
    where
        T: Zero,
    {
        Self {
            x: T::zero(),
            y: T::zero(),
        }
    }

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

    pub fn absolute(self, origin: Point<T>) -> Self
    where
        T: Add<Output = T>,
    {
        (origin.x + self.x, origin.y + self.y).into()
    }

    pub fn relative(self, origin: Point<T>) -> Self
    where
        T: Sub<Output = T>,
    {
        (self.x - origin.x, self.y - origin.y).into()
    }

    pub fn distance(self, rhs: Point<T>) -> T
    where
        T: Sub<Output = T>,
        T: Sq<Output = T>,
        T: Add<Output = T>,
        T: Sqrt<Output = T>,
    {
        (self - rhs).len()
    }

    pub fn rotated(&self, center: Point<T>, rotor: Complex<T>) -> Point<T>
    where
        T: Add<Output = T>,
        T: Sub<Output = T>,
        T: Mul<Output = T>,
        T: Clone,
    {
        math::lerp(center, self.clone(), rotor)
    }
}

impl Point<f32> {
    pub fn as_f64(self) -> Point<f64> {
        Point {
            x: self.x as f64,
            y: self.y as f64,
        }
    }
}

impl Point<i32> {
    pub fn as_f64(self) -> Point<f64> {
        Point {
            x: self.x as f64,
            y: self.y as f64,
        }
    }

    pub fn as_f32(self) -> Point<f32> {
        Point {
            x: self.x as f32,
            y: self.y as f32,
        }
    }
}

impl Point<f64> {
    pub fn as_f32(self) -> Point<f32> {
        Point {
            x: self.x as f32,
            y: self.y as f32,
        }
    }
}