Move to gridded position system
This commit is contained in:
parent
7e131af96d
commit
0d972dc76a
@ -7,7 +7,7 @@ use system::walker::{Walker, LocalRandomWalker};
|
|||||||
use system::storage::{Storage, VectorStorage};
|
use system::storage::{Storage, VectorStorage};
|
||||||
use num_integer::Integer;
|
use num_integer::Integer;
|
||||||
use rand::rngs::SmallRng;
|
use rand::rngs::SmallRng;
|
||||||
use crate::system::{DIM, Position};
|
use crate::system::{Position};
|
||||||
use crate::system::model::DLASystem;
|
use crate::system::model::DLASystem;
|
||||||
|
|
||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
|
|||||||
@ -1,11 +1,16 @@
|
|||||||
use std::ops::Add;
|
use std::ops::Add;
|
||||||
use serde::{Serialize, Deserialize};
|
use serde::{Serialize, Deserialize, Serializer};
|
||||||
|
|
||||||
pub mod walker;
|
pub mod walker;
|
||||||
pub mod storage;
|
pub mod storage;
|
||||||
pub mod model;
|
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)]
|
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
pub struct Position {
|
pub struct Position {
|
||||||
@ -14,26 +19,9 @@ pub struct Position {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Position {
|
impl Position {
|
||||||
pub fn zero() -> Position {
|
fn in_direction(direction: u32, value: i32) -> Self {
|
||||||
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 {
|
|
||||||
if direction == 0 { Position { x: value, y: 0 } } else { Position { x: 0, y: value } }
|
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 {
|
impl Add for Position {
|
||||||
@ -43,3 +31,34 @@ impl Add for Position {
|
|||||||
Position { x: self.x + rhs.x, y: self.y + rhs.y }
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -4,7 +4,7 @@ use std::io::Write;
|
|||||||
use std::io;
|
use std::io;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use rand::prelude::*;
|
use rand::prelude::*;
|
||||||
use crate::system::{DIM, Position};
|
use crate::system::{GriddedPosition, Position};
|
||||||
use crate::system::storage::{Storage, VectorStorage};
|
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};
|
||||||
@ -38,7 +38,7 @@ impl<R: Rng, S: Storage, W: Walker<R>> DLASystem<R, S, W> {
|
|||||||
running: true,
|
running: true,
|
||||||
|
|
||||||
storage: VectorStorage::new(1600, 2),
|
storage: VectorStorage::new(1600, 2),
|
||||||
walker: LocalRandomWalker::new(DIM),
|
walker: LocalRandomWalker::new(2),
|
||||||
particles: vec![],
|
particles: vec![],
|
||||||
active_particle: None,
|
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 {
|
fn check_stick(&mut self, position: &Position) -> bool {
|
||||||
position.neighbours()
|
position.neighbours()
|
||||||
|
.iter()
|
||||||
.any(|neighbour|
|
.any(|neighbour|
|
||||||
self.storage.at(&neighbour)
|
self.storage.at(&neighbour)
|
||||||
&& self.rng.gen_range(0.0f32..=1.0) < self.stick_probability
|
&& self.rng.gen_range(0.0f32..=1.0) < self.stick_probability
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
use num_integer::Integer;
|
use num_integer::Integer;
|
||||||
use rand::prelude::Rng;
|
use rand::prelude::Rng;
|
||||||
use crate::system::{DIM, Position};
|
use crate::system::{GriddedPosition, Position};
|
||||||
|
|
||||||
pub trait Walker<R: Rng> {
|
pub trait Walker<R: Rng> {
|
||||||
fn walk(&self, rng: &mut R, position: &Position) -> Position;
|
fn walk(&self, rng: &mut R, position: &Position) -> Position;
|
||||||
@ -16,11 +16,9 @@ impl LocalRandomWalker {
|
|||||||
|
|
||||||
impl<R: Rng> Walker<R> for LocalRandomWalker {
|
impl<R: Rng> Walker<R> for LocalRandomWalker {
|
||||||
fn walk(&self, rng: &mut R, position: &Position) -> Position {
|
fn walk(&self, rng: &mut R, position: &Position) -> Position {
|
||||||
let (dim, sign) = rng.gen_range(0u32..(DIM * 2)).div_rem(&self.dim);
|
let neighbours = position.neighbours();
|
||||||
let sign = if sign == 0 { 1 } else { -1 };
|
let index = rng.gen_range(0..(neighbours.len()));
|
||||||
let offset = Position::in_direction(dim, sign);
|
neighbours[index].clone()
|
||||||
|
|
||||||
position.clone() + offset
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user