195 lines
5.5 KiB
Rust
195 lines
5.5 KiB
Rust
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!");
|
|
}
|