aboutsummaryrefslogtreecommitdiffstats
path: root/src/sphere.rs
diff options
context:
space:
mode:
authorYann Herklotz <git@yannherklotz.com>2020-04-26 21:15:53 +0100
committerYann Herklotz <git@yannherklotz.com>2020-04-26 21:15:53 +0100
commit9f4cdae92c8df0a7990fdb77d9ff161b2eebf467 (patch)
treeeb1e8c4de3b6040859c88fb8c2ea69580a73ec10 /src/sphere.rs
downloadleela-9f4cdae92c8df0a7990fdb77d9ff161b2eebf467.tar.gz
leela-9f4cdae92c8df0a7990fdb77d9ff161b2eebf467.zip
Add initial files
Diffstat (limited to 'src/sphere.rs')
-rw-r--r--src/sphere.rs40
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
+ }
+}