vctr2 0.1.8

A simple 2d vector library
Documentation
use std::ops::{Index, IndexMut, Add, AddAssign, Sub, SubAssign, Neg, Mul, MulAssign, Div, DivAssign};

#[derive(Copy, Clone, Debug, Eq, PartialEq, Default)]
pub struct Matrix2x2<U> {
    mat: [[U; 2]; 2]
}

impl<U> Matrix2x2<U> {
    pub const fn new(m00: U, m01: U, m10: U, m11: U) -> Self {
        Matrix2x2 {
            mat: [
                [m00, m01],
                [m10, m11]
            ]
        }
    }
}

impl<U> Index<usize> for Matrix2x2<U> {
    type Output = [U; 2];
    fn index(&self, index: usize) -> &Self::Output {
        &self.mat[index]
    }
}
impl<U> IndexMut<usize> for Matrix2x2<U> {
    fn index_mut(&mut self, index: usize) -> &mut Self::Output {
        &mut self.mat[index]
    }
}


impl<U: Add<Output = V>, V> Add for Matrix2x2<U> {
    type Output = V;
    fn add(self, rhs: Self) -> Self::Output {
        self[0][0] + other[0][0]
        // Matrix2x2::new(
        //     self[0][0] + other[0][0],
        //     self[0][1] + other[0][1],
        //     self[1][0] + other[1][0],
        //     self[1][1] + other[1][1],
        // )
    }
}
impl<U: AddAssign> AddAssign for Matrix2x2<U> {
    fn add_assign(&mut self, rhs: Self) {
        self.x += rhs.x;
        self.y += rhs.y;
    }
}

impl<U: Sub<Output = V>, V> Sub for Matrix2x2<U> {
    type Output = Matrix2x2<V>;
    fn sub(self, rhs: Self) -> Self::Output {
        Matrix2x2 {
            x: self.x-rhs.x,
            y: self.y-rhs.y
        }
    }
}
impl<U: SubAssign> SubAssign for Matrix2x2<U> {
    fn sub_assign(&mut self, rhs: Self) {
        self.x -= rhs.x;
        self.y -= rhs.y;
    }
}

impl<U: Neg<Output = V>, V> Neg for Matrix2x2<U> {
    type Output = Matrix2x2<V>;
    fn neg(self) -> Self::Output {
        Matrix2x2 {
            x: -self.x,
            y: -self.y
        }
    }
}

impl<U, V> Mul<U> for Matrix2x2<U>
where
    U: Mul<Output = V> + Clone
{
    type Output = Matrix2x2<V>;
    fn mul(self, rhs: U) -> Self::Output {
        Matrix2x2 {
            x: self.x*rhs.clone(),
            y: self.y*rhs.clone()
        }
    }
}
impl<U: MulAssign + Clone> MulAssign<U> for Matrix2x2<U> {
    fn mul_assign(&mut self, rhs: U) {
        self.x *= rhs.clone();
        self.y *= rhs.clone();
    }
}

impl<U, V> Div<U> for Matrix2x2<U>
where
    U: Div<Output = V> + Clone
{
    type Output = Matrix2x2<V>;
    fn div(self, rhs: U) -> Self::Output {
        Matrix2x2 {
            x: self.x/rhs.clone(),
            y: self.y/rhs.clone()
        }
    }
}
impl<U: DivAssign + Clone> DivAssign<U> for Matrix2x2<U> {
    fn div_assign(&mut self, rhs: U) {
        self.x /= rhs.clone();
        self.y /= rhs.clone();
    }
}

impl<U> Mul<Matrix2x2<U>> for Matrix2x2<U>
where
    U: Mul<Output = U> + Add<Output = U>
{
    type Output = U;

    fn mul(self, rhs: Matrix2x2<U>) -> Self::Output {
        self.x*rhs.x + self.y*rhs.y
    }
}


impl<U, V, W> Matrix2x2<U>
where 
    U: Mul<Output = V> + Clone,
    V: Add<Output = W>
{
    pub fn length_squared(&self) -> W {
        self.x.clone()*self.x.clone() + self.y.clone()*self.y.clone()
    }
}


impl Matrix2x2<f32> {
    pub fn length(&self) -> f32 {
        f32::sqrt(self.length_squared())
    }

    pub fn distance(self, other: Self) -> f32 {
        (self - other).length()
    }

    // If the length of the vector is zero, returns the vector itself.
    pub fn normalized(&self) -> Self {
        let length = self.length();

        if length == 0. {
            *self
        } else {
            *self / length
        }
    }
    pub fn normalize(&mut self) -> &mut Self {
        *self = self.normalized();

        self
    }

    pub fn angle(&self) -> f32 {
        f32::atan2(self.y, self.x)
    }
}
impl Matrix2x2<f64> {
    pub fn length(&self) -> f64 {
        f64::sqrt(self.length_squared())
    }

    pub fn distance(self, other: Self) -> f64 {
        (self - other).length()
    }

    // If the length of the vector is zero, returns the vector itself.
    pub fn normalized(&self) -> Self {
        let length = self.length();

        if length == 0. {
            *self
        } else {
            *self / length
        }
    }
    pub fn normalize(&mut self) -> &mut Self {
        *self = self.normalized();

        self
    }

    pub fn angle(&self) -> f64 {
        f64::atan2(self.y, self.x)
    }
}


impl<U: Clone + Default> Matrix2x2<U> {
    pub fn horizontal(&self) -> Self {
        Matrix2x2 {
            x: self.x.clone(),
            y: U::default()
        }
    } 
    pub fn vertical(&self) -> Self {
        Matrix2x2 {
            x: U::default(),
            y: self.y.clone()
        }
    }
}


impl<U: Clone + Copy + Neg<Output = U>> Vector2<U> {
    pub fn normal(&self) -> Self {
        Vector2 {
            x: -self.y,
            y: self.x
        }
    }
}


impl<U: Clone + Copy> From<[U; 2]> for Vector2<U> {
    fn from(value: [U; 2]) -> Self {
        Vector2::new(value[0], value[1])
    }
}
impl<U: Clone + Copy> From<(U, U)> for Vector2<U> {
    fn from(value: (U, U)) -> Self {
        Vector2::new(value.0, value.1)
    }
}

impl<U> Vector2<U> {
    fn from_vec2<V: From<U>>(src: Vector2<U>) -> Vector2<V> {
        Vector2::<V>::new(src.x.into(), src.y.into())
    }
    fn into_vec2<V: Into<U>>(src: Vector2<V>) -> Vector2<U> {
        Vector2::<U>::new(src.x.into(), src.y.into())
    }
}