Scale a sphere and ray with respect to one another
This commit is contained in:
parent
40bfe6d74f
commit
b07925a2c3
|
@ -48,9 +48,10 @@ impl Ray {
|
|||
}
|
||||
|
||||
pub fn intersect<'a>(&self, s: &'a Sphere) -> Intersections<'a> {
|
||||
let sphere_to_ray = self.origin - Point::new(0., 0., 0.);
|
||||
let a = self.direction.dot(&self.direction);
|
||||
let b = 2. * self.direction.dot(&sphere_to_ray);
|
||||
let r2 = self.transform(s.transformation().inverse());
|
||||
let sphere_to_ray = r2.origin - Point::new(0., 0., 0.);
|
||||
let a = r2.direction.dot(&r2.direction);
|
||||
let b = 2. * r2.direction.dot(&sphere_to_ray);
|
||||
let c = sphere_to_ray.dot(&sphere_to_ray) - 1.;
|
||||
|
||||
let discriminant = b * b - 4. * a * c;
|
||||
|
@ -199,4 +200,24 @@ mod tests {
|
|||
assert_eq!(r2.origin, Point::new(2., 6., 12.));
|
||||
assert_eq!(r2.direction, Vector::new(0., 3., 0.,));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn intersect_scaled_sphere_with_ray() {
|
||||
let r = Ray::new(Point::new(0., 0., -5.), Vector::new(0., 0., 1.));
|
||||
let mut s = Sphere::new();
|
||||
s.set_transformation(scaling(2., 2., 2.));
|
||||
let xs = r.intersect(&s);
|
||||
assert_eq!(xs.len(), 2);
|
||||
assert_eq!(xs[0].t, 3.);
|
||||
assert_eq!(xs[1].t, 7.);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn intersect_translated_sphere_with_ray() {
|
||||
let r = Ray::new(Point::new(0., 0., -5.), Vector::new(0., 0., 1.));
|
||||
let mut s = Sphere::new();
|
||||
s.set_transformation(translation(5., 0., 0.));
|
||||
let xs = r.intersect(&s);
|
||||
assert_eq!(xs.len(), 0);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,13 +1,44 @@
|
|||
use crate::types::Point;
|
||||
use crate::types::{Matrix, Point};
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub struct Sphere {
|
||||
origin: Point,
|
||||
transformation: Matrix,
|
||||
}
|
||||
|
||||
impl Sphere {
|
||||
pub fn new() -> Self {
|
||||
Self{ origin: Point::new(0., 0., 0.) }
|
||||
Self {
|
||||
origin: Point::new(0., 0., 0.),
|
||||
transformation: Matrix::identity(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn transformation(&self) -> &Matrix {
|
||||
&self.transformation
|
||||
}
|
||||
|
||||
pub fn set_transformation(&mut self, m: Matrix) {
|
||||
self.transformation = m
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use crate::transforms::translation;
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn sphere_has_default_transformation() {
|
||||
let s = Sphere::new();
|
||||
assert_eq!(s.transformation(), &Matrix::identity());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn change_a_spheres_transformation() {
|
||||
let mut s = Sphere::new();
|
||||
let t = translation(2., 3., 4.);
|
||||
s.set_transformation(t.clone());
|
||||
assert_eq!(*s.transformation(), t);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue