Add N-dimensional position code
This commit is contained in:
parent
14b5cb4679
commit
1c49bf92c8
@ -1,3 +1,5 @@
|
|||||||
|
#![feature(array_zip)]
|
||||||
|
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use rand::prelude::*;
|
use rand::prelude::*;
|
||||||
|
|
||||||
|
|||||||
@ -6,6 +6,7 @@ use serde::{Serialize, Deserialize, Serializer};
|
|||||||
pub mod walker;
|
pub mod walker;
|
||||||
pub mod storage;
|
pub mod storage;
|
||||||
pub mod model;
|
pub mod model;
|
||||||
|
pub mod nd;
|
||||||
|
|
||||||
pub trait GriddedPosition: Add<Output=Self> + Serialize + Clone {
|
pub trait GriddedPosition: Add<Output=Self> + Serialize + Clone {
|
||||||
fn zero() -> Self;
|
fn zero() -> Self;
|
||||||
|
|||||||
99
src/system/nd.rs
Normal file
99
src/system/nd.rs
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
use std::ops::Add;
|
||||||
|
use rand::Rng;
|
||||||
|
use serde::{Serialize, Serializer};
|
||||||
|
use serde::ser::SerializeMap;
|
||||||
|
use crate::system::GriddedPosition;
|
||||||
|
use crate::system::storage::Storage;
|
||||||
|
|
||||||
|
pub struct NDVectorStorage<const DIM: usize> {
|
||||||
|
backing: Vec<bool>,
|
||||||
|
grid_size: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<const DIM: usize> Storage<NDPosition<DIM>> for NDVectorStorage<DIM> {
|
||||||
|
fn at(&self, position: &NDPosition<DIM>) -> bool {
|
||||||
|
return self.backing[position.linear_index(self.grid_size)];
|
||||||
|
}
|
||||||
|
|
||||||
|
fn deposit(&mut self, position: &NDPosition<DIM>) {
|
||||||
|
self.backing[position.linear_index(self.grid_size)] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||||
|
pub struct NDPosition<const DIM: usize>([i32; DIM]);
|
||||||
|
|
||||||
|
impl<const DIM: usize> NDPosition<DIM> {
|
||||||
|
pub fn in_direction(direction: usize, value: i32) -> Self {
|
||||||
|
let mut arr = [0; DIM];
|
||||||
|
arr[direction] = value;
|
||||||
|
NDPosition(arr)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<const DIM: usize> Add for NDPosition<DIM> {
|
||||||
|
type Output = Self;
|
||||||
|
|
||||||
|
fn add(self, rhs: Self) -> Self::Output {
|
||||||
|
Self(self.0.zip(rhs.0).map(|(a, b)| a + b))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<const DIM: usize> Serialize for NDPosition<DIM> {
|
||||||
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer {
|
||||||
|
let mut map = serializer.serialize_map(Some(DIM))?;
|
||||||
|
for (i, v) in self.0.iter().enumerate() {
|
||||||
|
map.serialize_entry(&format!("r{}", i), v)?;
|
||||||
|
}
|
||||||
|
map.end()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<const DIM: usize> GriddedPosition for NDPosition<DIM> {
|
||||||
|
fn zero() -> Self {
|
||||||
|
NDPosition([0; DIM])
|
||||||
|
}
|
||||||
|
|
||||||
|
fn spawn<R: Rng>(rng: &mut R, radius: f32) -> Self {
|
||||||
|
let mut a: [f32; DIM] = [0f32; DIM];
|
||||||
|
let mut b: [i32; DIM] = [0i32; DIM];
|
||||||
|
|
||||||
|
for i in 0..DIM {
|
||||||
|
a[i] = rng.gen_range(0f32..1f32);
|
||||||
|
}
|
||||||
|
|
||||||
|
let norm = a.iter().sum::<f32>()
|
||||||
|
.sqrt();
|
||||||
|
|
||||||
|
for i in 0..DIM {
|
||||||
|
a[i] = a[i] / norm;
|
||||||
|
b[i] = a[i] as i32;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Self(b)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn abs(&self) -> f32 {
|
||||||
|
let a: i32 = self.0.iter()
|
||||||
|
.map(|r| r.pow(2))
|
||||||
|
.sum();
|
||||||
|
|
||||||
|
(a as f32).powf(0.5)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn neighbours(&self) -> Vec<Self> {
|
||||||
|
let a = (0..DIM).into_iter();
|
||||||
|
|
||||||
|
return a.flat_map(|direction| [
|
||||||
|
self.clone() + NDPosition::in_direction(direction, 1),
|
||||||
|
self.clone() + NDPosition::in_direction(direction, -1),
|
||||||
|
]).collect();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn linear_index(&self, grid_size: u32) -> usize {
|
||||||
|
self.0.iter()
|
||||||
|
.enumerate()
|
||||||
|
.map(|(i, v)| (grid_size.pow(i as u32) as usize) * (v + ((grid_size / 2) as i32)) as usize)
|
||||||
|
.sum()
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user