~ttt/ray_tracing_in_one_weekend

5d3c6c4e1ce99024a42527eed20986628d8f49c4 — Tomasz Kłak 4 years ago 6e424b8
ch 6.3 done
3 files changed, 66 insertions(+), 0 deletions(-)

A src/hittable.rs
M src/main.rs
A src/sphere.rs
A src/hittable.rs => src/hittable.rs +13 -0
@@ 0,0 1,13 @@
use crate::vec3::*;
use crate::ray::*;

#[derive(Debug, Clone, Copy, Default)]
pub struct HitRecord {
    pub p: Point3,
    pub normal: Vec3,
    pub t: f64,
}

pub trait Hittable {
    fn hit(&self, r: &Ray, t_min: f64, t_max: f64) -> Option<HitRecord>;
}

M src/main.rs => src/main.rs +6 -0
@@ 4,6 4,12 @@ use vec3::*;
mod ray;
use ray::*;

mod hittable;
use hittable::*;

mod sphere;
use sphere::*;

fn hit_sphere(center: &Point3, radius: f64, r: &Ray) -> f64 {
    let oc = r.origin() - *center;
    let a = r.direction().length_squared();

A src/sphere.rs => src/sphere.rs +47 -0
@@ 0,0 1,47 @@
use crate::vec3::*;
use crate::ray::*;
use crate::hittable::*;

#[derive(Debug, Clone, Copy, Default)]
pub struct Sphere {
    center: Point3,
    radius: f64,
}

impl Sphere {
    fn new(center: Point3, radius: f64) -> Self {
        Self{center, radius}
    }
}

impl Hittable for Sphere {
    fn hit(&self, r: &Ray, t_min: f64, t_max: f64) -> Option<HitRecord> {
        let oc = r.origin() - self.center;
        let a = r.direction().length_squared();
        let half_b = dot(&oc, &r.direction());
        let c = oc.length_squared() - self.radius*self.radius;
        let discriminant = half_b*half_b - a*c;

        if discriminant > 0.0 {
            let root = discriminant.sqrt();

            let temp = (-half_b - root) / a;
            if temp < t_max && temp > t_min {
                let t = temp;
                let p = r.at(t);
                let normal = (p - self.center) / self.radius;
                return Some(HitRecord{t, p, normal})
            }

            let temp = (-half_b + root) / a;
            if temp < t_max && temp > t_min {
                let t = temp;
                let p = r.at(t);
                let normal = (p - self.center) / self.radius;
                return Some(HitRecord{t, p, normal})
            }
        }

        return None;
    }
}