diff --git a/src/agent.rs b/src/agent.rs index fe038cc..53879ad 100644 --- a/src/agent.rs +++ b/src/agent.rs @@ -41,19 +41,44 @@ impl Agent { } } + pub fn get_from_table(i: f32, table: &Vec) -> f32 { + let interval: f32 = 1.0/0.01; + + let i_proc = (i * interval).round()+(360.0*interval); + let output = table[i_proc as usize]; + + return output; + } + // Tick an agent #[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, sin_table: &Vec, cos_table: &Vec) { + /* let xc = self.x + cos(self.angle) * sensor_distance; let yc = self.y + sin(self.angle) * sensor_distance; + */ + + // /* + let xc = self.x + Self::get_from_table(self.angle, &cos_table) * sensor_distance; + let yc = self.y + Self::get_from_table(self.angle, &sin_table) * sensor_distance; + // */ let agent_add_sens = self.angle + sensor_angle; let agent_sub_sens = self.angle - sensor_angle; + // /* + let xl = self.x + Self::get_from_table(agent_sub_sens, &cos_table) * sensor_distance; + let yl = self.y + Self::get_from_table(agent_sub_sens, &sin_table) * sensor_distance; + let xr = self.x + Self::get_from_table(agent_add_sens, &cos_table) * sensor_distance; + let yr = self.y + Self::get_from_table(agent_add_sens, &sin_table) * sensor_distance; + // */ + + /* let xl = self.x + cos(agent_sub_sens) * sensor_distance; let yl = self.y + sin(agent_sub_sens) * sensor_distance; let xr = self.x + cos(agent_add_sens) * sensor_distance; let yr = self.y + 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 = buf.get_buf(xc, yc); @@ -78,11 +103,13 @@ impl Agent { self.angle = wrap(self.angle + delta_angle, TAU); self.x = wrap( - self.x + step_distance * cos(self.angle), + // self.x + step_distance * cos(self.angle), + self.x + step_distance * Self::get_from_table(self.angle, &cos_table), width as f32, ); self.y = wrap( - self.y + step_distance * sin(self.angle), + // self.y + step_distance * sin(self.angle), + self.y + step_distance * Self::get_from_table(self.angle, &sin_table), height as f32, ); } diff --git a/src/grid.rs b/src/grid.rs index 8955f55..ae28baa 100644 --- a/src/grid.rs +++ b/src/grid.rs @@ -164,7 +164,7 @@ impl Grid { } #[inline] - pub fn tick(&mut self) { + pub fn tick(&mut self, sin_table: Vec, cos_table: Vec) { let (width, height) = (self.width, self.height); let PopulationConfig { sensor_distance, @@ -180,7 +180,7 @@ impl Grid { agent.tick(&buf, sensor_distance, sensor_angle, rotation_angle, step_distance, - width, height); + width, height, &sin_table, &cos_table); }); self.deposit_all(); } diff --git a/src/main.rs b/src/main.rs index b813140..c4319b5 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,14 +2,14 @@ use physarum::model; fn main() { // # of iterations to go through - let n_iterations = 1024; + let n_iterations = 128; // let n_iterations = 2048; // let n_iterations = 1 << 14; // Size of grid and pictures - // let (width, height) = (256, 256); + let (width, height) = (256, 256); // let (width, height) = (512, 512); - let (width, height) = (1024, 1024); + // let (width, height) = (1024, 1024); // # of agents // let n_particles = 1 << 10; diff --git a/src/model.rs b/src/model.rs index 862f74e..042ba6c 100644 --- a/src/model.rs +++ b/src/model.rs @@ -10,6 +10,7 @@ use indicatif::{ParallelProgressIterator, ProgressBar, ProgressStyle}; use rand_distr::{Distribution, Normal}; use rayon::{iter::ParallelIterator, prelude::*}; use std::{path::Path, time::Instant}; +use fastapprox::faster::{cos, sin}; // Top-level simulation class. pub struct Model { @@ -94,6 +95,32 @@ impl Model { } } + pub fn gen_table(opt: i32) -> Vec { + let mut output: Vec = Vec::new(); + + let max: f32 = 360.0; + let min: f32 = -360.0; + let interval: f32 = 0.01; + + + let mut i: f32; + let mut tmp: f32 = 0.0; + for i1 in ((min/interval)as i32)..((max/interval)as i32) { + i = (i1 as f32)*interval; + if opt == 0 { + tmp = sin(i); + } else if opt == 1 { + tmp = cos(i); + } + output.push(tmp); + + } + println!("{}", output.len()); + + return output; + } + + // Simulates `steps` # of steps #[inline] pub fn run(&mut self, steps: usize) { @@ -112,6 +139,10 @@ impl Model { let mut time_per_step_list: Vec = Vec::new(); let agents_num: usize = self.grids.iter().map(|grid| grid.agents.len()).sum(); + let sin_table1 = Self::gen_table(0); + let cos_table1 = Self::gen_table(1); + let sin_table = sin_table1.clone(); + let cos_table = cos_table1.clone(); for i in 0..steps { if debug { println!("Starting tick for all agents...") @@ -125,7 +156,7 @@ impl Model { // Tick agents let diffusivity = self.diffusivity; self.grids.par_iter_mut().for_each(|grid| { - grid.tick(); + grid.tick(sin_table.clone(), cos_table.clone()); grid.diffuse(diffusivity); // Diffuse + Decay });