From e23a4aacab045045f49ac5d02305a8e618d899b3 Mon Sep 17 00:00:00 2001 From: Savanni D'Gerinel Date: Sun, 9 Jun 2024 13:19:47 -0400 Subject: [PATCH] Add primitive math operations --- ray-tracer/src/types.rs | 202 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 198 insertions(+), 4 deletions(-) diff --git a/ray-tracer/src/types.rs b/ray-tracer/src/types.rs index b253756..5174656 100644 --- a/ray-tracer/src/types.rs +++ b/ray-tracer/src/types.rs @@ -1,10 +1,10 @@ - const EPSILON: f64 = 0.00001; fn eq_f64(l: f64, r: f64) -> bool { - (l-r).abs() < EPSILON + (l - r).abs() < EPSILON } +#[derive(Debug)] struct Tuple { x: f64, y: f64, @@ -20,11 +20,55 @@ impl PartialEq for Tuple { } } +impl std::ops::Add for Tuple { + type Output = Tuple; + fn add(self, r: Tuple) -> Self::Output { + return Self::Output { + x: self.x + r.x, + y: self.y + r.y, + z: self.z + r.z, + w: self.w + r.w, + }; + } +} + +impl std::ops::Sub for Tuple { + type Output = Tuple; + fn sub(self, r: Tuple) -> Self::Output { + return Self::Output { + x: self.x - r.x, + y: self.y - r.y, + z: self.z - r.z, + w: self.w - r.w, + }; + } +} + +impl std::ops::Neg for Tuple { + type Output = Tuple; + fn neg(self) -> Self::Output { + return Self::Output { + x: -self.x, + y: -self.y, + z: -self.z, + w: -self.w, + }; + } +} + +#[derive(Debug, PartialEq)] struct Point(Tuple); impl Point { fn new(x: f64, y: f64, z: f64) -> Self { - Self(Tuple{ x, y, z, w: 1.0 }) + Self(Tuple { x, y, z, w: 1.0 }) + } +} + +impl From for Point { + fn from(tuple: Tuple) -> Self { + assert_eq!(tuple.w, 1.0); + Self(tuple) } } @@ -34,11 +78,42 @@ impl Default for Point { } } +impl std::ops::Add for Point { + type Output = Point; + fn add(self, r: Vector) -> Self::Output { + Point::from(self.0 + r.0) + } +} + +impl std::ops::Sub for Point { + type Output = Vector; + fn sub(self, r: Point) -> Self::Output { + Vector::from(self.0 - r.0) + } +} + +impl std::ops::Sub for Point { + type Output = Point; + fn sub(self, r: Vector) -> Self::Output { + Point::from(self.0 - r.0) + } +} + +impl std::ops::Neg for Point { + type Output = Point; + fn neg(self) -> Self::Output { + let mut t = -self.0; + t.w = 1.; + Point::from(t) + } +} + +#[derive(Debug, PartialEq)] struct Vector(Tuple); impl Vector { fn new(x: f64, y: f64, z: f64) -> Self { - Self(Tuple{ x, y, z, w: 0.0 }) + Self(Tuple { x, y, z, w: 0.0 }) } } @@ -48,6 +123,29 @@ impl Default for Vector { } } +impl From for Vector { + fn from(tuple: Tuple) -> Self { + assert_eq!(tuple.w, 0.0); + Self(tuple) + } +} + +impl std::ops::Sub for Vector { + type Output = Vector; + fn sub(self, r: Self) -> Self { + Vector::from(self.0 - r.0) + } +} + +impl std::ops::Neg for Vector { + type Output = Vector; + fn neg(self) -> Self::Output { + let mut t = -self.0; + t.w = 0.; + Vector::from(t) + } +} + #[cfg(test)] mod tests { use super::*; @@ -59,4 +157,100 @@ mod tests { assert!(eq_f64(0.9999994, 0.9999995)); assert!(!eq_f64(0.9995, 0.9994)); } + + #[test] + fn add_two_tuples() { + let a = Tuple { + x: 3., + y: -2., + z: 5., + w: 1., + }; + let b = Tuple { + x: -2., + y: 3., + z: 1., + w: 0., + }; + assert_eq!( + a + b, + Tuple { + x: 1., + y: 1., + z: 6., + w: 1. + } + ); + } + + #[test] + fn subtracts_two_tuples() { + let a = Tuple { + x: 3., + y: 2., + z: 1., + w: 1., + }; + let b = Tuple { + x: 5., + y: 6., + z: 7., + w: 1., + }; + assert_eq!( + a - b, + Tuple { + x: -2., + y: -4., + z: -6., + w: 0. + } + ); + } + + #[test] + fn adds_point_and_vector() { + let a = Point::new(3., -2., 5.); + let b = Vector::new(-2., 3., 1.); + assert_eq!(a + b, Point::new(1., 1., 6.,)); + } + + #[test] + fn subtracts_two_points() { + let a = Point::new(3., 2., 1.); + let b = Point::new(5., 6., 7.); + assert_eq!(a - b, Vector::new(-2., -4., -6.,)); + } + + #[test] + fn subtracts_vector_from_point() { + let a = Point::new(3., 2., 1.); + let b = Vector::new(5., 6., 7.); + assert_eq!(a - b, Point::new(-2., -4., -6.)); + } + + #[test] + fn subtracts_two_vectors() { + let a = Vector::new(3., 2., 1.); + let b = Vector::new(5., 6., 7.); + assert_eq!(a - b, Vector::new(-2., -4., -6.)); + } + + #[test] + fn it_negates_primitives() { + assert_eq!( + -Tuple { + x: 1., + y: 2., + z: 3., + w: 4. + }, + Tuple { + x: -1., + y: -2., + z: -3., + w: -4. + }, + ); + } }