pub mod calculus { #[derive(Copy, Clone, Debug)] pub struct Vec3 { pub x: f32, pub y: f32, pub z: f32, // cached: Vec3Cache, } pub type Point3 = Vec3; impl Vec3 { pub fn new(x: f32, y: f32, z: f32) -> Self { Self { x, y, z } } pub fn add(&self, other: &Self) -> Self { Self { x: self.x + other.x, y: self.y + other.y, z: self.z + other.z } } pub fn sub(&self, other: &Self) -> Self { Self { x: self.x - other.x, y: self.y - other.y, z: self.z - other.z } } pub fn scalar_mul(&self, multiplier: f32) -> Self { Self { x: self.x * multiplier, y: self.y * multiplier, z: self.z * multiplier, } } pub fn mag_sqr(&self) -> f32 { self.x * self.x + self.y * self.y + self.z * self.z } pub fn mag(&self) -> f32 { self.mag_sqr().sqrt() } pub fn dot_prod(&self, other: &Self) -> f32 { self.x * other.x + self.y * other.y + self.z * other.z } pub fn cross_prod(&self, other: &Self) -> Self { Self { 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, } } pub fn unit(&self) -> Self { let mag = self.mag(); Self { x: self.x / mag, y: self.y / mag, z: self.z / mag, } } } pub struct Ray<'a> { pub origin: &'a Point3, pub direction: &'a Vec3, } impl<'a> Ray<'a> { pub fn at(&self, t: f32) -> Point3 { // Get parametric location self.origin.add(&self.direction.scalar_mul(t)) } } pub fn deg2rad(deg: f32) -> f32 { deg * std::f32::consts::PI / 180.0 } }