Move to gridded position system

This commit is contained in:
Joshua Coles 2023-03-04 11:24:26 +00:00
parent 7e131af96d
commit 0d972dc76a
4 changed files with 47 additions and 29 deletions

View File

@ -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;

View File

@ -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<Output=Self> + Serialize + Clone {
fn zero() -> Self;
fn abs(&self) -> f32;
fn neighbours(&self) -> Vec<Self>;
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<Item=Self> + '_ {
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<Self> {
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;
}
}

View File

@ -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<R: Rng, S: Storage, W: Walker<R>> DLASystem<R, S, W> {
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<R: Rng, S: Storage, W: Walker<R>> DLASystem<R, S, W> {
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

View File

@ -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<R: Rng> {
fn walk(&self, rng: &mut R, position: &Position) -> Position;
@ -16,11 +16,9 @@ impl LocalRandomWalker {
impl<R: Rng> Walker<R> 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()
}
}