diff options
author | Yann Herklotz <git@yannherklotz.com> | 2020-04-26 21:15:53 +0100 |
---|---|---|
committer | Yann Herklotz <git@yannherklotz.com> | 2020-04-26 21:15:53 +0100 |
commit | 9f4cdae92c8df0a7990fdb77d9ff161b2eebf467 (patch) | |
tree | eb1e8c4de3b6040859c88fb8c2ea69580a73ec10 /src/sphere.rs | |
download | leela-9f4cdae92c8df0a7990fdb77d9ff161b2eebf467.tar.gz leela-9f4cdae92c8df0a7990fdb77d9ff161b2eebf467.zip |
Add initial files
Diffstat (limited to 'src/sphere.rs')
-rw-r--r-- | src/sphere.rs | 40 |
1 files changed, 40 insertions, 0 deletions
diff --git a/src/sphere.rs b/src/sphere.rs new file mode 100644 index 0000000..9ea9081 --- /dev/null +++ b/src/sphere.rs @@ -0,0 +1,40 @@ +use cgmath::prelude::*; +use cgmath::{Vector3, dot}; +use core::borrow::Borrow; +use crate::material::Material; +use crate::hittable::{Hittable, Hit}; +use crate::ray::Ray; + +pub struct Sphere { + center: Vector3<f64>, + radius: f64, + material: Box<dyn Material> +} + +impl Sphere { + pub fn new(center: Vector3<f64>, radius: f64, material: Box<dyn Material>) -> Sphere { + Sphere { center, radius, material } + } +} + +impl Hittable for Sphere { + fn is_hit(&self, ray: &Ray, t_min: f64, t_max: f64) -> Option<Hit> { + let oc = ray.orig - self.center; + 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())) + } + 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 + } +} |