vctr2 0.1.8

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

#[derive(Copy, Clone, Debug, Eq, PartialEq, Default)]
pub struct Vector2<U> {
    pub x: U,
    pub y: U
}

impl<U> Vector2<U> {
    pub const fn new(x: U, y: U) -> Self {
        Vector2 { x, y }
    }
}


impl<U: Add<Output = V>, V> Add for Vector2<U> {
    type Output = Vector2<V>;
    fn add(self, rhs: Self) -> Self::Output {
        Vector2 {
            x: self.x+rhs.x,
            y: self.y+rhs.y
        }
    }
}
impl<U: AddAssign> AddAssign for Vector2<U> {
    fn add_assign(&mut self, rhs: Self) {
        self.x += rhs.x;
        self.y += rhs.y;
    }
}

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

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

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

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

impl<U> Mul<Vector2<U>> for Vector2<U>
where
    U: Mul<Output = U> + Add<Output = U>
{
    type Output = U;
    fn mul(self, rhs: Vector2<U>) -> Self::Output {
        self.x*rhs.x + self.y*rhs.y
    }
}

impl<U, W> Vector2<U>
where
    Vector2<U>: Clone + Copy + Mul<Vector2<U>, Output = W>
{
    pub fn length_squared(self) -> W {
        self * self
    }
}

impl Vector2<f32> {
    pub fn from_angle(angle: f32, magnitude: f32) -> Self {
        Vector2::new(
            magnitude * angle.cos(),
            magnitude * angle.sin()
        )
    }

    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)
    }

    pub fn angle_from(self, other: Self) -> f32 {
        (self * other / (self.length() * other.length())).acos()
    }
}
impl Vector2<f64> {
    pub fn from_angle(angle: f64, magnitude: f64) -> Self {
        Vector2::new(
            magnitude * angle.cos(),
            magnitude * angle.sin()
        )
    }

    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)
    }

    pub fn angle_between(&self, other: &Self) -> f64 {
        (*self * *other / (self.length() * other.length())).acos()
    }
}


impl<U: Clone + Default> Vector2<U> {
    pub fn horizontal(&self) -> Self {
        Vector2 {
            x: self.x.clone(),
            y: U::default()
        }
    } 
    pub fn vertical(&self) -> Self {
        Vector2 {
            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())
    }
}

impl<U: Zero + PartialEq> Zero for Vector2<U> {
    fn zero() -> Self {
        Vector2::new(U::zero(), U::zero())
    }

    fn is_zero(&self) -> bool {
        *self == Self::zero()
    }
}

impl Sum for Vector2<f32> {
    fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
         iter.fold(Vector2::new(0., 0.), |acc, v| acc+v)
    }
}
impl Sum for Vector2<f64> {
    fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
         iter.fold(Vector2::new(0., 0.), |acc, v| acc+v)
    }
}