brutils 0.1.51

Some utilities for Rust
Documentation
use std::fmt;
use std::fmt::Display;
use std::ops;

/// 3 component vector, values are stored as doubles (f64)
#[derive(Debug, Clone, Copy)]
pub struct Vector3 {
    pub x: f64,
    pub y: f64,
    pub z: f64
}

impl Default for Vector3 {
    fn default() -> Self {
        Vector3 { x: 0.0, y: 0.0, z: 0.0 }
    }
}

impl Display for Vector3 {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "[x: {}, y: {}, z: {}]", self.x, self.y, self.z)
    }
}

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

    pub fn set(&mut self, x: f64, y: f64, z: f64) {
        self.x = x;
        self.y = y;
        self.z = z;
    }

    pub fn set_from_spherical(&mut self, azimuthal_angle: f64, polar_angle: f64) {
        let cos_azim = azimuthal_angle.cos();
        let sin_azim = azimuthal_angle.sin();

        let cos_polar = polar_angle.cos();
        let sin_polar = polar_angle.sin();

        self.set(cos_azim * sin_polar, sin_azim * sin_polar, cos_polar);
    }

    pub fn set_random_direction(&mut self) {
        let u = crate::random::random_double();
        let v = crate::random::random_double();

        let theta = std::f64::consts::PI * 2.0 * u;
        let phi = (2.0 * v - 1.0).acos();

        self.set_from_spherical(theta, phi);
    }

    pub fn length(&self) -> f64 {
        (self.x * self.x + self.y * self.y + self.z * self.z).sqrt()
    }

    pub fn length_squared(&self) -> f64 {
        self.x * self.x + self.y * self.y + self.z * self.z
    }

    pub fn distance(&self, other: &Vector3) -> f64 {
        ((self.x - other.x) * (self.x - other.x) + (self.y - other.y) * (self.y - other.y) + (self.z - other.z) * (self.z - other.z)).sqrt()
    }

    pub fn distance_squared(&self, other: &Vector3) -> f64 {
        (self.x - other.x) * (self.x - other.x) + (self.y - other.y) * (self.y - other.y) + (self.z - other.z) * (self.z - other.z)
    }

    pub fn dot(&self, other: &Vector3) -> f64 {
        self.x * other.x + self.y * other.y + self.z * other.z
    }

    pub fn cross(&self, other: &Vector3) -> Vector3 {
        Vector3::new(self.y * other.z - self.z * other.y, self.z * other.x - self.x * other.z, self.x * other.y - self.y * other.x)
    }

    pub fn lerp(&mut self, target: &Vector3, alpha: f64) {
        self.x += alpha * (target.x - self.x);
        self.y += alpha * (target.y - self.y);
        self.z += alpha * (target.z - self.z);
    }

    pub fn nor(&mut self) {
        let length = self.length_squared();
        if length == 0.0 || length == 1.0 {
            return;
        }
        self.multiply_scalar(1.0 / length.sqrt());
    }

    pub fn slerp(&mut self, target: &Vector3, alpha: f64) {
        let dot = self.dot(target);

        if dot > 0.9995 || dot < -0.9995 {
            self.lerp(target, alpha);
            return;
        }

        let theta0 = dot.acos();
        let theta = theta0 * alpha;

        let st = theta.sin();
        let tx = target.x - self.x * dot;
        let ty = target.y - self.y * dot;
        let tz = target.z - self.z * dot;
        let l2 = tx * tx + ty * ty + tz * tz;
        let dl = st * (if l2 < 0.0001 { 1.0 } else { l2.sqrt() });

        self.multiply_scalar(theta.cos());
        self.add(&Vector3::new(tx * dl, ty * dl, tz * dl));
        self.nor();
    }

    pub fn copy(&self) -> Self {
        Vector3 { x: self.x, y: self.y, z: self.z }
    }

    pub fn add(&mut self, other: &Vector3) {
        self.x += other.x;
        self.y += other.y;
        self.z += other.z;
    }

    pub fn subtract(&mut self, other: &Vector3) {
        self.x -= other.x;
        self.y -= other.y;
        self.z -= other.z;
    }

    pub fn multiply(&mut self, other: &Vector3) {
        self.x *= other.x;
        self.y *= other.y;
        self.z *= other.z;
    }

    pub fn divide(&mut self, other: &Vector3) {
        self.x /= other.x;
        self.y /= other.y;
        self.z /= other.z;
    }

    pub fn add_scalar(&mut self, scalar: f64) {
        self.x += scalar;
        self.y += scalar;
        self.z += scalar;
    }

    pub fn subtract_scalar(&mut self, scalar: f64) {
        self.x -= scalar;
        self.y -= scalar;
        self.z -= scalar;
    }

    pub fn multiply_scalar(&mut self, scalar: f64) {
        self.x *= scalar;
        self.y *= scalar;
        self.z *= scalar;
    }

    pub fn divide_scalar(&mut self, scalar: f64) {
        self.x /= scalar;
        self.y /= scalar;
        self.z /= scalar;
    }
}

impl ops::Add for Vector3 {
    type Output = Vector3;

    fn add(self, other: Vector3) -> Vector3 {
        Vector3 { x: self.x + other.x, y: self.y + other.y, z: self.z + other.z }
    }
}

impl ops::Sub for Vector3 {
    type Output = Vector3;

    fn sub(self, other: Vector3) -> Vector3 {
        Vector3 { x: self.x - other.x, y: self.y - other.y, z: self.z - other.z }
    }
}

impl ops::Mul for Vector3 {
    type Output = Vector3;

    fn mul(self, other: Vector3) -> Vector3 {
        Vector3 { x: self.x * other.x, y: self.y * other.y, z: self.z * other.z }
    }
}

impl ops::Div for Vector3 {
    type Output = Vector3;

    fn div(self, other: Vector3) -> Vector3 {
        Vector3 { x: self.x / other.x, y: self.y / other.y, z: self.z / other.z }
    }
}

impl ops::Add<f64> for Vector3 {
    type Output = Vector3;

    fn add(self, scalar: f64) -> Vector3 {
        Vector3 { x: self.x + scalar, y: self.y + scalar, z: self.z + scalar }
    }
}

impl ops::Sub<f64> for Vector3 {
    type Output = Vector3;

    fn sub(self, scalar: f64) -> Vector3 {
        Vector3 { x: self.x - scalar, y: self.y - scalar, z: self.z - scalar }
    }
}

impl ops::Mul<f64> for Vector3 {
    type Output = Vector3;

    fn mul(self, scalar: f64) -> Vector3 {
        Vector3 { x: self.x * scalar, y: self.y * scalar, z: self.z * scalar }
    }
}

impl ops::Div<f64> for Vector3 {
    type Output = Vector3;

    fn div(self, scalar: f64) -> Vector3 {
        Vector3 { x: self.x / scalar, y: self.y / scalar, z: self.z / scalar }
    }
}

impl ops::AddAssign for Vector3 {
    fn add_assign(&mut self, other: Vector3) {
        self.add(&other);
    }
}

impl ops::SubAssign for Vector3 {
    fn sub_assign(&mut self, other: Vector3) {
        self.subtract(&other);
    }
}

impl ops::MulAssign for Vector3 {
    fn mul_assign(&mut self, other: Vector3) {
        self.multiply(&other);
    }
}

impl ops::DivAssign for Vector3 {
    fn div_assign(&mut self, other: Vector3) {
        self.divide(&other);
    }
}

impl ops::AddAssign<f64> for Vector3 {
    fn add_assign(&mut self, scalar: f64) {
        self.add_scalar(scalar);
    }
}

impl ops::SubAssign<f64> for Vector3 {
    fn sub_assign(&mut self, scalar: f64) {
        self.subtract_scalar(scalar);
    }
}

impl ops::MulAssign<f64> for Vector3 {
    fn mul_assign(&mut self, scalar: f64) {
        self.multiply_scalar(scalar);
    }
}

impl ops::DivAssign<f64> for Vector3 {
    fn div_assign(&mut self, scalar: f64) {
        self.divide_scalar(scalar);
    }
}

impl ops::Neg for Vector3 {
    type Output = Vector3;

    fn neg(self) -> Vector3 {
        Vector3 { x: -self.x, y: -self.y, z: -self.z }
    }
}