spheres: fix normal_at for transformed spheres.
This commit is contained in:
parent
ac4f5eb9a6
commit
e529710d5d
@ -76,21 +76,27 @@ impl Sphere {
|
|||||||
/// 3_f32.sqrt() / 3.,
|
/// 3_f32.sqrt() / 3.,
|
||||||
/// ));
|
/// ));
|
||||||
/// assert_eq!(n, n.normalize());
|
/// assert_eq!(n, n.normalize());
|
||||||
/// ```
|
|
||||||
/// ```should_panic
|
|
||||||
/// use rtchallenge::{spheres::Sphere, tuples::Tuple};
|
|
||||||
///
|
///
|
||||||
/// // In debug builds points not on the sphere should fail.
|
/// // Compute the normal on a translated sphere.
|
||||||
/// let s = Sphere::default();
|
/// let mut s = Sphere::default();
|
||||||
/// let n = s.normal_at(Tuple::point(0., 0., 0.5));
|
/// s.transform = Matrix4x4::translation(0., 1., 0.);
|
||||||
|
/// let n = s.normal_at(Tuple::point(0., 1.70711, -0.70711));
|
||||||
|
/// assert_eq!(n, Tuple::vector(0., 0.70711, -0.70711));
|
||||||
|
|
||||||
|
/// // Compute the normal on a transformed sphere.
|
||||||
|
/// use std::f32::consts::PI;
|
||||||
|
///
|
||||||
|
/// let mut s = Sphere::default();
|
||||||
|
/// s.transform = Matrix4x4::scaling(1.,0.5,1.) * Matrix4x4::rotation_z(PI/5.);
|
||||||
|
/// let n = s.normal_at(Tuple::point(0., 2_f32.sqrt()/2., -2_f32.sqrt()/2.));
|
||||||
|
/// assert_eq!(n, Tuple::vector(0., 0.97014, -0.24254));
|
||||||
/// ```
|
/// ```
|
||||||
pub fn normal_at(&self, point: Tuple) -> Tuple {
|
pub fn normal_at(&self, world_point: Tuple) -> Tuple {
|
||||||
debug_assert!(
|
let object_point = self.transform.inverse() * world_point;
|
||||||
((point - Tuple::point(0., 0., 0.)).magnitude() - 1.).abs() < EPSILON,
|
let object_normal = object_point - Tuple::point(0., 0., 0.);
|
||||||
"{} != 1.",
|
let mut world_normal = self.transform.inverse().transpose() * object_normal;
|
||||||
(point - Tuple::point(0., 0., 0.)).magnitude()
|
world_normal.w = 0.;
|
||||||
);
|
world_normal.normalize()
|
||||||
(point - Tuple::point(0., 0., 0.)).normalize()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user