spheres: implement basic unit sphere and intersect.
This commit is contained in:
parent
f44d671573
commit
da98744288
59
rtchallenge/src/spheres.rs
Normal file
59
rtchallenge/src/spheres.rs
Normal file
@ -0,0 +1,59 @@
|
||||
use crate::{
|
||||
rays::Ray,
|
||||
tuples::{dot, Tuple},
|
||||
};
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct Sphere {}
|
||||
pub struct Intersection {}
|
||||
|
||||
/// Intersect a ray with a sphere.
|
||||
///
|
||||
/// # Examples
|
||||
/// ```
|
||||
/// use rtchallenge::{
|
||||
/// rays::Ray,
|
||||
/// spheres::{intersect, Sphere},
|
||||
/// tuples::Tuple,
|
||||
/// };
|
||||
///
|
||||
/// // A ray intersects a sphere in two points.
|
||||
/// let r = Ray::new(Tuple::point(0., 0., -5.), Tuple::vector(0., 0., 1.));
|
||||
/// let s = Sphere::default();
|
||||
/// let xs = intersect(&s, &r);
|
||||
/// assert_eq!(xs, vec![4., 6.]);
|
||||
///
|
||||
/// // A ray intersects a sphere at a tangent.
|
||||
/// let r = Ray::new(Tuple::point(0., 2., -5.), Tuple::vector(0., 0., 1.));
|
||||
/// let s = Sphere::default();
|
||||
/// let xs = intersect(&s, &r);
|
||||
/// assert_eq!(xs, vec![]);
|
||||
///
|
||||
/// // A ray originates inside a sphere.
|
||||
/// let r = Ray::new(Tuple::point(0., 0., 0.), Tuple::vector(0., 0., 1.));
|
||||
/// let s = Sphere::default();
|
||||
/// let xs = intersect(&s, &r);
|
||||
/// assert_eq!(xs, vec![-1., 1.]);
|
||||
///
|
||||
/// // A sphere is behind a ray.
|
||||
/// let r = Ray::new(Tuple::point(0., 0., 5.), Tuple::vector(0., 0., 1.));
|
||||
/// let s = Sphere::default();
|
||||
/// let xs = intersect(&s, &r);
|
||||
/// assert_eq!(xs, vec![-6., -4.]);
|
||||
/// ```
|
||||
|
||||
pub fn intersect(_sphere: &Sphere, ray: &Ray) -> Vec<f32> {
|
||||
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);
|
||||
let c = dot(sphere_to_ray, sphere_to_ray) - 1.;
|
||||
let discriminant = b * b - 4. * a * c;
|
||||
if discriminant < 0. {
|
||||
vec![]
|
||||
} else {
|
||||
vec![
|
||||
(-b - discriminant.sqrt()) / (2. * a),
|
||||
(-b + discriminant.sqrt()) / (2. * a),
|
||||
]
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user