Created
October 15, 2018 00:44
-
-
Save saethlin/c82e0f62ee4c8400eca472dbd3b528e9 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
extern crate dimensioned as dim; // it doesn't compile anyway but you need to know this | |
use dim::Sqrt; | |
use dim::si::Unitless; | |
use dim::typenum::{Diff, Prod, Quot, Sum}; | |
use rand::Rng; | |
use std::ops::{Add, Div, Mul, Sub}; | |
#[derive(Debug, Clone, Copy)] | |
pub struct Vec3<T> { | |
pub x: T, | |
pub y: T, | |
pub z: T, | |
} | |
impl<T: Div + Mul<T, Output = TT> + Add<T, Output = T> + Copy, TT: Sqrt<Output = T> + Copy> Vec3<T> | |
where | |
Prod<T, T>: Add, | |
TT: Add<TT, Output = TT>, | |
{ | |
pub fn from_fn<F: FnMut() -> T>(mut f: F) -> Vec3<T> { | |
Vec3 { | |
x: f(), | |
y: f(), | |
z: f(), | |
} | |
} | |
pub fn normalized(&self) -> Vec3<Quot<T, T>> { | |
let length = ((self.x * self.x) + (self.y * self.y) + (self.z * self.z)).sqrt(); | |
Vec3 { | |
x: self.x / length, | |
y: self.y / length, | |
z: self.z / length, | |
} | |
} | |
pub fn random_direction<R: Rng>(rng: &mut R) -> Vec3<Unitless<f64>> { | |
loop { | |
let v = Vec3::from_fn(|| Unitless::new(rng.gen_range(-1.0f64, 1.0f64))); | |
if (v.x * v.x + v.y * v.y + v.z * v.z) <= Unitless::new(1.0) { | |
break v.normalized(); | |
} | |
} | |
} | |
pub fn dot<R: Copy>(&self, other: &Vec3<R>) -> Sum<Prod<T, R>, Prod<T, R>> | |
where | |
T: Mul<R>, | |
Prod<T, R>: Add<Output = Prod<T, R>>, | |
{ | |
self.x * other.x + self.y * other.y + self.z * other.z | |
} | |
pub fn cross<R: Copy>(&self, other: &Vec3<R>) -> Vec3<Diff<Prod<T, R>, Prod<T, R>>> | |
where | |
T: Mul<R>, | |
Prod<T, R>: Sub, | |
{ | |
Vec3 { | |
x: self.y * other.z - self.z * other.y, | |
y: self.z * other.x - self.x * other.z, | |
z: self.x * other.y - self.y * other.x, | |
} | |
} | |
} | |
impl<T: Add<R>, R> Add<Vec3<R>> for Vec3<T> { | |
type Output = Vec3<Sum<T, R>>; | |
fn add(self, rhs: Vec3<R>) -> Self::Output { | |
Vec3 { | |
x: self.x + rhs.x, | |
y: self.y + rhs.y, | |
z: self.z + rhs.z, | |
} | |
} | |
} | |
impl<T: Sub<R>, R> Sub<Vec3<R>> for Vec3<T> { | |
type Output = Vec3<Diff<T, R>>; | |
fn sub(self, rhs: Vec3<R>) -> Self::Output { | |
Vec3 { | |
x: self.x - rhs.x, | |
y: self.y - rhs.y, | |
z: self.z - rhs.z, | |
} | |
} | |
} | |
impl<T: Mul<R>, R: Copy> Mul<R> for Vec3<T> { | |
type Output = Vec3<Prod<T, R>>; | |
fn mul(self, rhs: R) -> Self::Output { | |
Vec3 { | |
x: self.x * rhs, | |
y: self.y * rhs, | |
z: self.z * rhs, | |
} | |
} | |
} | |
impl<T: Div<R>, R: Copy> Div<R> for Vec3<T> { | |
type Output = Vec3<Quot<T, R>>; | |
fn div(self, rhs: R) -> Self::Output { | |
Vec3 { | |
x: self.x / rhs, | |
y: self.y / rhs, | |
z: self.z / rhs, | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment