intersections: now store object in Intersection.

This commit is contained in:
Bill Thiede 2021-07-16 21:14:23 -07:00
parent 0ce1e8f7af
commit c9b42d94b3
2 changed files with 27 additions and 7 deletions

View File

@ -2,6 +2,7 @@ use std::ops::Index;
use crate::spheres::Sphere; use crate::spheres::Sphere;
#[derive(Debug, PartialEq)]
pub struct Intersection<'i> { pub struct Intersection<'i> {
pub t: f32, pub t: f32,
pub object: &'i Sphere, pub object: &'i Sphere,
@ -31,7 +32,9 @@ impl<'i> Intersection<'i> {
/// ``` /// ```
/// use rtchallenge::{ /// use rtchallenge::{
/// intersections::{Intersection, Intersections}, /// intersections::{Intersection, Intersections},
/// spheres::Sphere, /// rays::Ray,
/// spheres::{intersect, Sphere},
/// tuples::Tuple,
/// }; /// };
/// ///
/// let s = Sphere::default(); /// let s = Sphere::default();
@ -41,6 +44,12 @@ impl<'i> Intersection<'i> {
/// assert_eq!(xs.len(), 2); /// assert_eq!(xs.len(), 2);
/// assert_eq!(xs[0].t, 1.); /// assert_eq!(xs[0].t, 1.);
/// assert_eq!(xs[1].t, 2.); /// assert_eq!(xs[1].t, 2.);
///
/// let r = Ray::new(Tuple::point(0., 0., -5.), Tuple::vector(0., 0., 1.));
/// let xs = intersect(&s, &r);
/// assert_eq!(xs.len(), 2);
/// assert_eq!(xs[0].object, &s);
/// assert_eq!(xs[1].object, &s);
/// ``` /// ```
pub struct Intersections<'i>(Vec<Intersection<'i>>); pub struct Intersections<'i>(Vec<Intersection<'i>>);

View File

@ -1,4 +1,5 @@
use crate::{ use crate::{
intersections::Intersection,
rays::Ray, rays::Ray,
tuples::{dot, Tuple}, tuples::{dot, Tuple},
}; };
@ -12,6 +13,7 @@ pub struct Sphere {}
/// # Examples /// # Examples
/// ``` /// ```
/// use rtchallenge::{ /// use rtchallenge::{
/// intersections::Intersection,
/// rays::Ray, /// rays::Ray,
/// spheres::{intersect, Sphere}, /// spheres::{intersect, Sphere},
/// tuples::Tuple, /// tuples::Tuple,
@ -21,7 +23,10 @@ pub struct Sphere {}
/// let r = Ray::new(Tuple::point(0., 0., -5.), Tuple::vector(0., 0., 1.)); /// let r = Ray::new(Tuple::point(0., 0., -5.), Tuple::vector(0., 0., 1.));
/// let s = Sphere::default(); /// let s = Sphere::default();
/// let xs = intersect(&s, &r); /// let xs = intersect(&s, &r);
/// assert_eq!(xs, vec![4., 6.]); /// assert_eq!(
/// xs,
/// vec![Intersection::new(4., &s), Intersection::new(6., &s)]
/// );
/// ///
/// // A ray intersects a sphere at a tangent. /// // A ray intersects a sphere at a tangent.
/// let r = Ray::new(Tuple::point(0., 2., -5.), Tuple::vector(0., 0., 1.)); /// let r = Ray::new(Tuple::point(0., 2., -5.), Tuple::vector(0., 0., 1.));
@ -33,15 +38,21 @@ pub struct Sphere {}
/// let r = Ray::new(Tuple::point(0., 0., 0.), Tuple::vector(0., 0., 1.)); /// let r = Ray::new(Tuple::point(0., 0., 0.), Tuple::vector(0., 0., 1.));
/// let s = Sphere::default(); /// let s = Sphere::default();
/// let xs = intersect(&s, &r); /// let xs = intersect(&s, &r);
/// assert_eq!(xs, vec![-1., 1.]); /// assert_eq!(
/// xs,
/// vec![Intersection::new(-1., &s), Intersection::new(1., &s)]
/// );
/// ///
/// // A sphere is behind a ray. /// // A sphere is behind a ray.
/// let r = Ray::new(Tuple::point(0., 0., 5.), Tuple::vector(0., 0., 1.)); /// let r = Ray::new(Tuple::point(0., 0., 5.), Tuple::vector(0., 0., 1.));
/// let s = Sphere::default(); /// let s = Sphere::default();
/// let xs = intersect(&s, &r); /// let xs = intersect(&s, &r);
/// assert_eq!(xs, vec![-6., -4.]); /// assert_eq!(
/// xs,
/// vec![Intersection::new(-6., &s), Intersection::new(-4., &s)]
/// );
/// ``` /// ```
pub fn intersect(_sphere: &Sphere, ray: &Ray) -> Vec<f32> { pub fn intersect<'s>(sphere: &'s Sphere, ray: &Ray) -> Vec<Intersection<'s>> {
let sphere_to_ray = ray.origin - Tuple::point(0., 0., 0.); let sphere_to_ray = ray.origin - Tuple::point(0., 0., 0.);
let a = dot(ray.direction, ray.direction); let a = dot(ray.direction, ray.direction);
let b = 2. * dot(ray.direction, sphere_to_ray); let b = 2. * dot(ray.direction, sphere_to_ray);
@ -51,8 +62,8 @@ pub fn intersect(_sphere: &Sphere, ray: &Ray) -> Vec<f32> {
vec![] vec![]
} else { } else {
vec![ vec![
(-b - discriminant.sqrt()) / (2. * a), Intersection::new((-b - discriminant.sqrt()) / (2. * a), &sphere),
(-b + discriminant.sqrt()) / (2. * a), Intersection::new((-b + discriminant.sqrt()) / (2. * a), &sphere),
] ]
} }
} }