From a69da66caaf8cc0b1d655b7d431caaeddb99c7c6 Mon Sep 17 00:00:00 2001 From: ishanjain28 Date: Wed, 23 Jan 2019 03:32:06 +0530 Subject: [PATCH] Refactored everything again --- ria-weekend/examples/ppm.rs | 42 ++++------------------ ria-weekend/examples/ray_demo.rs | 47 ++++++++---------------- ria-weekend/src/demo.rs | 61 ++++++++++++++++++++++++++++++++ ria-weekend/src/lib.rs | 2 ++ ria-weekend/src/ppm.rs | 3 +- ria-weekend/src/ray.rs | 16 ++++----- 6 files changed, 91 insertions(+), 80 deletions(-) create mode 100644 ria-weekend/src/demo.rs diff --git a/ria-weekend/examples/ppm.rs b/ria-weekend/examples/ppm.rs index d0d6bf5..21fd10a 100644 --- a/ria-weekend/examples/ppm.rs +++ b/ria-weekend/examples/ppm.rs @@ -1,43 +1,13 @@ extern crate ria_weekend; -use ria_weekend::ppm; -use std::error::Error; -use std::fs::File; -use std::{io, io::Write}; +use ria_weekend::{ppm, demo::Demo}; fn main() { - let mut height = 1080; - let mut width = 1920; + let demo = Demo::new("ppm_sample"); + let dimensions = demo.dimensions(); + let mut buf = String::new(); - println!("Enter width and height seperated by space"); + ppm::create_sample(&mut buf, dimensions); - let mut input = String::new(); - io::stdin() - .read_line(&mut input) - .expect("error in reading input"); - - let input = input - .trim() - .split(" ") - .map(|v| v.parse::().expect("error in parsing input")) - .collect::>(); - - if input.len() >= 2 { - height = input[1]; - width = input[0]; - } - let file_name = format!("ppm_sample{}x{}.ppm", width, height); - let mut buf = format!("P3\n{} {}\n255\n", width, height); - - ppm::create_sample(&mut buf, height, width); - - let mut file = match File::create(&file_name) { - Ok(file) => file, - Err(e) => panic!("couldn't create {}: {}", file_name, e.description()), - }; - - match file.write_all(buf.as_bytes()) { - Ok(_) => println!("Succesfully wrote to {}", file_name), - Err(e) => panic!("couldn't write to {}: {}", file_name, e.description()), - } + demo.save_as_ppm(buf); } diff --git a/ria-weekend/examples/ray_demo.rs b/ria-weekend/examples/ray_demo.rs index 2d4f2d2..3dd3a78 100644 --- a/ria-weekend/examples/ray_demo.rs +++ b/ria-weekend/examples/ray_demo.rs @@ -1,41 +1,22 @@ extern crate ria_weekend; -use ria_weekend::ray; -use std::error::Error; -use std::fs::File; -use std::{io, io::Write}; +use ria_weekend::{demo::Demo, ray, ray::Ray, vec3::Vec3}; fn main() { - let mut height = 100; - let mut width = 200; + let demo = Demo::new("ray_demo"); + let dimensions = demo.dimensions(); - println!("Enter width and height seperated by space"); - - let mut input = String::new(); - io::stdin() - .read_line(&mut input) - .expect("error in reading input"); - - let input = input - .trim() - .split(" ") - .map(|v| v.parse::().expect("error in parsing input")) - .collect::>(); - - if input.len() >= 2 { - height = input[1]; - width = input[0]; - } - let file_name = format!("ray_demo{}x{}.ppm", width, height); - let mut buf = format!("P3\n{} {}\n255\n", width, height); - let mut file = match File::create(&file_name) { - Ok(file) => file, - Err(e) => panic!("couldn't create {}: {}", file_name, e.description()), + let mut buf = String::new(); + // linear interpolation based on y coordinate + // top to down + let linear_interpolate_y = |ray: Ray| -> Vec3 { + let unit_direction = ray.direction().unit_vector(); + let t = 0.5 * (unit_direction.y() + 1.0); + // (1.0 - t) * start blend_color + t * end color + Vec3::new(1.0, 1.0, 1.0) * (1.0 - t) + Vec3::new(0.0, 0.0, 0.0) * t }; - ray::create_ray_demo(&mut buf, width, height); - match file.write_all(buf.as_bytes()) { - Ok(_) => println!("Succesfully wrote to {}", file_name), - Err(e) => panic!("couldn't write to {}: {}", file_name, e.description()), - } + ray::create_ray_demo(&mut buf, dimensions, linear_interpolate_y); + + demo.save_as_ppm(buf); } diff --git a/ria-weekend/src/demo.rs b/ria-weekend/src/demo.rs new file mode 100644 index 0000000..798819e --- /dev/null +++ b/ria-weekend/src/demo.rs @@ -0,0 +1,61 @@ +use std::error::Error; +use std::fs::File; +use std::{io, io::Write}; + +#[derive(Debug)] +pub struct Demo { + width: u32, + height: u32, + file_name: String, +} + +impl Demo { + pub fn new(file_name: &str) -> Demo { + let mut height = 100; + let mut width = 200; + + println!("Enter width and height seperated by space"); + + let mut input = String::new(); + io::stdin() + .read_line(&mut input) + .expect("error in reading input"); + + let input = input + .trim() + .split(" ") + .map(|v| v.parse::().expect("error in parsing input")) + .collect::>(); + + if input.len() >= 2 { + height = input[1]; + width = input[0]; + } + let file_name = format!("{}-{}x{}.ppm", file_name, width, height); + + Demo { + width, + height, + file_name, + } + } + + pub fn save_as_ppm(&self, buf: String) { + let mut header = format!("P3\n{} {}\n255\n", self.width, self.height); + + let mut file = match File::create(&self.file_name) { + Ok(file) => file, + Err(e) => panic!("couldn't create {}: {}", self.file_name, e.description()), + }; + file.write(header.as_bytes()) + .expect("error in writing file header"); + match file.write_all(buf.as_bytes()) { + Ok(_) => println!("Succesfully wrote to {}", self.file_name), + Err(e) => panic!("couldn't write to {}: {}", self.file_name, e.description()), + } + } + + pub fn dimensions(&self) -> (u32, u32) { + (self.width, self.height) + } +} diff --git a/ria-weekend/src/lib.rs b/ria-weekend/src/lib.rs index 43dbe67..acab4a1 100644 --- a/ria-weekend/src/lib.rs +++ b/ria-weekend/src/lib.rs @@ -1,3 +1,5 @@ pub mod ppm; pub mod vec3; pub mod ray; +pub mod demo; + diff --git a/ria-weekend/src/ppm.rs b/ria-weekend/src/ppm.rs index 66025f1..2fdc666 100644 --- a/ria-weekend/src/ppm.rs +++ b/ria-weekend/src/ppm.rs @@ -1,6 +1,7 @@ use crate::vec3::Vec3; -pub fn create_sample(buf: &mut String, h: u32, w: u32) { +pub fn create_sample(buf: &mut String, dimensions: (u32, u32)) { + let (w, h ) = dimensions; for j in (0..h).rev() { for i in 0..w { let color = Vec3::new((i as f32) / (w as f32), (j as f32) / (h as f32), 0.5_f32); diff --git a/ria-weekend/src/ray.rs b/ria-weekend/src/ray.rs index ab0b884..4304619 100644 --- a/ria-weekend/src/ray.rs +++ b/ria-weekend/src/ray.rs @@ -20,16 +20,12 @@ impl Ray { } } -// linear interpolation based on y coordinate -// top to down -fn linear_interpolate_y(ray: Ray) -> Vec3 { - let unit_direction = ray.direction().unit_vector(); - let t = 0.5 * (unit_direction.y() + 1.0); - // (1.0 - t) * start blend_color + t * end color - Vec3::new(1.0, 1.0, 1.0) * (1.0 - t) + Vec3::new(0.0, 0.0, 0.0) * t -} +pub fn create_ray_demo(buf: &mut String, dimensions: (u32, u32), op: F) +where + F: Fn(Ray) -> Vec3, +{ + let (w, h) = dimensions; -pub fn create_ray_demo(buf: &mut String, w: u32, h: u32) { // uses standard cg RHS notation // y up, z pointing outwards and x to right let lower_left_corner = Vec3::new(-1.0, -1.0, -1.0); @@ -47,7 +43,7 @@ pub fn create_ray_demo(buf: &mut String, w: u32, h: u32) { let ray = Ray::new(origin, lower_left_corner + horizontal * u + vertical * v); - let color = linear_interpolate_y(ray); + let color = op(ray); let ir = (255.99 * color[0]) as u32; let ig = (255.99 * color[1]) as u32; let ib = (255.99 * color[2]) as u32;