Add trail deposition, diffusion and decay.
This commit is contained in:
parent
cf35e041dd
commit
51f10723ed
15
src/blur.rs
15
src/blur.rs
@ -32,8 +32,7 @@ impl Blur {
|
||||
fn boxes_for_gaussian<const N: usize>(sigma: f32) -> ([usize; N]) {
|
||||
let w_ideal = (12.0 * sigma * sigma / N as f32 + 1.0).sqrt();
|
||||
let mut w = w_ideal as usize;
|
||||
w -= 1 - w & 1;
|
||||
|
||||
w -= 1 - (w & 1);
|
||||
let mut m = 0.25 * (N * (w + 3)) as f32;
|
||||
m -= 3.0 * sigma * sigma / (w + 1) as f32;
|
||||
let m = m.round() as usize;
|
||||
@ -145,4 +144,16 @@ mod tests {
|
||||
]
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_boxes_for_gaussian() {
|
||||
let boxes = Blur::boxes_for_gaussian::<3>(1.5);
|
||||
assert_eq!(boxes, [1, 1, 1]);
|
||||
|
||||
let boxes = Blur::boxes_for_gaussian::<3>(1.8);
|
||||
assert_eq!(boxes, [1, 1, 2]);
|
||||
|
||||
let boxes = Blur::boxes_for_gaussian::<3>(2.5);
|
||||
assert_eq!(boxes, [2, 2, 2]);
|
||||
}
|
||||
}
|
||||
|
||||
@ -17,8 +17,7 @@ pub struct Grid {
|
||||
impl Grid {
|
||||
/// Create a new grid filled with random floats in the [0.0..1.0) range.
|
||||
pub fn new(width: usize, height: usize) -> Self {
|
||||
use crate::util::is_power_of_two;
|
||||
if !is_power_of_two(width) || !is_power_of_two(height) {
|
||||
if !width.is_power_of_two() || !height.is_power_of_two() {
|
||||
panic!("Grid dimensitions must be a power of two.");
|
||||
}
|
||||
let rng = rand::thread_rng();
|
||||
|
||||
15
src/model.rs
15
src/model.rs
@ -1,6 +1,6 @@
|
||||
use crate::grid::Grid;
|
||||
|
||||
use rand::{seq::SliceRandom, thread_rng, Rng};
|
||||
use rand::{seq::SliceRandom, Rng};
|
||||
use rayon::prelude::*;
|
||||
|
||||
/// A single Physarum agent. The x and y positions are continuous, hence we use floating point
|
||||
@ -49,6 +49,7 @@ struct PopulationConfig {
|
||||
decay_factor: f32,
|
||||
sensor_angle: f32,
|
||||
rotation_angle: f32,
|
||||
deposition_amount: f32,
|
||||
}
|
||||
|
||||
impl PopulationConfig {
|
||||
@ -77,6 +78,8 @@ impl PopulationConfig {
|
||||
rotation_angle: rng
|
||||
.gen_range(Self::ROTATION_ANGLE_MIN..=Self::ROTATION_ANGLE_MAX)
|
||||
.to_radians(),
|
||||
deposition_amount: rng
|
||||
.gen_range(Self::DEPOSITION_AMOUNT_MIN..=Self::DEPOSITION_AMOUNT_MAX),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -163,8 +166,14 @@ impl Model {
|
||||
agent.rotate_and_move(direction, rotation_angle, step_distance, width, height);
|
||||
});
|
||||
|
||||
// Deposit + Diffuse + Decay
|
||||
|
||||
// Deposit
|
||||
for agent in self.agents.iter() {
|
||||
self.grid
|
||||
.add(agent.x, agent.y, self.config.deposition_amount);
|
||||
}
|
||||
// Diffuse + Decay
|
||||
self.grid
|
||||
.diffuse(self.diffusivity, self.config.decay_factor);
|
||||
self.iteration += 1;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,8 +1,3 @@
|
||||
#[inline(always)]
|
||||
pub fn is_power_of_two(x: usize) -> bool {
|
||||
(x & (x - 1)) == 0
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn wrap(x: f32, max: f32) -> f32 {
|
||||
x - max * ((x > max) as i32 as f32 - (x < 0.0_f32) as i32 as f32)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user