aboutsummaryrefslogtreecommitdiffstats
path: root/src/sphere.rs
diff options
context:
space:
mode:
authorYann Herklotz <git@yannherklotz.com>2020-10-10 00:12:12 +0100
committerYann Herklotz <git@yannherklotz.com>2020-10-10 00:12:12 +0100
commit495d1c9c113098f24767b595c7e830f0fa8bc991 (patch)
tree95eac21eacecadc58f23a59216e764ddd6928979 /src/sphere.rs
parentdd5ac7c5fe336e9cac794cfa72d139613a99b466 (diff)
downloadleela-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.rs104
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