euphoria 0.1.1

A math lib for Computer Graphics
Documentation
use std::ops::{
    Add, AddAssign, Div, DivAssign, Index, IndexMut, Mul, MulAssign, Neg, Sub, SubAssign,
};

pub type Vec3 = Vector3D;

// TODO: implements generics
#[derive(Debug, PartialEq, Clone, Copy, Default)]
pub struct Vector3D {
    pub x: f32,
    pub y: f32,
    pub z: f32,
}

impl Vector3D {
    pub fn new(x: f32, y: f32, z: f32) -> Self {
        Self { x, y, z }
    }

    #[inline]
    pub fn magnitude(&self) -> f32 {
        (self.x * self.x + self.y * self.y + self.z * self.z).sqrt()
    }

    #[inline]
    pub fn normalize(&self) -> Self {
        (*self / self.magnitude())
    }
}

impl Index<u8> for Vector3D {
    type Output = f32;

    fn index(&self, index: u8) -> &f32 {
        match index {
            0 => &self.x,
            1 => &self.x,
            2 => &self.x,
            _ => panic!(
                "index out of bounds: the len is 3 but the index is {}",
                index
            ),
        }
    }
}

#[test]
fn index() {
    let v = Vec3::new(10., 10., 10.);

    assert_eq!(10., v[0]);
    assert_eq!(10., v[1]);
    assert_eq!(10., v[2]);

    //assert_eq!(10., v[3]);
}

impl IndexMut<u8> for Vector3D {
    fn index_mut(&mut self, index: u8) -> &mut f32 {
        match index {
            0 => &mut self.x,
            1 => &mut self.x,
            2 => &mut self.x,
            _ => panic!(
                "index out of bounds: the len is 3 but the index is {}",
                index
            ),
        }
    }
}

#[test]
fn index_mut() {
    let mut v = Vec3::new(10., 10., 10.);

    assert_eq!(10., v[0]);
    assert_eq!(10., v[1]);
    assert_eq!(10., v[2]);

    v[2] = 3.0;
    //assert_eq!(10., v[2]);
    assert_eq!(3., v[2]);
}

impl MulAssign<f32> for Vector3D {
    fn mul_assign(&mut self, s: f32) {
        self.x *= s;
        self.y *= s;
        self.z *= s;
    }
}

#[test]
fn mul_assign() {
    let mut v = Vec3::new(5., 5., 5.);

    v *= 4.0;
    assert_eq!(Vec3::new(20., 20., 20.), v);
}

impl DivAssign<f32> for Vector3D {
    fn div_assign(&mut self, mut s: f32) {
        s = 1.0f32 / s;
        self.x *= s;
        self.y *= s;
        self.z *= s;
    }
}

#[test]
fn div_assign() {
    let mut v = Vec3::new(20., 20., 20.);

    v /= 4.0;
    assert_eq!(Vec3::new(5., 5., 5.), v);
}

impl Mul<f32> for Vector3D {
    type Output = Self;

    fn mul(self, s: f32) -> Self {
        Self::new(self.x * s, self.y * s, self.z * s)
    }
}

#[test]
fn mul() {
    let v = Vec3::new(20., 20., 20.);

    let v = v * 4.0;
    assert_eq!(Vec3::new(80., 80., 80.), v);
}

impl Div<f32> for Vector3D {
    type Output = Self;

    fn div(self, mut s: f32) -> Self {
        s = 1.0f32 / s;
        Self::new(self.x * s, self.y * s, self.z * s)
    }
}

#[test]
fn div() {
    let mut v = Vec3::new(20., 20., 20.);

    v = v / 4.0;
    assert_eq!(Vec3::new(5., 5., 5.), v);
}

impl Neg for Vector3D {
    type Output = Self;
    fn neg(self) -> Self {
        Self::new(-self.x, -self.y, -self.z)
    }
}

#[test]
fn neg() {
    let v = Vec3::new(20., 20., 20.);

    assert_eq!(Vec3::new(-20., -20., -20.), -v);
}

impl AddAssign for Vector3D {
    fn add_assign(&mut self, v: Self) {
        *self = Self {
            x: self.x + v.x,
            y: self.y + v.y,
            z: self.z + v.z,
        }
    }
}

#[test]
fn add_assign() {
    let mut a = Vec3::new(20., 20., 20.);
    let b = Vec3::new(20., 20., 20.);

    a += b;

    assert_eq!(Vec3::new(40., 40., 40.), a);
}

impl SubAssign for Vector3D {
    fn sub_assign(&mut self, v: Self) {
        *self = Self {
            x: self.x - v.x,
            y: self.y - v.y,
            z: self.z - v.z,
        }
    }
}

#[test]
fn sub_assign() {
    let mut a = Vec3::new(40., 40., 40.);
    let b = Vec3::new(20., 20., 20.);

    a -= b;

    assert_eq!(Vec3::new(20., 20., 20.), a);
}

impl Add for Vector3D {
    type Output = Self;
    fn add(self, v: Self) -> Self {
        Self {
            x: self.x + v.x,
            y: self.y + v.y,
            z: self.z + v.z,
        }
    }
}

#[test]
fn add() {
    let a = Vec3::new(20., 20., 20.);
    let b = Vec3::new(20., 20., 20.);

    let v = a + b;

    assert_eq!(Vec3::new(40., 40., 40.), v);
}

impl Sub for Vector3D {
    type Output = Self;
    fn sub(self, v: Self) -> Self {
        Self {
            x: self.x - v.x,
            y: self.y - v.y,
            z: self.z - v.z,
        }
    }
}

#[test]
fn sub() {
    let a = Vec3::new(40., 40., 40.);
    let b = Vec3::new(20., 20., 20.);

    let v = a - b;

    assert_eq!(Vec3::new(20., 20., 20.), v);
}

impl From<[f32; 3]> for Vector3D {
    fn from(n: [f32; 3]) -> Self {
        Self {
            x: n[0],
            y: n[1],
            z: n[2],
        }
    }
}

#[test]
fn from() {
    let n = [2., 3., 4.];

    let v = Vec3::from(n);

    assert_eq!(Vec3::new(2., 3., 4.), v);
}