diff options
author | eug-vs <eugene@eug-vs.xyz> | 2024-12-15 13:17:43 +0100 |
---|---|---|
committer | eug-vs <eugene@eug-vs.xyz> | 2024-12-15 13:17:43 +0100 |
commit | 70afc5a7d871919776a64782e8b93404e6b0defd (patch) | |
tree | c3d8a273bddf4cbc3c55d06c751766b93b961a1f /physics/src/ppm.rs | |
parent | 297efa5127e83bea57132c503680dd348a725db5 (diff) | |
download | particle-physics-70afc5a7d871919776a64782e8b93404e6b0defd.tar.gz |
feat!: add raylib rendering
Diffstat (limited to 'physics/src/ppm.rs')
-rw-r--r-- | physics/src/ppm.rs | 67 |
1 files changed, 67 insertions, 0 deletions
diff --git a/physics/src/ppm.rs b/physics/src/ppm.rs new file mode 100644 index 0000000..be26127 --- /dev/null +++ b/physics/src/ppm.rs @@ -0,0 +1,67 @@ +use std::{fs::File, io::Write, path::PathBuf}; + +use nalgebra::Point2; +use crate::algebra::{Scalar, N}; +use crate::renderer::Camera; +use crate::particle_system::Particle; + +pub struct PPM<const WIDTH: usize, const HEIGHT: usize> { + pub prefix: PathBuf, + + buffer: [[bool; WIDTH]; HEIGHT], + // pixels_per_unit: usize, +} + +impl<const WIDTH: usize, const HEIGHT: usize> PPM<WIDTH, HEIGHT> { + pub fn new(prefix: PathBuf) -> Self { + Self { + prefix, + buffer: [[false; WIDTH]; HEIGHT], + } + } + + pub fn clear_buffer(&mut self) { + self.buffer = [[false; WIDTH]; HEIGHT] + } + + pub fn draw_circle(&mut self, center: Point2<Scalar>, radius: Scalar) { + let screen_center = Point2::new((WIDTH / 2) as Scalar, (HEIGHT / 2) as Scalar); + + for pixel_row in 0..HEIGHT { + for pixel_col in 0..WIDTH { + let point = Point2::new(pixel_col as Scalar, pixel_row as Scalar); + + if (point - center - screen_center.coords).norm() <= radius { + self.buffer[HEIGHT - pixel_row - 1][pixel_col] = true + } + } + } + } + + pub fn render_particles(&mut self, particles: &Vec<Particle>, camera: &Camera) { + for p in particles { + let point = camera.world_to_screen_space(p.position); + self.draw_circle(point, p.mass.powf(1.0 / N as Scalar)); + } + } + + pub fn save_frame(&self, time: Scalar) { + let file_name = format!("frame-{:08.3}", time); + let path = self.prefix.join(file_name); + let mut file = File::create(path).unwrap(); + + let mut s = format!("P3\n{} {}\n255\n", WIDTH, HEIGHT); + let white = "255 255 255 "; + let black = "0 0 0 "; + + for row in self.buffer { + for pixel in row { + let color = if pixel { black } else { white }; + s += color + } + s += "\n"; + } + + file.write(s.as_bytes()).unwrap(); + } +} |