brutils 0.1.51

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

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

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

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

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

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

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

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

    pub fn set_length(&mut self, length: f64) {
        let old = self.length_squared();
        if old != 0.0 || old != length * length {
            self.multiply_scalar((length * length / old).sqrt());
        }
    }

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

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

    pub fn normalize(&mut self) {
        let length = self.length();
        if length != 0.0 {
            self.x /= length;
            self.y /= length;
        }
    }

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

    pub fn cross(&self, other: &Vector2) -> f64 {
        self.x * other.y - self.y * other.x
    }

    pub fn angle(&self) -> f64 {
        let mut angle = self.y.atan2(self.x) * crate::math::RAD_TO_DEG;
        if angle < 0.0 {
            angle += 360.0;
        }
        angle
    }

    pub fn angle_rad(&self) -> f64 {
        self.y.atan2(self.x)
    }

    pub fn angle_relative_to(&self, other: &Vector2) -> f64 {
        self.cross(other).atan2(self.dot(other)) * crate::math::RAD_TO_DEG
    }

    pub fn angle_relative_to_rad(&self, other: &Vector2) -> f64 {
        self.cross(other).atan2(self.dot(other))
    }

    pub fn set_angle(&mut self, degrees: f64) {
        self.set_angle_rad(degrees * crate::math::DEG_TO_RAD);
    }

    pub fn set_angle_rad(&mut self, radians: f64) {
        self.set(self.length(), 0.0);
        self.rotate_rad(radians);
    }

    pub fn rotate(&mut self, degrees: f64) {
        self.rotate_rad(degrees * crate::math::DEG_TO_RAD);
    }

    pub fn rotate_rad(&mut self, radians: f64) {
        let cos = radians.cos();
        let sin = radians.sin();

        let new_x = self.x * cos - self.y * sin;
        let new_y = self.x * sin + self.y * cos;

        self.x = new_x;
        self.y = new_y;
    }

    pub fn rotate_around(&mut self, other: &Vector2, degrees: f64) {
        self.subtract(other);
        self.rotate(degrees);
        self.add(other);
    }

    pub fn rotate_around_rad(&mut self, other: &Vector2, radians: f64) {
        self.subtract(other);
        self.rotate_rad(radians);
        self.add(other);
    }

    pub fn nor(&mut self) {
        let length = self.length();
        if length != 0.0 {
            self.x /= length;
            self.y /= length;
        }
    }

    pub fn lerp(&mut self, target: &Vector2, alpha: f64) {
        let inv_progress = 1.0 - alpha;
        self.x = (self.x * inv_progress) + (target.x * alpha);
        self.y = (self.y * inv_progress) + (target.y * alpha);
    }

    pub fn set_to_random_direction(&mut self) {
        let theta = crate::random::random_double_range(0.0, std::f64::consts::PI * 2.0);
        self.set(theta.cos(), theta.sin());
    }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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