@@ 4,7 4,19 @@ use vec3::*;
mod ray;
use ray::*;
+fn hit_sphere(center: &Point3, radius: f64, r: &Ray) -> bool {
+ let oc = r.origin() - *center;
+ let a = dot(&r.direction(), &r.direction());
+ let b = 2.0 * dot(&oc, &r.direction());
+ let c = dot(&oc, &oc) - radius*radius;
+ let discriminant = b*b - 4f64*a*c;
+ discriminant > 0.0
+}
+
fn ray_color(r: &Ray) -> Color {
+ if hit_sphere(&Point3::new(0.0, 0.0, -1f64), 0.5, r) {
+ return Color::new(1.0, 0.0, 0.0);
+ }
let unit_direction = unit_vector(r.direction());
let t = 0.5 * (unit_direction.y() + 1.0);
(1.0 - t) * Color::new(1.0, 1.0, 1.0) + t * Color::new(0.5, 0.7, 1.0)
@@ 17,6 29,7 @@ fn main() {
// Image
let aspect_ratio = 16.0 / 9.0;
let image_width = 400;
+ let image_width = 800;
let image_height = (image_width as f64 / aspect_ratio) as i32;
// Camera
@@ 25,11 38,11 @@ fn main() {
let viewport_width = aspect_ratio * viewport_height;
let focal_length = 1.0;
- let origin = Point3::new(0f64, 0f64, 0f64);
- let horizontal = Vec3::new(viewport_width, 0f64, 0f64);
- let vertical = Vec3::new(0f64, viewport_height, 0f64);
+ let origin = Point3::new(0.0, 0.0, 0.0);
+ let horizontal = Vec3::new(viewport_width, 0.0, 0.0);
+ let vertical = Vec3::new(0.0, viewport_height, 0.0);
let lower_left_corner =
- origin - horizontal / 2f64 - vertical / 2f64 - Vec3::new(0f64, 0f64, focal_length);
+ origin - horizontal / 2f64 - vertical / 2f64 - Vec3::new(0.0, 0.0, focal_length);
// Render
@@ 0,0 1,27 @@
+use crate::vec3::*;
+
+#[derive(Debug, Clone, Copy, Default)]
+pub struct Ray {
+ orig: Point3,
+ dir: Vec3,
+}
+
+impl Ray {
+ pub fn new(orig: &Point3, dir: &Vec3) -> Self {
+ Ray {
+ orig: *orig,
+ dir: *dir,
+ }
+ }
+
+ pub fn origin(&self) -> Point3 {
+ self.orig
+ }
+ pub fn direction(&self) -> Vec3 {
+ self.dir
+ }
+
+ pub fn at(&self, t: f64) -> Point3 {
+ self.orig + t * self.dir
+ }
+}