M src/hittable.rs => src/hittable.rs +13 -1
@@ 1,11 1,23 @@
-use crate::vec3::*;
use crate::ray::*;
+use crate::vec3::*;
#[derive(Debug, Clone, Copy, Default)]
pub struct HitRecord {
pub p: Point3,
pub normal: Vec3,
pub t: f64,
+ pub front_face: bool,
+}
+
+impl HitRecord {
+ pub fn set_face_normal(&mut self, r: &Ray, outward_normal: &Vec3) {
+ self.front_face = dot(&r.direction(), outward_normal) < 0.0;
+ self.normal = if self.front_face {
+ *outward_normal
+ } else {
+ -outward_normal
+ };
+ }
}
pub trait Hittable {
M src/main.rs => src/main.rs +5 -6
@@ 14,14 14,13 @@ fn hit_sphere(center: &Point3, radius: f64, r: &Ray) -> f64 {
let oc = r.origin() - *center;
let a = r.direction().length_squared();
let half_b = dot(&oc, &r.direction());
- let c = oc.length_squared() - radius*radius;
- let discriminant = half_b*half_b - a*c;
-
+ let c = oc.length_squared() - radius * radius;
+ let discriminant = half_b * half_b - a * c;
if discriminant < 0.0 {
-1.0
} else {
- (-half_b - discriminant.sqrt() ) / a
+ (-half_b - discriminant.sqrt()) / a
}
}
@@ 29,7 28,7 @@ fn ray_color(r: &Ray) -> Color {
let t = hit_sphere(&Point3::new(0.0, 0.0, -1f64), 0.5, r);
if t > 0.0 {
let N = unit_vector(r.at(t) - Vec3::new(0.0, 0.0, -1.0));
- return 0.5*Color::new(N.x()+1.0, N.y()+1.0, N.z()+1.0);
+ return 0.5 * Color::new(N.x() + 1.0, N.y() + 1.0, N.z() + 1.0);
}
let unit_direction = unit_vector(r.direction());
let t = 0.5 * (unit_direction.y() + 1.0);
@@ 69,7 68,7 @@ fn main() {
let v = j as f64 / (image_height - 1) as f64;
let r = Ray::new(
&origin,
- &(lower_left_corner + u * horizontal + v * vertical - origin)
+ &(lower_left_corner + u * horizontal + v * vertical - origin),
);
let pixel_color = ray_color(&r);
write_color(&mut handle, pixel_color);
M src/sphere.rs => src/sphere.rs +23 -9
@@ 1,6 1,6 @@
-use crate::vec3::*;
-use crate::ray::*;
use crate::hittable::*;
+use crate::ray::*;
+use crate::vec3::*;
#[derive(Debug, Clone, Copy, Default)]
pub struct Sphere {
@@ 10,7 10,7 @@ pub struct Sphere {
impl Sphere {
fn new(center: Point3, radius: f64) -> Self {
- Self{center, radius}
+ Self { center, radius }
}
}
@@ 19,8 19,8 @@ impl Hittable for Sphere {
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;
+ 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();
@@ 29,16 29,30 @@ impl Hittable for Sphere {
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 mut rec = HitRecord {
+ t: temp,
+ p,
+ normal: (p - self.center) / self.radius,
+ front_face: false,
+ };
+ let outward_normal = (rec.p - self.center) / self.radius;
+ rec.set_face_normal(r, &outward_normal);
+ return Some(rec);
}
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 mut rec = HitRecord {
+ t: temp,
+ p,
+ normal: (p - self.center) / self.radius,
+ front_face: false,
+ };
+ let outward_normal = (rec.p - self.center) / self.radius;
+ rec.set_face_normal(r, &outward_normal);
+ return Some(rec);
}
}