feat(raytracer): add minimal implementation

This commit is contained in:
2024-11-17 14:03:05 +01:00
parent 369293598f
commit a1ccb33a6e
10 changed files with 443 additions and 0 deletions

49
src/raytracer/sphere.rs Normal file
View File

@@ -0,0 +1,49 @@
use super::types::{Intersect, Material, Point3, Ray, Scalar, Vector3};
extern crate nalgebra as na;
pub struct Sphere {
center: Point3,
radius: Scalar,
material: Material,
}
/// Numerical error tolerance
const EPSILON: Scalar = 1e-5;
impl Intersect for Sphere {
fn intersect<'a>(&'a self, ray: &Ray) -> Option<(Point3, Vector3, Scalar, &'a Material)> {
let co = ray.origin - self.center;
let a = ray.direction.dot(&ray.direction);
let b = 2.0 * ray.direction.dot(&co);
let c = co.dot(&co) - (self.radius * self.radius);
let d = b * b - 4.0 * a * c;
if d >= 0.0 {
let e = d.sqrt();
let t1 = (-b - e) / (2.0 * a);
let t2 = (-b + e) / (2.0 * a);
let mut t = Scalar::MAX;
if t1 > EPSILON && t1 < t {
t = t1;
}
if t2 > EPSILON && t2 < t {
t = t2;
}
if t < Scalar::MAX {
let isect_pt: Point3 = ray.origin + ray.direction * t;
return Some((
isect_pt,
(isect_pt - self.center) / self.radius,
t,
&self.material,
));
}
}
None
}
}