use features::canvas::Canvas; use features::color::Color; use features::structs::Tuple; use features::matrix::Matrix; use std::f32::consts::PI; use std::fmt; use std::fs::File; use std::io::prelude::*; #[derive(Debug)] struct Environment { gravity: Tuple, wind: Tuple, } #[derive(Debug, Clone, Copy)] struct Projectile { position: Tuple, velocity: Tuple, } impl Projectile { fn new(position: Tuple, velocity: Tuple) -> Projectile { if !position.is_point() { panic!("position can not be a vector"); } if !velocity.is_vector() { panic!("velocity can not be point"); } Projectile { position: position, velocity: velocity, } } } impl Projectile { fn tick(&mut self, env: &Environment) { self.position = self.position + self.velocity; self.velocity = self.velocity + env.wind + env.gravity; } } impl fmt::Display for Projectile { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> fmt::Result { write!(f, "pos: {}, vel {}", self.position, self.velocity) } } fn init_env() -> Environment { Environment { gravity: Tuple::vector(0.0, 0.0, -0.98), wind: Tuple::vector(0.0, 0.0, 0.0), } } fn write_canvas_to_file(canvas: Canvas, file_path: &str) { let ppm = canvas.to_ppm(); let mut f = match File::create(file_path) { Ok(f) => f, Err(e) => panic!("file error. {}", e), }; let _ = match f.write_all(ppm.as_bytes()) { Ok(w) => w, Err(e) => panic!("did not write. {}", e), }; } fn before_clock() { let env = init_env(); let mut ball = Projectile::new( Tuple::point(0.0, 0.0, 0.0), Tuple::vector(2.2, 0.0, 21.0), ); let mut ball2 = Projectile::new( Tuple::point(195.0, 0.0, 0.0), Tuple::vector(-2.2, 0.0, 21.0), ); let mut ball3 = Projectile::new( Tuple::point(299.0, 0.0, 0.0), Tuple::vector(-2.2, 0.0, 21.0), ); let mut canvas = Canvas::new(300, 300); let color = Color::new(1.0, 0.0, 0.0); let color2 = Color::new(0.0, 1.0, 0.0); let color3 = Color::new(0.0, 0.0, 1.0); loop { canvas.write_pixel(ball.position.x() as usize, canvas.height() - (ball.position.z() as usize) - 1, color); canvas.write_pixel(ball2.position.x() as usize, canvas.height() - (ball2.position.z() as usize) - 1, color2); canvas.write_pixel(ball3.position.x() as usize, canvas.height() - (ball3.position.z() as usize) - 1, color3); ball.tick(&env); ball2.tick(&env); ball3.tick(&env); if ball.position.z() >= (canvas.height() - 1) as f32 || ball.position.z() < 0.0 || ball.position.x() >= (canvas.width() - 1) as f32 || ball.position.x() < 0.0 { break; } } write_canvas_to_file(canvas, "out.ppm"); let i = Matrix::identity(4); println!("The identity matrix is: {:#?}", i); let inverse_i = i.inverse(); println!("The inverse of the identity matrix is: {:#?}", inverse_i); let mut a = Matrix::from_array([ [1.0, 2.0, 3.0], [4.0, 5.0, 6.0], [7.0, 8.0, 1.0] ]); println!("Matrix: {:?}", a); let mut b = a.inverse(); println!("Inverse: {:?}", b); let c = &a * &b; println!("Multiplied by inverse: {:?}", c); b.transpose(); a.transpose(); let at = a.inverse(); println!("inverse then transpose: {:?}", b); println!("transpose then inverse: {:?}", at); let t = Tuple::point(1.0, 2.0, 3.0); let mut id = Matrix::identity(4); id[1][3] = -3.0; let q = &id * &t; println!("{:?}", id); println!("{:?}", q); } fn main() { before_clock(); clock(); } fn clock() { println!("Starting clock!"); let mut canvas = Canvas::new(1024, 1024); let color = Color::new(1.0, 0.0, 0.0); let middle = 1024.0 / 2.0; let three_fourths_middle = middle / 4.0 * 3.0; let center = &Tuple::point_zero() * &Matrix::translation(0.0, 1.0, 0.0); // canvas.write_pixel(center.x() as usize, center.y() as usize, color); canvas.write_pixel(middle as usize, middle as usize, Color::new(0.0, 1.0, 0.0)); for i in 1..13 { let twelve = Tuple::point_zero(); let twelve = &Matrix::translation(0.0, -12.0, 0.0) * &twelve; let twelve = &Matrix::scaling(0.0, 10.0, 0.0) * &twelve; let twelve = &Matrix::rotation_z((i as f32 / 12.0) * (2.0 * PI)) * &twelve; let twelve = &Matrix::translation(middle, middle, 0.0) * &twelve; println!("{}", twelve); canvas.write_pixel(twelve.x() as usize, twelve.y() as usize, color); } //for i in 0..=-1 { // let position = ((2.0 * PI) / 12.0) * (i as f32); // println!("i: {} pos: {}", i, position); // let transform = &(&(&Matrix::identity(4) // * &Matrix::translation(0.0, 1.0 , 0.0)) // * &Matrix::rotation_z(position)) // //* &Matrix::identity(4)) // * &Matrix::translation(middle, middle, 0.0); // let point = &Tuple::point_zero() * &(&transform * &Matrix::scaling(three_fourths_middle, three_fourths_middle, 0.0)); // //let point = &Tuple::point_zero() * &(&Matrix::translation(i as f32 * 6.0, 0.0, 0.0) * &Matrix::translation(middle, middle, 0.0)); // println!("point rotated: {}", &point); // canvas.write_pixel(point.x() as usize, point.y() as usize, color); //} write_canvas_to_file(canvas, "clock.ppm"); println!("Ending clock!"); }