use std::sync::Arc; use crate::{ objects::{materials::traits::Material, traits::Hittable}, ray::Ray, vec3::Vec3, }; use super::hit::Hit; #[derive(Debug)] pub struct Circle { radius: f32, center: Vec3, normal: Vec3, material: Arc, } impl Circle { pub fn new(radius: f32, center: Vec3, normal: Vec3, material: Arc) -> Self { Self { radius, center, normal: normal.get_unit(), material, } } } impl Hittable for Circle { fn hit(&self, r: &Ray) -> Option { // check if ray parallel to plane let dot = self.normal.dot(r.dir()); if dot == 0.0 { return None; } // hitpoint on plane let t = self.normal.dot(&(self.center - r.origin())) / dot; // hits behind camera if t < 0. { return None; }; let p = r.at(t); if (p - self.center).length() < self.radius { return Some(Hit::new(t, p, self.normal, self.material.clone(), self.normal.dot(&r.dir()) < 0.)); } None } }