diff --git a/rtchallenge/src/rays.rs b/rtchallenge/src/rays.rs index 69d2372..393993e 100644 --- a/rtchallenge/src/rays.rs +++ b/rtchallenge/src/rays.rs @@ -1,5 +1,6 @@ -use crate::tuples::Tuple; +use crate::{matrices::Matrix4x4, tuples::Tuple}; +/// Rays have an origin and a direction. This datatype is the 'ray' in 'raytracer'. pub struct Ray { pub origin: Tuple, pub direction: Tuple, @@ -40,4 +41,31 @@ impl Ray { pub fn position(&self, t: f32) -> Tuple { self.origin + self.direction * t } + + /// Apply Matrix4x4 transforms to Ray. + /// + /// # Examples + /// ``` + /// use rtchallenge::{matrices::Matrix4x4, rays::Ray, tuples::Tuple}; + /// + /// // Translating a ray + /// let r = Ray::new(Tuple::point(1., 2., 3.), Tuple::vector(0., 1., 0.)); + /// let m = Matrix4x4::translate(3., 4., 5.); + /// let r2 = r.transform(m); + /// assert_eq!(r2.origin, Tuple::point(4., 6., 8.)); + /// assert_eq!(r2.direction, Tuple::vector(0., 1., 0.)); + /// + /// // Scaling a ray + /// let r = Ray::new(Tuple::point(1., 2., 3.), Tuple::vector(0., 1., 0.)); + /// let m = Matrix4x4::scaling(2., 3., 4.); + /// let r2 = r.transform(m); + /// assert_eq!(r2.origin, Tuple::point(2., 6., 12.)); + /// assert_eq!(r2.direction, Tuple::vector(0., 3., 0.)); + /// ``` + pub fn transform(&self, m: Matrix4x4) -> Ray { + Ray { + origin: m * self.origin, + direction: m * self.direction, + } + } }