cargo fmt

This commit is contained in:
Simon Gardling 2025-03-24 16:27:11 -04:00
parent 3a9940dfba
commit f0d4e883f6
Signed by: titaniumtown
GPG Key ID: 9AB28AC10ECE533D
7 changed files with 313 additions and 86 deletions

View File

@ -1,11 +1,8 @@
use crate::{ use crate::{buffer::Buf, util::wrap};
util::wrap,
buffer::Buf,
};
use fastapprox::faster::{cos, sin};
use rand::{seq::SliceRandom, Rng}; use rand::{seq::SliceRandom, Rng};
use std::f32::consts::TAU; use std::f32::consts::TAU;
use fastapprox::faster::{cos, sin};
use std::fmt::{Display, Formatter}; use std::fmt::{Display, Formatter};
// A single Physarum agent. The x and y positions are continuous, hence we use floating point numbers instead of integers. // A single Physarum agent. The x and y positions are continuous, hence we use floating point numbers instead of integers.
@ -30,7 +27,13 @@ impl Display for Agent {
impl Agent { impl Agent {
// Construct a new agent with random parameters. // Construct a new agent with random parameters.
pub fn new<R: Rng + ?Sized>(width: usize, height: usize, id: usize, rng: &mut R, i: usize) -> Self { pub fn new<R: Rng + ?Sized>(
width: usize,
height: usize,
id: usize,
rng: &mut R,
i: usize,
) -> Self {
let (x, y, angle) = rng.gen::<(f32, f32, f32)>(); let (x, y, angle) = rng.gen::<(f32, f32, f32)>();
Agent { Agent {
x: x * width as f32, x: x * width as f32,
@ -43,7 +46,16 @@ impl Agent {
// Tick an agent // Tick an agent
#[inline] #[inline]
pub fn tick(&mut self, buf: &Buf, sensor_distance: f32, sensor_angle: f32, rotation_angle: f32, step_distance: f32, width: usize, height: usize) { pub fn tick(
&mut self,
buf: &Buf,
sensor_distance: f32,
sensor_angle: f32,
rotation_angle: f32,
step_distance: f32,
width: usize,
height: usize,
) {
let xc = self.x + cos(self.angle) * sensor_distance; let xc = self.x + cos(self.angle) * sensor_distance;
let yc = self.y + sin(self.angle) * sensor_distance; let yc = self.y + sin(self.angle) * sensor_distance;
@ -77,14 +89,8 @@ impl Agent {
let delta_angle = rotation_angle * direction; let delta_angle = rotation_angle * direction;
self.angle = wrap(self.angle + delta_angle, TAU); self.angle = wrap(self.angle + delta_angle, TAU);
self.x = wrap( self.x = wrap(self.x + step_distance * cos(self.angle), width as f32);
self.x + step_distance * cos(self.angle), self.y = wrap(self.y + step_distance * sin(self.angle), height as f32);
width as f32,
);
self.y = wrap(
self.y + step_distance * sin(self.angle),
height as f32,
);
} }
} }
@ -108,4 +114,4 @@ impl PartialEq for Agent {
&& self.population_id == other.population_id && self.population_id == other.population_id
&& self.i == other.i && self.i == other.i
} }
} }

View File

@ -148,15 +148,69 @@ mod tests {
// ndimage.uniform_filter(a, size=3, mode='wrap') # 2D blur // ndimage.uniform_filter(a, size=3, mode='wrap') # 2D blur
let mut src: Vec<f32> = vec![ let mut src: Vec<f32> = vec![
0.32352856, 0.06571674, 0.01939427, 0.06352045, 0.708_527, 0.617_221_7, 0.16638431, 0.32352856,
0.628_400_74, 0.554_893_9, 0.240_076_77, 0.325_009_94, 0.08515139, 0.679_840_9, 0.6975669, 0.06571674,
0.736_234_25, 0.55053085, 0.692_227_66, 0.22727048, 0.13594262, 0.10002105, 0.16099514, 0.01939427,
0.07719103, 0.23984282, 0.9083058, 0.642_227_4, 0.968_934_2, 0.74662715, 0.715_620_1, 0.06352045,
0.736_546_5, 0.70610344, 0.221_011_18, 0.755_721_87, 0.691_958_84, 0.837_414, 0.27583158, 0.708_527,
0.572_570_5, 0.681_606, 0.392_373_38, 0.33524343, 0.893_968_34, 0.602_969_35, 0.171_301_13, 0.617_221_7,
0.1733834, 0.771_278_2, 0.99537134, 0.915_049_6, 0.493_121_1, 0.430_352_03, 0.70297265, 0.16638431,
0.367_341_8, 0.4551964, 0.471_043_14, 0.603_747_8, 0.738_726_85, 0.5630592, 0.974_402_25, 0.628_400_74,
0.633_682_85, 0.841_092_94, 0.24447136, 0.750384, 0.16893725, 0.542_256_65, 0.435_607_82, 0.554_893_9,
0.240_076_77,
0.325_009_94,
0.08515139,
0.679_840_9,
0.6975669,
0.736_234_25,
0.55053085,
0.692_227_66,
0.22727048,
0.13594262,
0.10002105,
0.16099514,
0.07719103,
0.23984282,
0.9083058,
0.642_227_4,
0.968_934_2,
0.74662715,
0.715_620_1,
0.736_546_5,
0.70610344,
0.221_011_18,
0.755_721_87,
0.691_958_84,
0.837_414,
0.27583158,
0.572_570_5,
0.681_606,
0.392_373_38,
0.33524343,
0.893_968_34,
0.602_969_35,
0.171_301_13,
0.1733834,
0.771_278_2,
0.99537134,
0.915_049_6,
0.493_121_1,
0.430_352_03,
0.70297265,
0.367_341_8,
0.4551964,
0.471_043_14,
0.603_747_8,
0.738_726_85,
0.5630592,
0.974_402_25,
0.633_682_85,
0.841_092_94,
0.24447136,
0.750384,
0.16893725,
0.542_256_65,
0.435_607_82,
0.414_971_23, 0.414_971_23,
]; ];
let (width, height) = (8, 8); let (width, height) = (8, 8);
@ -165,15 +219,69 @@ mod tests {
blur.box_blur_h(&src, &mut dst, width, 1); blur.box_blur_h(&src, &mut dst, width, 1);
let mut sol: Vec<f32> = vec![ let mut sol: Vec<f32> = vec![
0.339_215_37, 0.136_213_18, 0.04954382, 0.263_813_9, 0.46308973, 0.497_377_7, 0.470_668_94, 0.339_215_37,
0.372_771_2, 0.448_500_5, 0.373_326_87, 0.21674603, 0.363_334_1, 0.48751974, 0.70454735, 0.136_213_18,
0.661_444, 0.613_886_36, 0.609_268, 0.351_813_58, 0.15441138, 0.1323196, 0.11273574, 0.04954382,
0.159343, 0.40844655, 0.613_458_75, 0.788_961_2, 0.785_929_56, 0.810_393_8, 0.732_931_26, 0.263_813_9,
0.719_423_35, 0.554_553_7, 0.560_945_5, 0.539_653_5, 0.807_780_4, 0.601_734_8, 0.561_938_7, 0.46308973,
0.510_002_7, 0.548_849_94, 0.46974093, 0.540_528_4, 0.640_390_2, 0.40154082, 0.315_884_62, 0.497_377_7,
0.371_987_58, 0.646_677_6, 0.893_899_74, 0.801_180_66, 0.612_840_9, 0.508_814_16, 0.681_572_2, 0.470_668_94,
0.508_503_6, 0.431_193_77, 0.509_995_76, 0.604_505_9, 0.635_177_9, 0.758_729_4, 0.746_811_33, 0.372_771_2,
0.629_915_65, 0.573_082_4, 0.611_982_76, 0.38793087, 0.48719263, 0.38226724, 0.464_278_58, 0.448_500_5,
0.373_326_87,
0.21674603,
0.363_334_1,
0.48751974,
0.70454735,
0.661_444,
0.613_886_36,
0.609_268,
0.351_813_58,
0.15441138,
0.1323196,
0.11273574,
0.159343,
0.40844655,
0.613_458_75,
0.788_961_2,
0.785_929_56,
0.810_393_8,
0.732_931_26,
0.719_423_35,
0.554_553_7,
0.560_945_5,
0.539_653_5,
0.807_780_4,
0.601_734_8,
0.561_938_7,
0.510_002_7,
0.548_849_94,
0.46974093,
0.540_528_4,
0.640_390_2,
0.40154082,
0.315_884_62,
0.371_987_58,
0.646_677_6,
0.893_899_74,
0.801_180_66,
0.612_840_9,
0.508_814_16,
0.681_572_2,
0.508_503_6,
0.431_193_77,
0.509_995_76,
0.604_505_9,
0.635_177_9,
0.758_729_4,
0.746_811_33,
0.629_915_65,
0.573_082_4,
0.611_982_76,
0.38793087,
0.48719263,
0.38226724,
0.464_278_58,
0.494_753_96, 0.494_753_96,
]; ];
for (v1, v2) in dst.iter().zip(sol) { for (v1, v2) in dst.iter().zip(sol) {
@ -182,15 +290,69 @@ mod tests {
blur.box_blur_v(&src, &mut dst, width, height, 1, 1.0); blur.box_blur_v(&src, &mut dst, width, height, 1, 1.0);
sol = vec![ sol = vec![
0.504_035_1, 0.382_295_5, 0.19629186, 0.299_685_27, 0.519_101_74, 0.619_015_1, 0.446_075_47, 0.504_035_1,
0.531_300_96, 0.523_550_03, 0.177688, 0.16011561, 0.08289763, 0.516_454_34, 0.46399322, 0.382_295_5,
0.38082045, 0.695_745_8, 0.629_783_03, 0.47876048, 0.402_526_56, 0.300_264_18, 0.5257942, 0.19629186,
0.49362046, 0.3990294, 0.738_186_2, 0.675_471_3, 0.677_872_9, 0.386_133_8, 0.46273723, 0.299_685_27,
0.526_382_57, 0.391_889_3, 0.265_365_8, 0.852_665_36, 0.645_718_5, 0.659_216_46, 0.39861405, 0.519_101_74,
0.686_489_6, 0.804_508, 0.671_175_5, 0.349_791_88, 0.693_347_4, 0.665_966_9, 0.458_685_64, 0.619_015_1,
0.30147046, 0.604_963_96, 0.760_241_7, 0.682_05, 0.463_807_9, 0.766_240_9, 0.6465416, 0.446_075_47,
0.459_911_97, 0.291_017_06, 0.664_235_1, 0.589_352_13, 0.732_011, 0.497_262_72, 0.606_575_13, 0.531_300_96,
0.553_394_7, 0.42471716, 0.23968734, 0.428_315_88, 0.493_737_34, 0.632_735_1, 0.388_350_46, 0.523_550_03,
0.177688,
0.16011561,
0.08289763,
0.516_454_34,
0.46399322,
0.38082045,
0.695_745_8,
0.629_783_03,
0.47876048,
0.402_526_56,
0.300_264_18,
0.5257942,
0.49362046,
0.3990294,
0.738_186_2,
0.675_471_3,
0.677_872_9,
0.386_133_8,
0.46273723,
0.526_382_57,
0.391_889_3,
0.265_365_8,
0.852_665_36,
0.645_718_5,
0.659_216_46,
0.39861405,
0.686_489_6,
0.804_508,
0.671_175_5,
0.349_791_88,
0.693_347_4,
0.665_966_9,
0.458_685_64,
0.30147046,
0.604_963_96,
0.760_241_7,
0.682_05,
0.463_807_9,
0.766_240_9,
0.6465416,
0.459_911_97,
0.291_017_06,
0.664_235_1,
0.589_352_13,
0.732_011,
0.497_262_72,
0.606_575_13,
0.553_394_7,
0.42471716,
0.23968734,
0.428_315_88,
0.493_737_34,
0.632_735_1,
0.388_350_46,
0.672_591_45, 0.672_591_45,
]; ];
for (v1, v2) in dst.iter().zip(sol) { for (v1, v2) in dst.iter().zip(sol) {
@ -199,15 +361,69 @@ mod tests {
blur.box_blur(&mut src, &mut dst, width, height, 1, 1.0); blur.box_blur(&mut src, &mut dst, width, height, 1, 1.0);
sol = vec![ sol = vec![
0.472_543_84, 0.36087415, 0.29275754, 0.338_359_62, 0.47926736, 0.528_064_1, 0.5321305, 0.472_543_84,
0.493_803_83, 0.465_661_3, 0.287_117_9, 0.140_233_76, 0.253_155_86, 0.3544484, 0.453_756, 0.36087415,
0.513_519_8, 0.5333721, 0.615_576_57, 0.503_69, 0.393_850_42, 0.40952832, 0.43989295, 0.29275754,
0.472_814_68, 0.543_612, 0.588_999_5, 0.735_336_54, 0.579826, 0.508_914_65, 0.458_417_86, 0.338_359_62,
0.460_336_36, 0.39454588, 0.503_306_8, 0.597_834_17, 0.666_094_1, 0.567_849_7, 0.581_440_03, 0.47926736,
0.62987053, 0.720_724_34, 0.608_491_8, 0.571_438_25, 0.562_952_64, 0.630_297_84, 0.475_374_34, 0.528_064_1,
0.455_04, 0.5555587, 0.682_418_5, 0.635_366_5, 0.63736624, 0.632_005_2, 0.571_009_6, 0.5321305,
0.465_823_53, 0.471_721_38, 0.5148681, 0.661_866_07, 0.606_208_6, 0.611_949_6, 0.583_459_8, 0.493_803_83,
0.550_234_44, 0.405_933_05, 0.364_240_14, 0.38724685, 0.518_262_74, 0.504_940_9, 0.564_559, 0.465_661_3,
0.287_117_9,
0.140_233_76,
0.253_155_86,
0.3544484,
0.453_756,
0.513_519_8,
0.5333721,
0.615_576_57,
0.503_69,
0.393_850_42,
0.40952832,
0.43989295,
0.472_814_68,
0.543_612,
0.588_999_5,
0.735_336_54,
0.579826,
0.508_914_65,
0.458_417_86,
0.460_336_36,
0.39454588,
0.503_306_8,
0.597_834_17,
0.666_094_1,
0.567_849_7,
0.581_440_03,
0.62987053,
0.720_724_34,
0.608_491_8,
0.571_438_25,
0.562_952_64,
0.630_297_84,
0.475_374_34,
0.455_04,
0.5555587,
0.682_418_5,
0.635_366_5,
0.63736624,
0.632_005_2,
0.571_009_6,
0.465_823_53,
0.471_721_38,
0.5148681,
0.661_866_07,
0.606_208_6,
0.611_949_6,
0.583_459_8,
0.550_234_44,
0.405_933_05,
0.364_240_14,
0.38724685,
0.518_262_74,
0.504_940_9,
0.564_559,
0.538_112_16, 0.538_112_16,
]; ];
for (v1, v2) in src.iter().zip(sol) { for (v1, v2) in src.iter().zip(sol) {

View File

@ -17,11 +17,7 @@ impl Clone for Buf {
impl Buf { impl Buf {
pub fn new(width: usize, height: usize, buf: Vec<f32>) -> Self { pub fn new(width: usize, height: usize, buf: Vec<f32>) -> Self {
Buf { Buf { width, height, buf }
width,
height,
buf,
}
} }
// Truncate x and y and return a corresponding index into the data slice. // Truncate x and y and return a corresponding index into the data slice.
@ -36,4 +32,4 @@ impl Buf {
pub fn get_buf(&self, x: f32, y: f32) -> f32 { pub fn get_buf(&self, x: f32, y: f32) -> f32 {
self.buf[self.index(x, y)] self.buf[self.index(x, y)]
} }
} }

View File

@ -1,12 +1,8 @@
use crate::{ use crate::{agent::Agent, blur::Blur, buffer::Buf};
blur::Blur,
agent::Agent,
buffer::Buf,
};
use rand::{distributions::Uniform, Rng}; use rand::{distributions::Uniform, Rng};
use std::fmt::{Display, Formatter};
use rayon::{iter::ParallelIterator, prelude::*}; use rayon::{iter::ParallelIterator, prelude::*};
use std::fmt::{Display, Formatter};
// A population configuration. // A population configuration.
#[derive(Debug)] #[derive(Debug)]
@ -93,7 +89,7 @@ pub struct Grid {
// pub buf: Vec<f32>, // pub buf: Vec<f32>,
pub buf: Buf, pub buf: Buf,
pub blur: Blur, pub blur: Blur,
pub agents: Vec<Agent> pub agents: Vec<Agent>,
} }
impl Clone for Grid { impl Clone for Grid {
@ -112,7 +108,12 @@ impl Clone for Grid {
impl Grid { impl Grid {
// Create a new grid filled with random floats in the [0.0..1.0) range. // Create a new grid filled with random floats in the [0.0..1.0) range.
pub fn new<R: Rng + ?Sized>(width: usize, height: usize, rng: &mut R, agents: Vec<Agent>) -> Self { pub fn new<R: Rng + ?Sized>(
width: usize,
height: usize,
rng: &mut R,
agents: Vec<Agent>,
) -> Self {
if !width.is_power_of_two() || !height.is_power_of_two() { if !width.is_power_of_two() || !height.is_power_of_two() {
panic!("Grid dimensions must be a power of two."); panic!("Grid dimensions must be a power of two.");
} }
@ -177,10 +178,15 @@ impl Grid {
let buf = self.buf.clone(); let buf = self.buf.clone();
self.agents.par_iter_mut().for_each(|agent| { self.agents.par_iter_mut().for_each(|agent| {
agent.tick(&buf, agent.tick(
sensor_distance, sensor_angle, &buf,
rotation_angle, step_distance, sensor_distance,
width, height); sensor_angle,
rotation_angle,
step_distance,
width,
height,
);
}); });
self.deposit_all(); self.deposit_all();
} }

View File

@ -9,7 +9,6 @@ pub struct ThinGridData {
pub data: Vec<f32>, pub data: Vec<f32>,
} }
impl Clone for ThinGridData { impl Clone for ThinGridData {
fn clone(&self) -> ThinGridData { fn clone(&self) -> ThinGridData {
ThinGridData { ThinGridData {
@ -32,9 +31,10 @@ impl ThinGridData {
#[allow(dead_code)] #[allow(dead_code)]
pub fn new_from_grid_vec(in_grids: Vec<Grid>) -> Vec<Self> { pub fn new_from_grid_vec(in_grids: Vec<Grid>) -> Vec<Self> {
in_grids.iter().map(|grid|{ in_grids
Self::new_from_grid(grid) .iter()
}).collect() .map(|grid| Self::new_from_grid(grid))
.collect()
} }
// from grid.rs (needed in image gen) // from grid.rs (needed in image gen)
@ -109,13 +109,13 @@ impl ImgData {
pub fn save_to_image(&self) { pub fn save_to_image(&self) {
let (width, height) = (self.grids[0].width, self.grids[0].height); let (width, height) = (self.grids[0].width, self.grids[0].height);
let mut img = image::RgbImage::new(width as u32, height as u32); let mut img = image::RgbImage::new(width as u32, height as u32);
let max_values: Vec<_> = self let max_values: Vec<_> = self
.grids .grids
.iter() .iter()
.map(|grid| grid.quantile(0.999) * 1.5) .map(|grid| grid.quantile(0.999) * 1.5)
.collect(); .collect();
for y in 0..height { for y in 0..height {
for x in 0..width { for x in 0..width {
let i = y * width + x; let i = y * width + x;
@ -135,7 +135,7 @@ impl ImgData {
img.put_pixel(x as u32, y as u32, image::Rgb([r as u8, g as u8, b as u8])); img.put_pixel(x as u32, y as u32, image::Rgb([r as u8, g as u8, b as u8]));
} }
} }
img.save(format!("./tmp/out_{}.png", self.iteration).as_str()) img.save(format!("./tmp/out_{}.png", self.iteration).as_str())
.unwrap(); .unwrap();
} }

View File

@ -1,8 +1,8 @@
mod agent;
mod blur; mod blur;
mod buffer;
mod grid; mod grid;
mod imgdata; // for storing image data mod imgdata; // for storing image data
pub mod model; pub mod model;
mod palette; mod palette;
mod util; // for math things mod util; // for math things
mod agent;
mod buffer;

View File

@ -1,8 +1,8 @@
use crate::{ use crate::{
agent::Agent,
grid::{combine, Grid}, grid::{combine, Grid},
imgdata::{ImgData, ThinGridData}, imgdata::{ImgData, ThinGridData},
palette::{random_palette, Palette}, palette::{random_palette, Palette},
agent::Agent,
}; };
use indicatif::{ParallelProgressIterator, ProgressBar, ProgressStyle}; use indicatif::{ParallelProgressIterator, ProgressBar, ProgressStyle};
@ -78,9 +78,8 @@ impl Model {
let mut grids: Vec<Grid> = Vec::new(); let mut grids: Vec<Grid> = Vec::new();
for pop in 0..n_populations { for pop in 0..n_populations {
let agents = (0..particles_per_grid) let agents = (0..particles_per_grid)
.map(|i| { .map(|i| Agent::new(width, height, pop, &mut rng, i))
Agent::new(width, height, pop, &mut rng, i) .collect();
}).collect();
grids.push(Grid::new(width, height, &mut rng, agents)); grids.push(Grid::new(width, height, &mut rng, agents));
} }
@ -123,7 +122,7 @@ impl Model {
let agents_tick_time = Instant::now(); let agents_tick_time = Instant::now();
// Tick agents // Tick agents
let diffusivity = self.diffusivity; let diffusivity = self.diffusivity;
self.grids.par_iter_mut().for_each(|grid| { self.grids.par_iter_mut().for_each(|grid| {
grid.tick(); grid.tick();
grid.diffuse(diffusivity); // Diffuse + Decay grid.diffuse(diffusivity); // Diffuse + Decay
@ -167,12 +166,16 @@ impl Model {
let img_data = ImgData::new(grids, self.palette, self.iteration); let img_data = ImgData::new(grids, self.palette, self.iteration);
self.img_data_vec.push(img_data); self.img_data_vec.push(img_data);
let size: usize = self.size_of_imgdata_vec(); let size: usize = self.size_of_imgdata_vec();
let mb = size/1024/1024; let mb = size / 1024 / 1024;
// println!("{} B | {} KB | {} MB", size, size/1024, size/1024/1024); // println!("{} B | {} KB | {} MB", size, size/1024, size/1024/1024);
let max_mb = 6000; let max_mb = 6000;
if mb >= max_mb { if mb >= max_mb {
println!("ram usage is over {} MB (and len of {}), flushing to disk\n", max_mb, self.img_data_vec.len()); println!(
"ram usage is over {} MB (and len of {}), flushing to disk\n",
max_mb,
self.img_data_vec.len()
);
self.render_all_imgdata(); self.render_all_imgdata();
self.flush_image_data(); self.flush_image_data();
} }