Skip to content

Commit

Permalink
feat: add sphere to shapes
Browse files Browse the repository at this point in the history
  • Loading branch information
alanjian85 committed Jul 17, 2024
1 parent 8cdd343 commit 1af881f
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 15 deletions.
6 changes: 6 additions & 0 deletions src/core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,9 @@ impl Ray {
self.orig + t * self.dir
}
}

pub trait Intersect {
fn intersect(&self, _ray: &Ray) -> Option<f64> {
None
}
}
21 changes: 6 additions & 15 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,31 +1,22 @@
mod camera;
mod cli;
mod core;
mod shapes;

use camera::Camera;
use clap::Parser;
use cli::{Cli, Size};
use core::Ray;
use core::{Intersect, Ray};
use image::{Rgb, RgbImage};
use indicatif::ProgressBar;
use nalgebra::{Point2, Point3, Vector3};
use palette::{LinSrgb, Srgb};

fn hit_sphere(center: Point3<f64>, radius: f64, ray: &Ray) -> Option<f64> {
let a = ray.dir.magnitude_squared();
let b = (-2.0 * ray.dir).dot(&(center - ray.orig));
let c = (center - ray.orig).magnitude_squared() - radius * radius;
let discriminant = b * b - 4.0 * a * c;
if discriminant < 0.0 {
return None;
}
Some((-b - discriminant.sqrt()) / (2.0 * a))
}
use shapes::Sphere;

fn ray_color(ray: &Ray) -> LinSrgb<f64> {
let sphere_center = Point3::new(0.0, 0.0, -1.0);
if let Some(t) = hit_sphere(sphere_center, 0.5, ray) {
let normal = (ray.at(t) - sphere_center).normalize();
let sphere = Sphere::new(Point3::new(0.0, 0.0, -1.0), 0.5);
if let Some(t) = sphere.intersect(ray) {
let normal = (ray.at(t) - Point3::new(0.0, 0.0, -1.0)).normalize();
let normal = 0.5 * (normal + Vector3::new(1.0, 1.0, 1.0));
return LinSrgb::new(normal.x, normal.y, normal.z);
}
Expand Down
26 changes: 26 additions & 0 deletions src/shapes.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
use crate::{Intersect, Ray};
use nalgebra::Point3;

pub struct Sphere {
center: Point3<f64>,
radius: f64,
}

impl Sphere {
pub fn new(center: Point3<f64>, radius: f64) -> Self {
Self { center, radius }
}
}

impl Intersect for Sphere {
fn intersect(&self, ray: &Ray) -> Option<f64> {
let a = ray.dir.magnitude_squared();
let b = ray.dir.dot(&(self.center - ray.orig));
let c = (self.center - ray.orig).magnitude_squared() - self.radius * self.radius;
let discriminant = b * b - a * c;
if discriminant < 0.0 {
return None;
}
Some((b - discriminant.sqrt()) / a)
}
}

0 comments on commit 1af881f

Please sign in to comment.