diff --git a/rtchallenge/src/spheres.rs b/rtchallenge/src/spheres.rs index c54207c..67311c2 100644 --- a/rtchallenge/src/spheres.rs +++ b/rtchallenge/src/spheres.rs @@ -8,6 +8,7 @@ use crate::{ #[derive(Debug, PartialEq)] /// Sphere represents the unit-sphere (radius of unit 1.) at the origin 0., 0., 0. pub struct Sphere { + // TODO(wathiede): cache inverse to speed up intersect. pub transform: Matrix4x4, } @@ -39,6 +40,7 @@ impl Default for Sphere { /// ``` /// use rtchallenge::{ /// intersections::Intersection, +/// matrices::Matrix4x4, /// rays::Ray, /// spheres::{intersect, Sphere}, /// tuples::Tuple, @@ -76,8 +78,25 @@ impl Default for Sphere { /// xs, /// vec![Intersection::new(-6., &s), Intersection::new(-4., &s)] /// ); +/// +/// // Intersect a scaled sphere with a ray. +/// let r = Ray::new(Tuple::point(0., 0., -5.), Tuple::vector(0., 0., 1.)); +/// let mut s = Sphere::default(); +/// s.transform = Matrix4x4::scaling(2., 2., 2.); +/// let xs = intersect(&s, &r); +/// assert_eq!(xs.len(), 2, "xs {:?}", xs); +/// assert_eq!(xs[0].t, 3., "xs {:?}", xs); +/// assert_eq!(xs[1].t, 7., "xs {:?}", xs); +/// +/// // Intersect a translated sphere with a ray. +/// let r = Ray::new(Tuple::point(0., 0., -5.), Tuple::vector(0., 0., 1.)); +/// let mut s = Sphere::default(); +/// s.transform = Matrix4x4::translation(5., 0., 0.); +/// let xs = intersect(&s, &r); +/// assert_eq!(xs.len(), 0); /// ``` pub fn intersect<'s>(sphere: &'s Sphere, ray: &Ray) -> Vec> { + let ray = ray.transform(sphere.transform.inverse()); let sphere_to_ray = ray.origin - Tuple::point(0., 0., 0.); let a = dot(ray.direction, ray.direction); let b = 2. * dot(ray.direction, sphere_to_ray);