HittableList

This commit is contained in:
dengqn 2025-08-03 02:16:05 +08:00
parent 63ccb552fd
commit 5a77b92d9e
4 changed files with 40 additions and 16 deletions

View File

@ -1,5 +1,20 @@
use crate::types_defined::{HitRecord, Ray}; use crate::types_defined::{HitRecord, Ray};
pub trait Hittable { pub trait Hittable {
fn hit(self, r: &Ray, t_min: f32, t_max: f32) -> HitRecord; fn hit(&self, r: &Ray, t_min: f32, t_max: f32) -> HitRecord;
} }
pub struct HittableList {
pub objects: Vec<Box<dyn Hittable>>
}
impl HittableList {
pub fn hit(&self, r: &Ray, t_min: f32, t_max: f32) -> Vec<HitRecord> {
let mut records = vec![];
for object in &self.objects {
records.push(object.hit(r, t_min, t_max));
}
records
}
}

View File

@ -23,7 +23,7 @@ pub fn gen_ray_sphere_normal_ppm_p3(width: i32, height: i32, camera_center: Vec3
*/ */
let _sphere_center = Point::new(0.0, 0.0, -1.0); let _sphere_center = Point::new(0.0, 0.0, -1.0);
let sphere_radius = 0.5; let sphere_radius = -0.5;
let sphere = Sphere::new(_sphere_center, sphere_radius); let sphere = Sphere::new(_sphere_center, sphere_radius);
// determind color // determind color
@ -43,15 +43,16 @@ ray color functions
fn ray_color<H: Hittable>(r: &Ray, h: H) -> Color { fn ray_color<H: Hittable>(r: &Ray, h: H) -> Color {
let hr = h.hit(&r, 0.0, f32::MAX); let hr = h.hit(&r, 0.0, f32::MAX);
if hr.t >= 0.0 { if hr.t >= 0.0 {
let inter_point = hr.p; let normal_color = 0.5 * (hr.normal + Point::new(1.0, 1.0, 1.0));
// 单位向量 return if hr.front_face {
let n = inter_point / inter_point.dot(inter_point); normal_color
// 法向量也是 -11 +1再x0.5让他落到颜色的区间 } else {
// return 0.5 * (n - sphere_center + Point::new(1.0, 1.0, 1.0)) Color::new(1.0, 1.0, 1.0) - normal_color
return 0.5 * (hr.normal + Point::new(1.0, 1.0, 1.0)) }
} }
// v / |v| // v / |v|
let unit_direction = r.direction / r.direction.length(); let unit_direction = r.direction / r.direction.length();
let a = 0.5*(unit_direction.y + 1.0); let a = 0.5*(unit_direction.y + 1.0);
return (1.0-a)*Color::new(1.0, 1.0, 1.0) + a*Color::new(0.5, 0.7, 1.0); // return background color.
(1.0-a)*Color::new(1.0, 1.0, 1.0) + a*Color::new(0.5, 0.7, 1.0)
} }

View File

@ -11,7 +11,7 @@ impl Sphere {
} }
impl hittable::Hittable for Sphere { impl hittable::Hittable for Sphere {
fn hit(self, r: &Ray, t_min: f32, t_max: f32) -> HitRecord { fn hit(&self, r: &Ray, t_min: f32, t_max: f32) -> HitRecord {
let a: f32 = r.direction.length_squared(); let a: f32 = r.direction.length_squared();
let h = r.direction.dot(self.center - r.point); let h = r.direction.dot(self.center - r.point);
// let b = -2.0 * r.direction.dot(sphere_center - r.point); // let b = -2.0 * r.direction.dot(sphere_center - r.point);
@ -19,7 +19,7 @@ impl hittable::Hittable for Sphere {
let discriminant = h * h - a * c; let discriminant = h * h - a * c;
// // 两个 // // 两个
let disc_sqrt = discriminant.sqrt(); let disc_sqrt = discriminant.sqrt();
let near = (h - disc_sqrt) / a; let near = (h - disc_sqrt) / a;
let far = (h + disc_sqrt) / a; let far = (h + disc_sqrt) / a;
@ -32,10 +32,14 @@ impl hittable::Hittable for Sphere {
} }
} }
let p = r.at(root);
let normal = (p - self.center) / self.radius;
HitRecord { HitRecord {
t: root, t: root,
p: r.at(root), // p,
normal: r.at(root) - self.center, normal,
// check if r.p inside(>=0) the sphere.
front_face: r.direction.dot(normal) < 0.0,
} }
} }
} }

View File

@ -1,6 +1,8 @@
/* /*
* [3] * [3]
*/ */
use crate::hittable::Hittable;
#[derive(Debug, Clone, Copy, PartialEq)] #[derive(Debug, Clone, Copy, PartialEq)]
pub struct Vec3 { pub struct Vec3 {
pub x: f32, pub x: f32,
@ -21,11 +23,13 @@ pub struct Ray {
pub struct HitRecord { pub struct HitRecord {
pub t: f32, pub t: f32,
pub p: Vec3, // pub p: Vec3,
pub normal: Vec3, pub normal: Vec3,
pub front_face: bool,
} }
/* /*
///////////// /////////////
// for test // for test