diff --git a/src/main.rs b/src/main.rs index 78641c8..521569f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -25,7 +25,7 @@ fn main() { println!("Running: {:?}", cli); - let mut sys = DLASystem::::new( + let mut sys = DLASystem::::new( SmallRng::seed_from_u64(cli.seed), cli.max_particles, cli.stick_probability diff --git a/src/system/mod.rs b/src/system/mod.rs index cede115..39dacd9 100644 --- a/src/system/mod.rs +++ b/src/system/mod.rs @@ -1,4 +1,6 @@ +use std::f32::consts::PI; use std::ops::Add; +use rand::Rng; use serde::{Serialize, Deserialize, Serializer}; pub mod walker; @@ -7,6 +9,7 @@ pub mod model; pub trait GriddedPosition: Add + Serialize + Clone { fn zero() -> Self; + fn spawn(rng: &mut R, radius: f32) -> Self; fn abs(&self) -> f32; fn neighbours(&self) -> Vec; fn linear_index(&self, grid_size: u32) -> usize; @@ -37,6 +40,12 @@ impl GriddedPosition for Position { Position { x: 0, y: 0 } } + fn spawn(rng: &mut R, radius: f32) -> Self { + let theta = rng.gen_range(0f32..1.0) * 2.0 * PI; + let (x, y) = (radius * theta.cos(), radius * theta.sin()); + Position { x: x as i32, y: y as i32 } + } + fn abs(&self) -> f32 { ((self.x.pow(2) + self.y.pow(2)) as f32).powf(0.5) } diff --git a/src/system/model.rs b/src/system/model.rs index 26855fe..d162949 100644 --- a/src/system/model.rs +++ b/src/system/model.rs @@ -9,7 +9,7 @@ use crate::system::storage::{Storage, VectorStorage}; use crate::system::walker::{LocalRandomWalker, Walker}; use serde::{Serialize, Deserialize}; -pub struct DLASystem> { +pub struct DLASystem, W: Walker> { rng: R, storage: S, walker: W, @@ -19,8 +19,8 @@ pub struct DLASystem> { pub running: bool, - particles: Vec, - active_particle: Option, + particles: Vec

, + active_particle: Option

, add_ratio: f32, add_circle: f32, @@ -29,9 +29,9 @@ pub struct DLASystem> { cluster_radius: f32, } -impl> DLASystem { - pub fn new(rng: R, max_particles: usize, stick_probability: f32) -> DLASystem { - let mut sys: DLASystem = DLASystem { +impl, W: Walker> DLASystem { + pub fn new(rng: R, max_particles: usize, stick_probability: f32) -> DLASystem { + let mut sys: DLASystem = DLASystem { rng, stick_probability, max_particles, @@ -87,7 +87,7 @@ impl> DLASystem { } } - fn check_stick(&mut self, position: &Position) -> bool { + fn check_stick(&mut self, position: &P) -> bool { position.neighbours() .iter() .any(|neighbour| @@ -97,16 +97,14 @@ impl> DLASystem { } fn spawn_particle(&mut self) { - let theta = self.rng.gen_range(0f32..1.0) * 2.0 * PI; - let (x, y) = (self.add_circle * theta.cos(), self.add_circle * theta.sin()); - let position = Position { x: x as i32, y: y as i32 }; + let position = P::spawn(&mut self.rng, self.add_circle); if !self.storage.at(&position) { self.active_particle = Some(position); } } - fn deposit(&mut self, p0: &Position) { + fn deposit(&mut self, p0: &P) { self.particles.push(p0.clone()); self.storage.deposit(p0); diff --git a/src/system/storage.rs b/src/system/storage.rs index 1223417..6934683 100644 --- a/src/system/storage.rs +++ b/src/system/storage.rs @@ -1,8 +1,8 @@ -use crate::system::Position; +use crate::system::{GriddedPosition, Position}; -pub trait Storage { - fn at(&self, position: &Position) -> bool; - fn deposit(&mut self, position: &Position); +pub trait Storage { + fn at(&self, position: &P) -> bool; + fn deposit(&mut self, position: &P); } pub struct VectorStorage { @@ -35,7 +35,7 @@ impl VectorStorage { } } -impl Storage for VectorStorage { +impl Storage for VectorStorage { fn at(&self, position: &Position) -> bool { return self.backing[self.linear_index(position)] } diff --git a/src/system/walker.rs b/src/system/walker.rs index 8f40a4d..bb02e33 100644 --- a/src/system/walker.rs +++ b/src/system/walker.rs @@ -2,8 +2,8 @@ use num_integer::Integer; use rand::prelude::Rng; use crate::system::{GriddedPosition, Position}; -pub trait Walker { - fn walk(&self, rng: &mut R, position: &Position) -> Position; +pub trait Walker { + fn walk(&self, rng: &mut R, position: &P) -> P; } pub struct LocalRandomWalker { @@ -14,7 +14,7 @@ impl LocalRandomWalker { pub(crate) fn new(dim: u32) -> LocalRandomWalker { LocalRandomWalker { dim } } } -impl Walker for LocalRandomWalker { +impl Walker for LocalRandomWalker { fn walk(&self, rng: &mut R, position: &Position) -> Position { let neighbours = position.neighbours(); let index = rng.gen_range(0..(neighbours.len()));