spheres: implement normal_at.
This commit is contained in:
parent
e430e3769e
commit
6e7bd1c136
@ -3,6 +3,7 @@ use crate::{
|
|||||||
matrices::Matrix4x4,
|
matrices::Matrix4x4,
|
||||||
rays::Ray,
|
rays::Ray,
|
||||||
tuples::{dot, Tuple},
|
tuples::{dot, Tuple},
|
||||||
|
EPSILON,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq)]
|
||||||
@ -34,6 +35,65 @@ impl Default for Sphere {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Sphere {
|
||||||
|
/// Find the normal at the point on the sphere.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
/// ```
|
||||||
|
/// use rtchallenge::{matrices::Matrix4x4, spheres::Sphere, tuples::Tuple};
|
||||||
|
///
|
||||||
|
/// // Normal on X-axis
|
||||||
|
/// let s = Sphere::default();
|
||||||
|
/// let n = s.normal_at(Tuple::point(1., 0., 0.));
|
||||||
|
/// assert_eq!(n, Tuple::vector(1., 0., 0.));
|
||||||
|
///
|
||||||
|
/// // Normal on Y-axis
|
||||||
|
/// let s = Sphere::default();
|
||||||
|
/// let n = s.normal_at(Tuple::point(0., 1., 0.));
|
||||||
|
/// assert_eq!(n, Tuple::vector(0., 1., 0.));
|
||||||
|
///
|
||||||
|
/// // Normal on Z-axis
|
||||||
|
/// let s = Sphere::default();
|
||||||
|
/// let n = s.normal_at(Tuple::point(0., 0., 1.));
|
||||||
|
/// assert_eq!(n, Tuple::vector(0., 0., 1.));
|
||||||
|
///
|
||||||
|
/// // Normal on a sphere at a nonaxial point.
|
||||||
|
/// let s = Sphere::default();
|
||||||
|
/// let n = s.normal_at(Tuple::point(
|
||||||
|
/// 3_f32.sqrt() / 3.,
|
||||||
|
/// 3_f32.sqrt() / 3.,
|
||||||
|
/// 3_f32.sqrt() / 3.,
|
||||||
|
/// ));
|
||||||
|
/// assert_eq!(
|
||||||
|
/// n,
|
||||||
|
/// Tuple::vector(3_f32.sqrt() / 3., 3_f32.sqrt() / 3., 3_f32.sqrt() / 3.,)
|
||||||
|
/// );
|
||||||
|
/// // Normals returned are normalized.
|
||||||
|
/// let s = Sphere::default();
|
||||||
|
/// let n = s.normal_at(Tuple::point(
|
||||||
|
/// 3_f32.sqrt() / 3.,
|
||||||
|
/// 3_f32.sqrt() / 3.,
|
||||||
|
/// 3_f32.sqrt() / 3.,
|
||||||
|
/// ));
|
||||||
|
/// assert_eq!(n, n.normalize());
|
||||||
|
/// ```
|
||||||
|
/// ```should_panic
|
||||||
|
/// use rtchallenge::{spheres::Sphere, tuples::Tuple};
|
||||||
|
///
|
||||||
|
/// // In debug builds points not on the sphere should fail.
|
||||||
|
/// let s = Sphere::default();
|
||||||
|
/// let n = s.normal_at(Tuple::point(0., 0., 0.5));
|
||||||
|
/// ```
|
||||||
|
pub fn normal_at(&self, point: Tuple) -> Tuple {
|
||||||
|
debug_assert!(
|
||||||
|
((point - Tuple::point(0., 0., 0.)).magnitude() - 1.).abs() < EPSILON,
|
||||||
|
"{} != 1.",
|
||||||
|
(point - Tuple::point(0., 0., 0.)).magnitude()
|
||||||
|
);
|
||||||
|
(point - Tuple::point(0., 0., 0.)).normalize()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Intersect a ray with a sphere.
|
/// Intersect a ray with a sphere.
|
||||||
///
|
///
|
||||||
/// # Examples
|
/// # Examples
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user