Fix neighbours in Grid3D...
This commit is contained in:
parent
4a5fca6837
commit
2bd51ef53c
64
src/fd.rs
64
src/fd.rs
@ -6,7 +6,7 @@ use std::fs::File;
|
||||
use std::os::unix::fs::symlink;
|
||||
use bevy::tasks::ParallelSlice;
|
||||
use crate::system::spaces::square_grid::{Grid2D, Grid3D};
|
||||
use itertools::Itertools;
|
||||
use itertools::{Itertools, MinMaxResult};
|
||||
use clap::Parser;
|
||||
use crate::system::{GriddedPosition, Position};
|
||||
use crate::system::model::HistoryLine;
|
||||
@ -101,55 +101,19 @@ fn box_count_3d(data: &Vec<Grid3D>, size: u32) -> usize {
|
||||
.count();
|
||||
}
|
||||
|
||||
fn box_count_nd<const N: usize, P: Position>(data: &Vec<P>, size: u32) -> usize {
|
||||
let n = data.len();
|
||||
let pp = data.iter().map(|op| op.to_cartesian()).collect::<Vec<P::Cartesian>>();
|
||||
fn box_count_nd<const N: usize>(data: &Vec<[f32; N]>, size: u32) -> usize {
|
||||
let ranges = (0..N).map(|n|
|
||||
match data.iter()
|
||||
.minmax_by(|a, b| a[n].total_cmp(&b[n])) {
|
||||
MinMaxResult::NoElements => panic!("No data"),
|
||||
MinMaxResult::OneElement(_) => panic!("Needs more than one point to compute boxcount"),
|
||||
MinMaxResult::MinMax(min, max) => [min[n], min[n]],
|
||||
}).collect::<Vec<_>>();
|
||||
|
||||
let x_min = data
|
||||
.iter()
|
||||
.min_by(|Grid3D { x: x1, .. }, Grid3D { x: x2, .. }| x1.cmp(x2))
|
||||
.unwrap().x;
|
||||
let w: f32 = (ranges[0][1] - ranges[0][0]) / (size as f32);
|
||||
|
||||
let x_max = data
|
||||
.iter()
|
||||
.max_by(|Grid3D { x: x1, .. }, Grid3D { x: x2, .. }| x1.cmp(x2))
|
||||
.unwrap().x;
|
||||
|
||||
let y_min = data
|
||||
.iter()
|
||||
.min_by(|Grid3D { y: v1, .. }, Grid3D { y: v2, .. }| v1.cmp(v2))
|
||||
.unwrap().y;
|
||||
|
||||
let y_max = data
|
||||
.iter()
|
||||
.max_by(|Grid3D { y: v1, .. }, Grid3D { y: v2, .. }| v1.cmp(v2))
|
||||
.unwrap().y;
|
||||
|
||||
let z_min = data
|
||||
.iter()
|
||||
.min_by(|Grid3D { z: v1, .. }, Grid3D { z: v2, .. }| v1.cmp(v2))
|
||||
.unwrap().y;
|
||||
|
||||
let z_max = data
|
||||
.iter()
|
||||
.max_by(|Grid3D { z: v1, .. }, Grid3D { z: v2, .. }| v1.cmp(v2))
|
||||
.unwrap().y;
|
||||
|
||||
let x_range = (x_max - x_min) as f64;
|
||||
let y_range = (y_max - y_min) as f64;
|
||||
let z_range = (z_max - z_min) as f64;
|
||||
|
||||
let w: f64 = x_range / (size as f64);
|
||||
|
||||
let grid_points = data.iter()
|
||||
.map(|Grid3D { x, y, z }| [
|
||||
((x - x_min) as f64 / w) as u32,
|
||||
((y - y_min) as f64 / w) as u32,
|
||||
((z - z_min) as f64 / w) as u32,
|
||||
])
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
return grid_points.iter()
|
||||
return data.iter()
|
||||
.map(|point| -> [i32; N] { std::array::from_fn(|n| ((point[n] - ranges[n][0]) / w) as i32) })
|
||||
.unique()
|
||||
.count();
|
||||
}
|
||||
@ -165,10 +129,10 @@ fn main() {
|
||||
.expect("Failed to read json");
|
||||
|
||||
let a = lines.iter()
|
||||
.map(|l| l.position.clone())
|
||||
.map(|l| l.position.to_cartesian())
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
for size in 1..250 {
|
||||
println!("[{}, {:?}],", size, box_count_3d(&a, size));
|
||||
println!("[{}, {:?}],", size, box_count_nd(&a, size));
|
||||
}
|
||||
}
|
||||
|
||||
@ -102,8 +102,24 @@ impl Add for Grid3D {
|
||||
type Output = Grid3D;
|
||||
|
||||
fn add(self, rhs: Self) -> Self::Output {
|
||||
Grid3D { x: self.x + rhs.x, y: self.y + rhs.y, z: self.z + rhs.z }
|
||||
Grid3D {
|
||||
x: self.x + rhs.x,
|
||||
y: self.y + rhs.y,
|
||||
z: self.z + rhs.z,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn grid3_add_test() {
|
||||
assert_eq!(
|
||||
Grid3D::from_cartesian([0f32, 0f32, 0f32]) + Grid3D::from_cartesian([0f32, 1f32, 0f32]),
|
||||
Grid3D::from_cartesian([0f32, 1f32, 0f32])
|
||||
);
|
||||
assert_eq!(
|
||||
Grid3D::from_cartesian([5.0, 3.0, 1.0]) + Grid3D::from_cartesian([-2.0, 5.0, 100.0]),
|
||||
Grid3D::from_cartesian([3.0, 8.0, 101.0])
|
||||
);
|
||||
}
|
||||
|
||||
impl Position for Grid3D {
|
||||
@ -130,11 +146,25 @@ impl Position for Grid3D {
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn grid3_neighbours_test() {
|
||||
let neighbours = (0..Grid3D::NEIGHBOURS)
|
||||
.map(|n| Grid3D::neighbour(&Grid3D::zero(), n))
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
assert!(neighbours.contains(&Grid3D { x: 1, y: 0, z: 0 }));
|
||||
assert!(neighbours.contains(&Grid3D { x: -1, y: 0, z: 0 }));
|
||||
assert!(neighbours.contains(&Grid3D { x: 0, y: 1, z: 0 }));
|
||||
assert!(neighbours.contains(&Grid3D { x: 0, y: -1, z: 0 }));
|
||||
assert!(neighbours.contains(&Grid3D { x: 0, y: 0, z: 1 }));
|
||||
assert!(neighbours.contains(&Grid3D { x: 0, y: 0, z: -1 }));
|
||||
}
|
||||
|
||||
impl GriddedPosition for Grid3D {
|
||||
const NEIGHBOURS: u32 = 6;
|
||||
|
||||
fn neighbour(&self, neighbour_index: u32) -> Self {
|
||||
let (dim, sign) = neighbour_index.div_rem(&3);
|
||||
let (dim, sign) = neighbour_index.div_rem(&2);
|
||||
let sign = if sign == 0 { 1 } else { -1 };
|
||||
let offset = Self::in_direction(dim, sign);
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user