Swap to GriddedParticle throughout

This commit is contained in:
Joshua Coles 2023-03-04 11:37:17 +00:00
parent cd1f20c1d2
commit f7ac576129
5 changed files with 27 additions and 20 deletions

View File

@ -25,7 +25,7 @@ fn main() {
println!("Running: {:?}", cli); println!("Running: {:?}", cli);
let mut sys = DLASystem::<SmallRng, VectorStorage, LocalRandomWalker>::new( let mut sys = DLASystem::<SmallRng, Position, VectorStorage, LocalRandomWalker>::new(
SmallRng::seed_from_u64(cli.seed), SmallRng::seed_from_u64(cli.seed),
cli.max_particles, cli.max_particles,
cli.stick_probability cli.stick_probability

View File

@ -1,4 +1,6 @@
use std::f32::consts::PI;
use std::ops::Add; use std::ops::Add;
use rand::Rng;
use serde::{Serialize, Deserialize, Serializer}; use serde::{Serialize, Deserialize, Serializer};
pub mod walker; pub mod walker;
@ -7,6 +9,7 @@ pub mod model;
pub trait GriddedPosition: Add<Output=Self> + Serialize + Clone { pub trait GriddedPosition: Add<Output=Self> + Serialize + Clone {
fn zero() -> Self; fn zero() -> Self;
fn spawn<R: Rng>(rng: &mut R, radius: f32) -> Self;
fn abs(&self) -> f32; fn abs(&self) -> f32;
fn neighbours(&self) -> Vec<Self>; fn neighbours(&self) -> Vec<Self>;
fn linear_index(&self, grid_size: u32) -> usize; fn linear_index(&self, grid_size: u32) -> usize;
@ -37,6 +40,12 @@ impl GriddedPosition for Position {
Position { x: 0, y: 0 } Position { x: 0, y: 0 }
} }
fn spawn<R: Rng>(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 { fn abs(&self) -> f32 {
((self.x.pow(2) + self.y.pow(2)) as f32).powf(0.5) ((self.x.pow(2) + self.y.pow(2)) as f32).powf(0.5)
} }

View File

@ -9,7 +9,7 @@ use crate::system::storage::{Storage, VectorStorage};
use crate::system::walker::{LocalRandomWalker, Walker}; use crate::system::walker::{LocalRandomWalker, Walker};
use serde::{Serialize, Deserialize}; use serde::{Serialize, Deserialize};
pub struct DLASystem<R: Rng, S: Storage, W: Walker<R>> { pub struct DLASystem<R: Rng, P: GriddedPosition, S: Storage<P>, W: Walker<R, P>> {
rng: R, rng: R,
storage: S, storage: S,
walker: W, walker: W,
@ -19,8 +19,8 @@ pub struct DLASystem<R: Rng, S: Storage, W: Walker<R>> {
pub running: bool, pub running: bool,
particles: Vec<Position>, particles: Vec<P>,
active_particle: Option<Position>, active_particle: Option<P>,
add_ratio: f32, add_ratio: f32,
add_circle: f32, add_circle: f32,
@ -29,9 +29,9 @@ pub struct DLASystem<R: Rng, S: Storage, W: Walker<R>> {
cluster_radius: f32, cluster_radius: f32,
} }
impl<R: Rng, S: Storage, W: Walker<R>> DLASystem<R, S, W> { impl<R: Rng, P: GriddedPosition, S: Storage<P>, W: Walker<R, P>> DLASystem<R, P, S, W> {
pub fn new(rng: R, max_particles: usize, stick_probability: f32) -> DLASystem<R, VectorStorage, LocalRandomWalker> { pub fn new(rng: R, max_particles: usize, stick_probability: f32) -> DLASystem<R, Position, VectorStorage, LocalRandomWalker> {
let mut sys: DLASystem<R, VectorStorage, LocalRandomWalker> = DLASystem { let mut sys: DLASystem<R, Position, VectorStorage, LocalRandomWalker> = DLASystem {
rng, rng,
stick_probability, stick_probability,
max_particles, max_particles,
@ -87,7 +87,7 @@ impl<R: Rng, S: Storage, W: Walker<R>> DLASystem<R, S, W> {
} }
} }
fn check_stick(&mut self, position: &Position) -> bool { fn check_stick(&mut self, position: &P) -> bool {
position.neighbours() position.neighbours()
.iter() .iter()
.any(|neighbour| .any(|neighbour|
@ -97,16 +97,14 @@ impl<R: Rng, S: Storage, W: Walker<R>> DLASystem<R, S, W> {
} }
fn spawn_particle(&mut self) { fn spawn_particle(&mut self) {
let theta = self.rng.gen_range(0f32..1.0) * 2.0 * PI; let position = P::spawn(&mut self.rng, self.add_circle);
let (x, y) = (self.add_circle * theta.cos(), self.add_circle * theta.sin());
let position = Position { x: x as i32, y: y as i32 };
if !self.storage.at(&position) { if !self.storage.at(&position) {
self.active_particle = Some(position); self.active_particle = Some(position);
} }
} }
fn deposit(&mut self, p0: &Position) { fn deposit(&mut self, p0: &P) {
self.particles.push(p0.clone()); self.particles.push(p0.clone());
self.storage.deposit(p0); self.storage.deposit(p0);

View File

@ -1,8 +1,8 @@
use crate::system::Position; use crate::system::{GriddedPosition, Position};
pub trait Storage { pub trait Storage<P: GriddedPosition> {
fn at(&self, position: &Position) -> bool; fn at(&self, position: &P) -> bool;
fn deposit(&mut self, position: &Position); fn deposit(&mut self, position: &P);
} }
pub struct VectorStorage { pub struct VectorStorage {
@ -35,7 +35,7 @@ impl VectorStorage {
} }
} }
impl Storage for VectorStorage { impl Storage<Position> for VectorStorage {
fn at(&self, position: &Position) -> bool { fn at(&self, position: &Position) -> bool {
return self.backing[self.linear_index(position)] return self.backing[self.linear_index(position)]
} }

View File

@ -2,8 +2,8 @@ use num_integer::Integer;
use rand::prelude::Rng; use rand::prelude::Rng;
use crate::system::{GriddedPosition, Position}; use crate::system::{GriddedPosition, Position};
pub trait Walker<R: Rng> { pub trait Walker<R: Rng, P: GriddedPosition> {
fn walk(&self, rng: &mut R, position: &Position) -> Position; fn walk(&self, rng: &mut R, position: &P) -> P;
} }
pub struct LocalRandomWalker { pub struct LocalRandomWalker {
@ -14,7 +14,7 @@ impl LocalRandomWalker {
pub(crate) fn new(dim: u32) -> LocalRandomWalker { LocalRandomWalker { dim } } pub(crate) fn new(dim: u32) -> LocalRandomWalker { LocalRandomWalker { dim } }
} }
impl<R: Rng> Walker<R> for LocalRandomWalker { impl<R: Rng> Walker<R, Position> for LocalRandomWalker {
fn walk(&self, rng: &mut R, position: &Position) -> Position { fn walk(&self, rng: &mut R, position: &Position) -> Position {
let neighbours = position.neighbours(); let neighbours = position.neighbours();
let index = rng.gen_range(0..(neighbours.len())); let index = rng.gen_range(0..(neighbours.len()));