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> {
|
pub fn intersect<'a>(&self, s: &'a Sphere) -> Intersections<'a> {
|
||||||
let sphere_to_ray = self.origin - Point::new(0., 0., 0.);
|
let r2 = self.transform(s.transformation().inverse());
|
||||||
let a = self.direction.dot(&self.direction);
|
let sphere_to_ray = r2.origin - Point::new(0., 0., 0.);
|
||||||
let b = 2. * self.direction.dot(&sphere_to_ray);
|
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 c = sphere_to_ray.dot(&sphere_to_ray) - 1.;
|
||||||
|
|
||||||
let discriminant = b * b - 4. * a * c;
|
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.origin, Point::new(2., 6., 12.));
|
||||||
assert_eq!(r2.direction, Vector::new(0., 3., 0.,));
|
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)]
|
#[derive(Debug, PartialEq)]
|
||||||
pub struct Sphere {
|
pub struct Sphere {
|
||||||
origin: Point,
|
origin: Point,
|
||||||
|
transformation: Matrix,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Sphere {
|
impl Sphere {
|
||||||
pub fn new() -> Self {
|
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