use std::ops::{Add, Sub, Mul};
pub type RFloat = f32;
#[derive(PartialEq, Clone, Copy, Default, Debug)]
pub struct Vector {
pub x: RFloat,
pub y: RFloat,
pub z: RFloat,
}
impl Add for Vector {
type Output = Vector;
#[inline(always)]
fn add(self, rhs: Vector) -> Vector {
Vector {
x: self.x + rhs.x,
y: self.y + rhs.y,
z: self.z + rhs.z,
}
}
}
impl Sub for Vector {
type Output = Vector;
#[inline(always)]
fn sub(self, rhs: Vector) -> Vector {
Vector {
x: self.x - rhs.x,
y: self.y - rhs.y,
z: self.z - rhs.z,
}
}
}
impl Mul for Vector {
type Output = Vector;
#[inline(always)]
fn mul(self, rhs: Vector) -> Vector {
Vector {
x: self.x * rhs.x,
y: self.y * rhs.y,
z: self.z * rhs.z,
}
}
}
impl<'a> Vector {
#[inline(always)]
pub fn mulfed(&self, m: RFloat) -> Vector {
Vector {
x: self.x * m,
y: self.y * m,
z: self.z * m,
}
}
#[inline(always)]
pub fn mulf(&'a mut self, m: RFloat) -> &'a mut Vector {
self.x = self.x * m;
self.y = self.y * m;
self.z = self.z * m;
self
}
#[inline(always)]
pub fn dot(&self, r: &Vector) -> RFloat {
self.x * r.x + self.y * r.y + self.z * r.z
}
#[inline(always)]
pub fn len(&self) -> RFloat {
self.dot(self).sqrt()
}
#[inline(always)]
pub fn normalize(&'a mut self) -> &'a mut Vector {
let len = self.len();
self.mulf(len.recip())
}
#[inline(always)]
pub fn normalized(&self) -> Vector {
self.mulfed(self.len().recip())
}
}
#[cfg(test)]
mod tests {
extern crate test;
use std::default::Default;
use super::*;
#[test]
fn basics() {
let v32 = Vector {
x: 5.0,
y: 4.0,
z: 0.0,
};
assert_eq!(v32.x, 5.0);
assert_eq!(v32, v32);
assert!(!(v32 != v32));
{
let mut copy = v32;
copy.x = 10.0;
}
let v64 = Vector {
x: 1.0,
y: 2.0,
z: 3.0,
};
assert_eq!(v64.x, 1.0);
let v = v32 + v32;
assert_eq!(v.x, v32.x + v32.x);
assert_eq!(v.y, v32.y + v32.y);
assert_eq!(v.z, v32.z + v32.z);
let v = v32 - v32;
assert_eq!(v.x, 0.0);
let v = v32 * v32;
assert_eq!(v.x, v32.x * v32.x);
let mut v = v32.mulfed(3.0);
assert_eq!(v.x, v32.x * 3.0);
v.mulf(2.0);
assert_eq!(v.x, v32.x * 3.0 * 2.0);
}
#[test]
fn default() {
let v1: Vector = Default::default();
let v2 = <Vector as Default>::default();
assert_eq!(v1, v2);
}
#[test]
fn normalize() {
let v = Vector {
x: 2.0,
y: 0.0,
z: 0.0,
};
assert_eq!(v.len(), 2.0);
assert_eq!(v.normalized().len(), 1.0);
let mut v = v;
assert_eq!(v.normalize().len(), 1.0);
}
}