diff --git a/src/grid.rs b/src/grid.rs index 2979f8a..dd350b8 100644 --- a/src/grid.rs +++ b/src/grid.rs @@ -76,8 +76,7 @@ impl PopulationConfig { } } -/// A 2D grid with a scalar value per each grid block. Each grid is occupied by a single population, -/// hence we store the population config inside the grid. +/// A 2D grid with a scalar value per each grid block. Each grid is occupied by a single population, hence we store the population config inside the grid. #[derive(Debug)] pub struct Grid { pub config: PopulationConfig, @@ -101,7 +100,6 @@ impl Clone for Grid { buf: self.buf.clone(), blur: self.blur.clone(), } - // return Grid::new(); } } @@ -132,8 +130,7 @@ impl Grid { j * self.width + i } - /// Get the buffer value at a given position. The implementation effectively treats data as - /// periodic, hence any finite position will produce a value. + /// Get the buffer value at a given position. The implementation effectively treats data as periodic, hence any finite position will produce a value. pub fn get_buf(&self, x: f32, y: f32) -> f32 { self.buf[self.index(x, y)] } @@ -181,8 +178,7 @@ where let datas: Vec<_> = grids.iter().map(|grid| &grid.data).collect(); let bufs: Vec<_> = grids.iter().map(|grid| &grid.buf).collect(); - // We mutate grid buffers and read grid data. We use unsafe because we need shared/unique - // borrows on different fields of the same Grid struct. + // We mutate grid buffers and read grid data. We use unsafe because we need shared/unique borrows on different fields of the same Grid struct. bufs.iter().enumerate().for_each(|(i, buf)| unsafe { let buf_ptr = *buf as *const Vec as *mut Vec; buf_ptr.as_mut().unwrap().fill(0.0); diff --git a/src/model.rs b/src/model.rs index 7f55f04..439a3a3 100644 --- a/src/model.rs +++ b/src/model.rs @@ -155,20 +155,9 @@ impl Model { } } - fn pick_direction(center: f32, left: f32, right: f32, rng: &mut R) -> f32 { - if (center > left) && (center > right) { - return 0.0; - } else if (center < left) && (center < right) { - return *[-1.0, 1.0].choose(rng).unwrap(); - } else if left < right { - return 1.0; - } else if right < left { - return -1.0; - } - return 0.0; - } /// Simulates `steps` # of steps + #[inline(always)] pub fn run(&mut self, steps: usize) { let debug: bool = false; @@ -189,7 +178,9 @@ impl Model { // Combine grids let grids = &mut self.grids; combine(grids, &self.attraction_table); + let agents_tick_time = Instant::now(); + self.agents.par_iter_mut().for_each(|agent| { // let i: usize = agent.i; @@ -214,15 +205,25 @@ impl Model { let xr = agent.x + agent_add_sens.cos() * sensor_distance; let yr = agent.y + agent_add_sens.sin() * sensor_distance; - // Sense. We sense from the buffer because this is where we previously combined data - // from all the grid. - let trail_c = grid.get_buf(xc, yc); - let trail_l = grid.get_buf(xl, yl); - let trail_r = grid.get_buf(xr, yr); + // 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 + // Rotate and move logic let mut rng = rand::thread_rng(); - let direction = Model::pick_direction(trail_c, trail_l, trail_r, &mut 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; + } + agent.rotate_and_move(direction, rotation_angle, step_distance, width, height); });