summaryrefslogtreecommitdiff
path: root/src/ppm.rs
diff options
context:
space:
mode:
authoreug-vs <eugene@eug-vs.xyz>2024-12-12 15:23:01 +0100
committereug-vs <eugene@eug-vs.xyz>2024-12-12 18:14:54 +0100
commit783070635b568b44b6902bfdc01bdadf12b86bc8 (patch)
tree89718706dc37d02761bb30f9e0b15e7110cc4e7e /src/ppm.rs
parentecdafb45dd9c416cb0810d6687a20ac97e480ac9 (diff)
downloadparticle-physics-783070635b568b44b6902bfdc01bdadf12b86bc8.tar.gz
feat: implement constraint system and PPM rendering
Diffstat (limited to 'src/ppm.rs')
-rw-r--r--src/ppm.rs41
1 files changed, 41 insertions, 0 deletions
diff --git a/src/ppm.rs b/src/ppm.rs
new file mode 100644
index 0000000..01cdebb
--- /dev/null
+++ b/src/ppm.rs
@@ -0,0 +1,41 @@
+use std::{fs::File, io::Write, path::PathBuf};
+
+use crate::particle_system::{Particle, Vector, N, Scalar};
+
+pub struct PPM {
+ pub prefix: PathBuf,
+ pub width: usize,
+ pub height: usize,
+ // pixels_per_unit: usize,
+}
+
+impl PPM {
+ fn render_particles(&self, particles: &Vec<Particle>) -> String {
+ let mut s = format!("P3\n{} {}\n255\n", self.width, self.height);
+ let white = "255 255 255 ";
+ let black = "0 0 0 ";
+
+ for pixel_row in 0..self.height {
+ for pixel_col in 0..self.width {
+ let point = Vector::new(pixel_col as Scalar, (pixel_row as Scalar) * -1.0)
+ + Vector::new(self.width as Scalar / -2.0, self.height as Scalar / 2.0);
+ let color = match particles.iter().any(|p| {
+ (p.position - point).coords.norm() <= (p.mass).powf(1.0 / (N as f64))
+ }) {
+ true => black,
+ false => white,
+ };
+ s += color;
+ }
+ }
+ s
+ }
+
+ pub fn save_frame(&self, particles: &Vec<Particle>, 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 data = self.render_particles(particles);
+ file.write(data.as_bytes()).unwrap();
+ }
+}