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};
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_radius = 0.5;
let sphere_radius = -0.5;
let sphere = Sphere::new(_sphere_center, sphere_radius);
// determind color
@ -43,15 +43,16 @@ ray color functions
fn ray_color<H: Hittable>(r: &Ray, h: H) -> Color {
let hr = h.hit(&r, 0.0, f32::MAX);
if hr.t >= 0.0 {
let inter_point = hr.p;
// 单位向量
let n = inter_point / inter_point.dot(inter_point);
// 法向量也是 -11 +1再x0.5让他落到颜色的区间
// return 0.5 * (n - sphere_center + Point::new(1.0, 1.0, 1.0))
return 0.5 * (hr.normal + Point::new(1.0, 1.0, 1.0))
let normal_color = 0.5 * (hr.normal + Point::new(1.0, 1.0, 1.0));
return if hr.front_face {
normal_color
} else {
Color::new(1.0, 1.0, 1.0) - normal_color
}
}
// v / |v|
let unit_direction = r.direction / r.direction.length();
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 {
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 h = r.direction.dot(self.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 disc_sqrt = discriminant.sqrt();
let near = (h - disc_sqrt) / a;
let far = (h + disc_sqrt) / a;
@ -31,11 +31,15 @@ impl hittable::Hittable for Sphere {
root = -1.0;
}
}
let p = r.at(root);
let normal = (p - self.center) / self.radius;
HitRecord {
t: root,
p: r.at(root),
normal: r.at(root) - self.center,
// p,
normal,
// check if r.p inside(>=0) the sphere.
front_face: r.direction.dot(normal) < 0.0,
}
}
}

View File

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