Skip to content

Commit

Permalink
feat: add color struct
Browse files Browse the repository at this point in the history
  • Loading branch information
alanjian85 committed Jul 8, 2024
1 parent 418b912 commit 1a1c755
Show file tree
Hide file tree
Showing 4 changed files with 85 additions and 28 deletions.
2 changes: 1 addition & 1 deletion src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ impl Size {
impl FromStr for Size {
type Err = String;

fn from_str(s: &str) -> Result<Self, Self::Err> {
fn from_str(s: &str) -> Result<Self, String> {
let size: Vec<_> = s.split('x').collect();
if size.len() != 2 {
return Err(String::from("invalid number of dimensions found in string"));
Expand Down
73 changes: 73 additions & 0 deletions src/core.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
use nalgebra::{Point3, Vector3};
use std::ops::{Add, Mul};

pub struct Ray {
pub orig: Point3<f64>,
pub dir: Vector3<f64>,
}

impl Ray {
pub fn new(orig: Point3<f64>, dir: Vector3<f64>) -> Self {
Self { orig, dir }
}

pub fn at(&self, t: f64) -> Point3<f64> {
self.orig + t * self.dir
}
}

pub struct Color {
pub r: f64,
pub g: f64,
pub b: f64,
}

impl Color {
pub fn new(r: f64, g: f64, b: f64) -> Self {
Self { r, g, b }
}

pub fn from(vec: Vector3<f64>) -> Self {
Self {
r: vec.x,
g: vec.y,
b: vec.z,
}
}
}

impl Add for Color {
type Output = Self;

fn add(self, rhs: Self) -> Self {
Self {
r: self.r + rhs.r,
g: self.g + rhs.g,
b: self.b + rhs.b,
}
}
}

impl Mul<f64> for Color {
type Output = Self;

fn mul(self, rhs: f64) -> Self {
Self {
r: self.r * rhs,
g: self.g * rhs,
b: self.b * rhs,
}
}
}

impl Mul<Color> for f64 {
type Output = Color;

fn mul(self, rhs: Color) -> Color {
Color {
r: self * rhs.r,
g: self * rhs.g,
b: self * rhs.b,
}
}
}
22 changes: 11 additions & 11 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
mod cli;
mod ray;
mod core;

use clap::Parser;
use cli::{Cli, Size};
use core::{Color, Ray};
use image::{Rgb, RgbImage};
use indicatif::ProgressBar;
use nalgebra::{Point3, Vector3};
use ray::Ray;

fn hit_sphere(center: Point3<f64>, radius: f64, ray: &Ray) -> Option<f64> {
let a = ray.dir.magnitude_squared();
Expand All @@ -19,16 +19,16 @@ fn hit_sphere(center: Point3<f64>, radius: f64, ray: &Ray) -> Option<f64> {
Some((-b - discriminant.sqrt()) / (2.0 * a))
}

fn ray_color(ray: &Ray) -> Vector3<f64> {
fn ray_color(ray: &Ray) -> Color {
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();
return 0.5 * (normal + Vector3::new(1.0, 1.0, 1.0));
let normal = Color::from((ray.at(t) - sphere_center).normalize());
return 0.5 * (normal + Color::new(1.0, 1.0, 1.0));
}

let dir = ray.dir.normalize();
let a = 0.5 * (dir.y + 1.0);
(1.0 - a) * Vector3::new(1.0, 1.0, 1.0) + a * Vector3::new(0.5, 0.7, 1.0)
let alpha = 0.5 * (dir.y + 1.0);
(1.0 - alpha) * Color::new(1.0, 1.0, 1.0) + alpha * Color::new(0.5, 0.7, 1.0)
}

fn main() {
Expand Down Expand Up @@ -56,15 +56,15 @@ fn main() {
let ray = Ray::new(camera_pos, pixel_pos - camera_pos);
let color = ray_color(&ray);

let r = (255.999 * color.x) as u8;
let g = (255.999 * color.y) as u8;
let b = (255.999 * color.z) as u8;
let r = (255.999 * color.r) as u8;
let g = (255.999 * color.g) as u8;
let b = (255.999 * color.b) as u8;

image.put_pixel(x, y, Rgb([r, g, b]));
}
progress_bar.inc(1);
}

image.save(cli.output).unwrap();
progress_bar.finish();
image.save(cli.output).unwrap();
}
16 changes: 0 additions & 16 deletions src/ray.rs

This file was deleted.

0 comments on commit 1a1c755

Please sign in to comment.