diff --git a/src/main.rs b/src/main.rs index 022e41e..78641c8 100644 --- a/src/main.rs +++ b/src/main.rs @@ -7,7 +7,7 @@ use system::walker::{Walker, LocalRandomWalker}; use system::storage::{Storage, VectorStorage}; use num_integer::Integer; use rand::rngs::SmallRng; -use crate::system::{DIM, Position}; +use crate::system::{Position}; use crate::system::model::DLASystem; use clap::Parser; diff --git a/src/system/mod.rs b/src/system/mod.rs index 7cc21c7..1e5513e 100644 --- a/src/system/mod.rs +++ b/src/system/mod.rs @@ -1,11 +1,16 @@ use std::ops::Add; -use serde::{Serialize, Deserialize}; +use serde::{Serialize, Deserialize, Serializer}; pub mod walker; pub mod storage; pub mod model; -pub(crate) const DIM: u32 = 2; +pub trait GriddedPosition: Add + Serialize + Clone { + fn zero() -> Self; + fn abs(&self) -> f32; + fn neighbours(&self) -> Vec; + fn linear_index(&self, grid_size: u32) -> usize; +} #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] pub struct Position { @@ -14,26 +19,9 @@ pub struct Position { } impl Position { - pub fn zero() -> Position { - Position { x: 0, y: 0 } - } - - pub fn abs(&self) -> f32 { - ((self.x.pow(2) + self.y.pow(2)) as f32).powf(0.5) - } - - pub fn in_direction(direction: u32, value: i32) -> Self { + fn in_direction(direction: u32, value: i32) -> Self { if direction == 0 { Position { x: value, y: 0 } } else { Position { x: 0, y: value } } } - - pub fn neighbours(&self) -> impl Iterator + '_ { - let a = (0..DIM).into_iter(); - - return a.flat_map(|direction| [ - self.clone() + Position::in_direction(direction, 1), - self.clone() + Position::in_direction(direction, -1), - ]); - } } impl Add for Position { @@ -43,3 +31,34 @@ impl Add for Position { Position { x: self.x + rhs.x, y: self.y + rhs.y } } } + +impl GriddedPosition for Position { + fn zero() -> Position { + Position { x: 0, y: 0 } + } + + fn abs(&self) -> f32 { + ((self.x.pow(2) + self.y.pow(2)) as f32).powf(0.5) + } + + fn neighbours(&self) -> Vec { + let a = (0..2).into_iter(); + + return a.flat_map(|direction| [ + self.clone() + Position::in_direction(direction, 1), + self.clone() + Position::in_direction(direction, -1), + ]).collect(); + } + + fn linear_index(&self, grid_size: u32) -> usize { + let grid_size = grid_size as i32; + + assert!(self.x <= grid_size && -(grid_size) <= self.x); + assert!(self.y <= grid_size && -(grid_size) <= self.y); + + let x = (self.x + (grid_size) / 2) as usize; + let y = (self.y + (grid_size) / 2) as usize; + + return grid_size as usize * y + x; + } +} diff --git a/src/system/model.rs b/src/system/model.rs index 1dc4b0b..26855fe 100644 --- a/src/system/model.rs +++ b/src/system/model.rs @@ -4,7 +4,7 @@ use std::io::Write; use std::io; use std::path::Path; use rand::prelude::*; -use crate::system::{DIM, Position}; +use crate::system::{GriddedPosition, Position}; use crate::system::storage::{Storage, VectorStorage}; use crate::system::walker::{LocalRandomWalker, Walker}; use serde::{Serialize, Deserialize}; @@ -38,7 +38,7 @@ impl> DLASystem { running: true, storage: VectorStorage::new(1600, 2), - walker: LocalRandomWalker::new(DIM), + walker: LocalRandomWalker::new(2), particles: vec![], active_particle: None, @@ -89,6 +89,7 @@ impl> DLASystem { fn check_stick(&mut self, position: &Position) -> bool { position.neighbours() + .iter() .any(|neighbour| self.storage.at(&neighbour) && self.rng.gen_range(0.0f32..=1.0) < self.stick_probability diff --git a/src/system/walker.rs b/src/system/walker.rs index 378f6c3..8f40a4d 100644 --- a/src/system/walker.rs +++ b/src/system/walker.rs @@ -1,6 +1,6 @@ use num_integer::Integer; use rand::prelude::Rng; -use crate::system::{DIM, Position}; +use crate::system::{GriddedPosition, Position}; pub trait Walker { fn walk(&self, rng: &mut R, position: &Position) -> Position; @@ -16,11 +16,9 @@ impl LocalRandomWalker { impl Walker for LocalRandomWalker { fn walk(&self, rng: &mut R, position: &Position) -> Position { - let (dim, sign) = rng.gen_range(0u32..(DIM * 2)).div_rem(&self.dim); - let sign = if sign == 0 { 1 } else { -1 }; - let offset = Position::in_direction(dim, sign); - - position.clone() + offset + let neighbours = position.neighbours(); + let index = rng.gen_range(0..(neighbours.len())); + neighbours[index].clone() } }