summaryrefslogtreecommitdiff
path: root/physics/src/ppm.rs
diff options
context:
space:
mode:
authoreug-vs <eugene@eug-vs.xyz>2024-12-15 13:17:43 +0100
committereug-vs <eugene@eug-vs.xyz>2024-12-15 13:17:43 +0100
commit70afc5a7d871919776a64782e8b93404e6b0defd (patch)
treec3d8a273bddf4cbc3c55d06c751766b93b961a1f /physics/src/ppm.rs
parent297efa5127e83bea57132c503680dd348a725db5 (diff)
downloadparticle-physics-70afc5a7d871919776a64782e8b93404e6b0defd.tar.gz
feat!: add raylib rendering
Diffstat (limited to 'physics/src/ppm.rs')
-rw-r--r--physics/src/ppm.rs67
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();
+ }
+}