Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added background image of linear blend and foreground image of a sphere #3

Merged
merged 8 commits into from
Aug 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

16 changes: 15 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,21 @@
name = "ray_tracer"
version = "0.1.0"
edition = "2021"
license = "GNU GENERAL PUBLIC LICENSE"
authors = ["Sen"]

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
lib ={ path = "lib"} # needed for the tests to work

[[bin]]
name = "project_bin"
path = "src/main.rs"

# Check https://rust-classes.com/chapter_4_3
[workspace]
members = [
"lib",
"project_bin",
]
resolver = "2"
8 changes: 8 additions & 0 deletions lib/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
[package]
name = "lib"
version = "0.1.0"
edition = "2021"
license = "GNU GENERAL PUBLIC LICENSE"
authors = ["Sen"]

[dependencies]
1 change: 1 addition & 0 deletions lib/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pub mod utilities;
114 changes: 114 additions & 0 deletions lib/src/utilities/color.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
use std::io::Write;
use std::ops::Add;
use std::{
fs::File,
ops::{AddAssign, Div, Mul, MulAssign},
};

/// The color Class
///

#[derive(Clone, Copy)]
pub struct Color {
red: f64,
green: f64,
blue: f64,
}

impl Color {
pub fn new(red: f64, green: f64, blue: f64) -> Self {
Color { red, green, blue }
}

pub fn get_r(self) -> f64 {
self.red
}
pub fn get_g(self) -> f64 {
self.green
}
pub fn get_b(self) -> f64 {
self.blue
}

pub fn write_color(&self, file: &mut File) -> std::io::Result<()> {
let rbyte = (255.999 * self.red) as i32;
let gbyte = (255.999 * self.green) as i32;
let bbyte = (255.999 * self.blue) as i32;

writeln!(file, "{} {} {}", rbyte, gbyte, bbyte)
}
}

impl Default for Color {
fn default() -> Self {
Color {
red: 0.0,
green: 0.0,
blue: 0.0,
}
}
}

impl AddAssign for Color {
fn add_assign(&mut self, rhs: Self) {
self.red += rhs.red;
self.green += rhs.green;
self.blue += rhs.blue;
}
}

impl Add for Color {
type Output = Self;
fn add(self, rhs: Self) -> Self::Output {
Self {
red: self.red + rhs.red,
green: self.green + rhs.green,
blue: self.blue + rhs.blue,
}
}
}

impl MulAssign for Color {
fn mul_assign(&mut self, rhs: Self) {
self.red *= rhs.red;
self.green *= rhs.green;
self.blue *= rhs.blue;
}
}

// https://doc.rust-lang.org/std/ops/trait.Mul.html
impl Mul<f64> for Color {
type Output = Self;
fn mul(self, rhs: f64) -> Self::Output {
Self {
red: self.red * rhs,
green: self.green * rhs,
blue: self.blue * rhs,
}
}
}

impl Div<f64> for Color {
type Output = Self;
fn div(self, rhs: f64) -> Self::Output {
Self {
red: self.red / rhs,
green: self.green / rhs,
blue: self.blue / rhs,
}
}
}

pub trait Cross {
fn cross_prod(&self, rhs: Self) -> Self;
}

impl Cross for Color {
fn cross_prod(&self, rhs: Self) -> Self {
Self {
red: (self.green * rhs.blue) - (self.blue * rhs.green),
green: (self.blue * rhs.red) - (self.red * rhs.blue),
blue: (self.red * rhs.green) - (self.green * rhs.red),
}
}
}
4 changes: 4 additions & 0 deletions lib/src/utilities/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
pub mod color;
pub mod point;
pub mod ray;
pub mod vector3;
97 changes: 97 additions & 0 deletions lib/src/utilities/point.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
use super::vector3::Vector3;
use std::ops::{Add, Neg, Sub};

/// The Point3 Class
///

#[derive(Clone, Copy)]
pub struct Point3 {
x: f64,
y: f64,
z: f64,
}

impl Point3 {
pub fn new(x: f64, y: f64, z: f64) -> Self {
Self { x, y, z }
}

pub fn get_x(self) -> f64 {
self.x
}
pub fn get_y(self) -> f64 {
self.y
}
pub fn get_z(self) -> f64 {
self.z
}

pub fn as_vec(&self) -> Vector3 {
Vector3::new(self.x, self.y, self.z)
}
}

impl Default for Point3 {
fn default() -> Self {
Self {
x: 0.0,
y: 0.0,
z: 0.0,
}
}
}

impl Neg for Point3 {
type Output = Self;
fn neg(self) -> Self::Output {
Self {
x: -self.x,
y: -self.y,
z: -self.z,
}
}
}

impl Add for Point3 {
type Output = Self;
fn add(self, rhs: Self) -> Self::Output {
Self {
x: self.x + rhs.x,
y: self.y + rhs.y,
z: self.z + rhs.z,
}
}
}

impl Sub for Point3 {
type Output = Self;
fn sub(self, rhs: Self) -> Self::Output {
Self {
x: self.x - rhs.x,
y: self.y - rhs.y,
z: self.z - rhs.z,
}
}
}

impl Add<Vector3> for Point3 {
type Output = Self;
fn add(self, rhs: Vector3) -> Self::Output {
Self {
x: self.x + rhs.get_x(),
y: self.y + rhs.get_y(),
z: self.z + rhs.get_z(),
}
}
}

impl Sub<Vector3> for Point3 {
type Output = Self;
fn sub(self, rhs: Vector3) -> Self::Output {
Self {
x: self.x - rhs.get_x(),
y: self.y - rhs.get_y(),
z: self.z - rhs.get_z(),
}
}
}
65 changes: 65 additions & 0 deletions lib/src/utilities/ray.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
use super::{color::Color, point::Point3, vector3::Vector3};

/// The Ray Class
///

pub struct Ray {
origin: Point3,
direction: Vector3,
}

impl Ray {
pub fn new(origin: Point3, direction: Vector3) -> Self {
Self { origin, direction }
}

pub fn position(&self, parameter: f64) -> Point3 {
let positon_fn = |t: f64| self.origin + (self.direction * t);
positon_fn(parameter)
}

pub fn get_origin(&self) -> Point3 {
self.origin
}
pub fn get_direction(&self) -> Vector3 {
self.direction
}

fn is_sphere_hit(&self, center: &Point3, radius: f64) -> bool {
let dist_center_origin: Vector3 = (*center - self.get_origin()).as_vec();
let a: f64 = self.get_direction().dot_prod(self.get_direction());
let b: f64 = -2.0 * (self.get_direction().dot_prod(dist_center_origin));
let c: f64 = (dist_center_origin.dot_prod(dist_center_origin)) - (radius * radius);

let discriminant: f64 = (b * b) - (4.0 * (a * c)); // For finding roots of a quadratic eqn b^2 -4ac = 0
discriminant >= 0.0
}

/// Implements a simple gradient
pub fn ray_color(&self) -> Color {
// Check if sphere is hit: color it red
let sphere_hit = self.is_sphere_hit(&Point3::new(0.0, 0.0, -1.0), 0.5);
if sphere_hit {
println!("Inside sphere hit");
return Color::new(1.0, 0.0, 0.0);
}

// Color the background blue
let unit_direction: Vector3 = self.get_direction().unit_vector();
let a: f64 = 0.5 * (unit_direction.get_y() + 1.0);

// Linear blending or Linear interpolation
// blendedValue = (1−a)⋅startValue+a⋅endValue
// Returns a blue blended color
(Color::new(1.0, 1.0, 1.0) * (1.0 - a)) + (Color::new(0.5, 0.7, 1.0) * a)
}
}

impl Default for Ray {
fn default() -> Self {
Self {
origin: Point3::default(),
direction: Vector3::default(),
}
}
}
Loading