world: implement World::is_shadowed.

This commit is contained in:
Bill Thiede 2021-07-18 12:54:18 -07:00
parent 1065702a5d
commit 09047eb713

View File

@ -177,4 +177,48 @@ impl World {
None => BLACK,
}
}
/// Determine if point in world is in a shadow.
///
/// # Examples
/// ```
/// use rtchallenge::{
/// tuples::{ Tuple},
/// world::World,
/// };
///
/// let w = World::test_world();
///
/// // There is no shadow when nothing is collinear with point and light.
/// let p = Tuple::point(0.,10.,0.);
/// assert_eq!(w.is_shadowed(p), false);
///
/// // There shadow when an object is between the point and the light.
/// let p = Tuple::point(10.,-10.,10.);
/// assert_eq!(w.is_shadowed(p), true);
///
/// // There is no shadow when an object is behind the light.
/// let p = Tuple::point(-20.,20.,-20.);
/// assert_eq!(w.is_shadowed(p), false);
///
/// // There is no shadow when an object is behind the point.
/// let p = Tuple::point(-2.,2.,-2.);
/// assert_eq!(w.is_shadowed(p), false);
pub fn is_shadowed(&self, point: Tuple) -> bool {
// TODO(wathiede): how to make this multi light aware?
let light = self
.light
.as_ref()
.expect("cannot compute is_shadowed in world with no light");
let v = light.position - point;
let distance = v.magnitude();
let direction = v.normalize();
let r = Ray::new(point, direction);
let intersections = self.intersect(&r);
if let Some(h) = intersections.hit() {
return h.t < distance;
}
false
}
}