diff --git a/src/main.rs b/src/main.rs index 466af4c..e1f4b58 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,19 +1,10 @@ #![feature(array_zip)] use std::path::PathBuf; -use rand::prelude::*; mod system; mod example_systems; -use system::walker::{LocalRandomWalker, Walker}; -use system::grid::VectorStorage; -use num_integer::Integer; -use rand::rngs::SmallRng; -use crate::system::grid::Position; -use crate::system::model::DLASystem; -use crate::system::Storage; - use clap::Parser; use crate::example_systems::stick_probability; diff --git a/src/system/grid.rs b/src/system/grid.rs index 93ea1b1..ef65d0c 100644 --- a/src/system/grid.rs +++ b/src/system/grid.rs @@ -73,32 +73,20 @@ impl VectorStorage { VectorStorage { grid_size, backing: vec![false; grid_size.pow(2) as usize] } } - pub fn linear_index(&self, position: &Position) -> usize { - assert!(position.x <= self.grid_size as i32 && -(self.grid_size as i32) <= position.x); - assert!(position.y <= self.grid_size as i32 && -(self.grid_size as i32) <= position.y); - - let x = (position.x + (self.grid_size as i32) / 2) as usize; - let y = (position.y + (self.grid_size as i32) / 2) as usize; - - return self.grid_size as usize * y + x - } - /* * Convenience function for c-binding * */ pub fn write(&mut self, position: &Position, val: bool) { - let index = self.linear_index(position); - self.backing[index] = val; + self.backing[position.linear_index(self.grid_size)] = val; } } impl Storage for VectorStorage { fn at(&self, position: &Position) -> bool { - return self.backing[self.linear_index(position)] + return self.backing[position.linear_index(self.grid_size)] } fn deposit(&mut self, position: &Position) { - let index = self.linear_index(position); - self.backing[index] = true; + self.backing[position.linear_index(self.grid_size)] = true; } } diff --git a/src/system/hexagonal.rs b/src/system/hexagonal.rs new file mode 100644 index 0000000..5d78df3 --- /dev/null +++ b/src/system/hexagonal.rs @@ -0,0 +1,51 @@ +use std::ops::Add; +use bevy::render::color::HexColorError::Hex; +use rand::Rng; +use crate::system::GriddedPosition; +use serde::{Serialize, Deserialize}; + +#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] +pub struct HexPosition { + pub q: i32, + pub r: i32, +} + +impl Add for HexPosition { + type Output = Self; + + fn add(self, rhs: Self) -> Self::Output { + HexPosition { q: self.q + rhs.q, r: self.r + rhs.r } + } +} + +impl GriddedPosition for HexPosition { + const NEIGHBOURS: u32 = 6; + + fn zero() -> Self { + HexPosition { q: 0, r: 0 } + } + + fn spawn(rng: &mut R, radius: f32) -> Self { + todo!() + } + + fn abs(&self) -> f32 { + ((self.q.pow(2) + self.r.pow(2) + self.q * self.r) as f32).sqrt() + } + + fn neighbour(&self, neighbour_index: u32) -> Self { + let neighbour_index = neighbour_index as usize; + + const OFFSETS: [(i32, i32); 6] = [ + (1, 0), (1, -1), (0, -1), + (-1, 0), (-1, 1), (0, 1), + ]; + + self.clone() + HexPosition { q: OFFSETS[neighbour_index].0, r: OFFSETS[neighbour_index].0 } + } + + fn linear_index(&self, grid_size: u32) -> usize { + todo!() + // ((self.q + grid_size / 2) + grid_size * self.r) as usize + } +} diff --git a/src/system/mod.rs b/src/system/mod.rs index 6bfb55c..64ba2fb 100644 --- a/src/system/mod.rs +++ b/src/system/mod.rs @@ -1,14 +1,12 @@ -use std::f32::consts::PI; use std::ops::Add; -use num_integer::Integer; use rand::Rng; -use serde::{Deserialize, Serialize, Serializer}; -use crate::system::grid::VectorStorage; +use serde::Serialize; pub mod walker; pub mod grid; pub mod model; pub mod nd; +mod hexagonal; pub trait GriddedPosition: Add + Serialize + Clone { const NEIGHBOURS: u32; diff --git a/src/system/model.rs b/src/system/model.rs index f4c02c3..68716b4 100644 --- a/src/system/model.rs +++ b/src/system/model.rs @@ -1,14 +1,8 @@ -use std::f32::consts::PI; -use std::fs::File; -use std::io::Write; use std::io; use std::path::Path; use rand::prelude::*; -use crate::system::{GriddedPosition, grid::Position, Storage}; -use crate::system::grid::VectorStorage; -use crate::system::walker::{LocalRandomWalker, Walker}; -use serde::{Deserialize, Serialize}; -use crate::system::nd::{NDPosition, NDVectorStorage}; +use crate::system::{GriddedPosition, Storage}; +use crate::system::walker::Walker; pub struct DLASystem, W: Walker

> { rng: R, diff --git a/src/system/nd.rs b/src/system/nd.rs index bd6aa0a..dbad2e2 100644 --- a/src/system/nd.rs +++ b/src/system/nd.rs @@ -75,11 +75,11 @@ impl GriddedPosition for NDPosition { .sqrt(); for i in 0..DIM { - a[i] = a[i] / norm; + a[i] = a[i] * radius / norm; b[i] = a[i] as i32; } - return Self(b) + return Self(b); } fn abs(&self) -> f32 { diff --git a/src/system/walker.rs b/src/system/walker.rs index fbe8ad8..4ae62c8 100644 --- a/src/system/walker.rs +++ b/src/system/walker.rs @@ -1,6 +1,5 @@ -use num_integer::Integer; use rand::prelude::Rng; -use crate::system::{GriddedPosition, grid::Position}; +use crate::system::GriddedPosition; pub trait Walker { fn walk(&self, rng: &mut R, position: &P) -> P; @@ -22,35 +21,35 @@ mod test { #[test] fn uniformity() { - let walker = LocalRandomWalker::new(); + let walker = LocalRandomWalker; let mut rng = SmallRng::from_rng(thread_rng()).unwrap(); let mut results: Vec = vec![]; let origin = &Position::zero(); - let x: u32 = (1_000000_000); + let x: u32 = (1_000_000); for i in 0..x { results.push(walker.walk(&mut rng, origin)); } let a = results .iter() - .filter(|a| **a == Position(0, 1)) + .filter(|a| **a == Position { x: 0, y: 1 }) .count(); let b = results .iter() - .filter(|a| **a == Position(0, -1)) + .filter(|a| **a == Position { x: 0, y: -1 }) .count(); let c = results .iter() - .filter(|a| **a == Position(1, 0)) + .filter(|a| **a == Position { x: 1, y: 0 }) .count(); let d = results .iter() - .filter(|a| **a == Position(-1, 0)) + .filter(|a| **a == Position { x: -1, y: 0 }) .count(); println!("{} {} {} {}", a as f32 / x as f32, b as f32 / x as f32, c as f32 / x as f32, d as f32 / x as f32);