diff --git a/ray-tracer/src/types/mod.rs b/ray-tracer/src/types/mod.rs index e2a03b0..34bc3c6 100644 --- a/ray-tracer/src/types/mod.rs +++ b/ray-tracer/src/types/mod.rs @@ -156,4 +156,18 @@ mod tests { *c.pixel_mut(2, 3) = red; assert_eq!(*c.pixel(2, 3), red); } + + #[test] + fn reflect_vector_approaching_at_45() { + let v = Vector::new(1., -1., 0.); + let n = Vector::new(0., 1., 0.); + assert_eq!(v.reflect(&n), Vector::new(1., 1., 0.)); + } + + #[test] + fn reflect_off_slanted_surface() { + let v = Vector::new(0., -1., 0.); + let n = Vector::new(2_f64.sqrt() / 2., 2_f64.sqrt() / 2., 0.); + assert_eq!(v.reflect(&n), Vector::new(1., 0., 0.)); + } } diff --git a/ray-tracer/src/types/vector.rs b/ray-tracer/src/types/vector.rs index eb0f8bb..3c8f88d 100644 --- a/ray-tracer/src/types/vector.rs +++ b/ray-tracer/src/types/vector.rs @@ -42,6 +42,10 @@ impl Vector { let z = self.x() * r.y() - self.y() * r.x(); Self::new(x, y, z) } + + pub fn reflect(&self, n: &Vector) -> Self { + self - (n * 2. * self.dot(n)) + } } impl Default for Vector { @@ -66,15 +70,36 @@ impl std::ops::Deref for Vector { impl std::ops::Add for Vector { type Output = Vector; - fn add(self, r: Self) -> Self { + fn add(self, r: Self) -> Self::Output { Vector::from(self.0 + r.0) } } +impl std::ops::Sub<&Vector> for &Vector { + type Output = Vector; + fn sub(self, r: &Vector) -> Self::Output { + Vector::from(self.0 - r.0) + } +} + +impl std::ops::Sub for &Vector { + type Output = Vector; + fn sub(self, r: Vector) -> Self::Output { + self - &r + } +} + +impl std::ops::Sub<&Vector> for Vector { + type Output = Vector; + fn sub(self, r: &Vector) -> Self::Output { + &self - r + } +} + impl std::ops::Sub for Vector { type Output = Vector; - fn sub(self, r: Self) -> Self { - Vector::from(self.0 - r.0) + fn sub(self, r: Vector) -> Self::Output { + &self - &r } } @@ -87,6 +112,13 @@ impl std::ops::Neg for Vector { } } +impl std::ops::Mul for &Vector { + type Output = Vector; + fn mul(self, r: f64) -> Self::Output { + Vector::from(self.0 * r) + } +} + impl std::ops::Mul for Vector { type Output = Vector; fn mul(self, r: f64) -> Self {