restructuring

This commit is contained in:
Simon Gardling
2021-04-01 10:33:05 -04:00
parent f8b16c720b
commit 41ba5f248c
6 changed files with 231 additions and 122 deletions

View File

@@ -1,122 +1,18 @@
use crate::{
grid::{combine, Grid, PopulationConfig},
imgdata::ImgData,
grid::{combine, Grid},
imgdata::{ImgData, ThinGridData},
palette::{random_palette, Palette},
util::wrap,
agent::Agent,
};
use indicatif::{ParallelProgressIterator, ProgressBar, ProgressStyle};
use itertools::multizip;
use rand::{seq::SliceRandom, Rng};
// use rand::Rng;
use rand_distr::{Distribution, Normal};
use rayon::{iter::ParallelIterator, prelude::*};
use std::{f32::consts::TAU, path::Path, time::Instant};
// A single Physarum agent. The x and y positions are continuous, hence we use floating point numbers instead of integers.
#[derive(Debug)]
pub struct Agent {
x: f32,
y: f32,
angle: f32,
population_id: usize,
i: usize,
}
impl Agent {
// Construct a new agent with random parameters.
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)>();
Agent {
x: x * width as f32,
y: y * height as f32,
angle: angle * TAU,
population_id: id,
i,
}
}
#[inline]
pub fn tick(&mut self, grid: &Grid) {
let (width, height) = (grid.width, grid.height);
let PopulationConfig {
sensor_distance,
sensor_angle,
rotation_angle,
step_distance,
..
} = grid.config;
let xc = self.x + fastapprox::faster::cos(self.angle) * sensor_distance;
let yc = self.y + fastapprox::faster::sin(self.angle) * sensor_distance;
let agent_add_sens = self.angle + sensor_angle;
let agent_sub_sens = self.angle - sensor_angle;
let xl = self.x + fastapprox::faster::cos(agent_sub_sens) * sensor_distance;
let yl = self.y + fastapprox::faster::sin(agent_sub_sens) * sensor_distance;
let xr = self.x + fastapprox::faster::cos(agent_add_sens) * sensor_distance;
let yr = self.y + fastapprox::faster::sin(agent_add_sens) * sensor_distance;
// We sense from the buffer because this is where we previously combined data from all the grid.
let center = grid.get_buf(xc, yc);
let left = grid.get_buf(xl, yl);
let right = grid.get_buf(xr, yr);
// Rotate and move logic
let mut rng = rand::thread_rng();
let mut direction: f32 = 0.0;
if (center > left) && (center > right) {
direction = 0.0;
} else if (center < left) && (center < right) {
direction = *[-1.0, 1.0].choose(&mut rng).unwrap();
} else if left < right {
direction = 1.0;
} else if right < left {
direction = -1.0;
}
let delta_angle = rotation_angle * direction;
self.angle = wrap(self.angle + delta_angle, TAU);
self.x = wrap(
self.x + step_distance * fastapprox::faster::cos(self.angle),
width as f32,
);
self.y = wrap(
self.y + step_distance * fastapprox::faster::sin(self.angle),
height as f32,
);
}
}
impl Clone for Agent {
fn clone(&self) -> Agent {
Agent {
x: self.x,
y: self.y,
angle: self.angle,
population_id: self.population_id,
i: self.i,
}
}
}
impl PartialEq for Agent {
fn eq(&self, other: &Self) -> bool {
self.x == other.x
&& self.y == other.y
&& self.angle == other.angle
&& self.population_id == other.population_id
&& self.i == other.i
}
}
use std::{path::Path, time::Instant};
// Top-level simulation class.
pub struct Model {
// Physarum agents.
// agents: Vec<Agent>,
// The grid they move on.
grids: Vec<Grid>,
@@ -276,8 +172,14 @@ impl Model {
);
}
fn strip_grid_data(grids: Vec<Grid>) -> Vec<ThinGridData> {
return grids.iter().map(|grid| {
return ThinGridData::from_grid(grid);
}).collect();
}
fn save_image_data(&mut self) {
let grids = self.grids.clone();
let grids = Self::strip_grid_data(self.grids.clone());
let img_data = ImgData::new(grids, self.palette, self.iteration);
self.img_data_vec.push(img_data);
if self.grids[0].width > 1024 && self.grids[0].height > 1024 && self.img_data_vec.len() > 100 {
@@ -312,10 +214,12 @@ impl Model {
.par_iter()
.progress_with(pb)
.for_each(|img| {
Self::save_to_image(img.to_owned());
// Self::save_to_image(img.to_owned());
img.save_to_image();
});
}
/*
pub fn save_to_image(imgdata: ImgData) {
let (width, height) = (imgdata.grids[0].width, imgdata.grids[0].height);
let mut img = image::RgbImage::new(width as u32, height as u32);
@@ -349,4 +253,5 @@ impl Model {
img.save(format!("./tmp/out_{}.png", imgdata.iteration).as_str())
.unwrap();
}
*/
}