diff options
author | Yann Herklotz <git@yannherklotz.com> | 2020-10-10 00:12:12 +0100 |
---|---|---|
committer | Yann Herklotz <git@yannherklotz.com> | 2020-10-10 00:12:12 +0100 |
commit | 495d1c9c113098f24767b595c7e830f0fa8bc991 (patch) | |
tree | 95eac21eacecadc58f23a59216e764ddd6928979 /src/sphere.rs | |
parent | dd5ac7c5fe336e9cac794cfa72d139613a99b466 (diff) | |
download | leela-495d1c9c113098f24767b595c7e830f0fa8bc991.tar.gz leela-495d1c9c113098f24767b595c7e830f0fa8bc991.zip |
Format all the files and add moving sphere
Diffstat (limited to 'src/sphere.rs')
-rw-r--r-- | src/sphere.rs | 104 |
1 files changed, 94 insertions, 10 deletions
diff --git a/src/sphere.rs b/src/sphere.rs index f1c88b6..59ca498 100644 --- a/src/sphere.rs +++ b/src/sphere.rs @@ -1,19 +1,27 @@ -use cgmath::prelude::*; -use cgmath::{Vector3, dot}; -use core::borrow::Borrow; +use crate::hittable::{Hit, Hittable}; use crate::material::Material; -use crate::hittable::{Hittable, Hit}; use crate::ray::Ray; +use cgmath::prelude::*; +use cgmath::{dot, Vector3}; +use core::borrow::Borrow; pub struct Sphere { center: Vector3<f64>, radius: f64, - material: Box<dyn Material + std::marker::Sync> + material: Box<dyn Material + std::marker::Sync>, } impl Sphere { - pub fn new(center: Vector3<f64>, radius: f64, material: Box<dyn Material + std::marker::Sync>) -> Sphere { - Sphere { center, radius, material } + pub fn new( + center: Vector3<f64>, + radius: f64, + material: Box<dyn Material + std::marker::Sync>, + ) -> Sphere { + Sphere { + center, + radius, + material, + } } } @@ -23,16 +31,92 @@ impl Hittable for Sphere { let a = ray.dir.magnitude2(); let b = dot(oc, ray.dir); let c = oc.magnitude2() - self.radius * self.radius; - let discriminant = b*b - a*c; + let discriminant = b * b - a * c; + + if discriminant > 0.0 { + let soln = (-b - discriminant.sqrt()) / a; + if soln < t_max && soln > t_min { + return Some(Hit::new( + ray, + soln, + (ray.at(soln) - self.center) / self.radius, + self.material.borrow(), + )); + } + let soln = (-b + discriminant.sqrt()) / a; + if soln < t_max && soln > t_min { + return Some(Hit::new( + ray, + soln, + (ray.at(soln) - self.center) / self.radius, + self.material.borrow(), + )); + } + } + None + } +} + +struct MovingSphere { + center0: Vector3<f64>, + center1: Vector3<f64>, + time0: f64, + time1: f64, + radius: f64, + material: Box<dyn Material + std::marker::Sync>, +} + +impl MovingSphere { + pub fn new( + center0: Vector3<f64>, + center1: Vector3<f64>, + time0: f64, + time1: f64, + radius: f64, + material: Box<dyn Material + std::marker::Sync>, + ) -> MovingSphere { + MovingSphere { + center0, + center1, + time0, + time1, + radius, + material, + } + } + + pub fn center(&self, time: f64) -> Vector3<f64> { + self.center0 + + ((time + self.time0) / (self.time0 + self.time1)) * (self.center1 - self.center0) + } +} + +impl Hittable for MovingSphere { + fn is_hit(&self, ray: &Ray, t_min: f64, t_max: f64) -> Option<Hit> { + let oc = ray.orig - self.center(ray.time); + let a = ray.dir.magnitude2(); + let b = dot(oc, ray.dir); + let c = oc.magnitude2() - self.radius * self.radius; + let discriminant = b * b - a * c; if discriminant > 0.0 { let soln = (-b - discriminant.sqrt()) / a; if soln < t_max && soln > t_min { - return Some(Hit::new(ray, soln, (ray.at(soln) - self.center) / self.radius, self.material.borrow())) + return Some(Hit::new( + ray, + soln, + (ray.at(soln) - self.center(ray.time)) / self.radius, + self.material.borrow(), + )); } let soln = (-b + discriminant.sqrt()) / a; if soln < t_max && soln > t_min { - return Some(Hit::new(ray, soln, (ray.at(soln) - self.center) / self.radius, self.material.borrow())) + return Some(Hit::new( + ray, + soln, + (ray.at(soln) - self.center(ray.time)) / self.radius, + self.material.borrow(), + )); } } None |