use crate::*;
impl SpatialHashGrid2D {
pub fn create(cell_size: f64) -> SpatialHashGrid2D {
let safe_size: f64 = cell_size.max(EPSILON);
let mut grid: SpatialHashGrid2D = SpatialHashGrid2D::new(safe_size);
grid.set_inverse_cell_size(1.0 / safe_size);
grid
}
pub fn with_default_size() -> SpatialHashGrid2D {
Self::create(SPATIAL_DEFAULT_CELL_SIZE_2D)
}
pub fn insert(&mut self, index: usize, min: Vector2D, max: Vector2D) {
let inv: f64 = self.get_inverse_cell_size();
let min_col: i32 = (min.get_x() * inv).floor() as i32;
let min_row: i32 = (min.get_y() * inv).floor() as i32;
let max_col: i32 = (max.get_x() * inv).floor() as i32;
let max_row: i32 = (max.get_y() * inv).floor() as i32;
for col in min_col..=max_col {
for row in min_row..=max_row {
self.get_mut_cells()
.entry((col, row))
.or_default()
.push(index);
}
}
}
pub fn query(&self, min: Vector2D, max: Vector2D) -> Vec<usize> {
let inv: f64 = self.get_inverse_cell_size();
let min_col: i32 = (min.get_x() * inv).floor() as i32;
let min_row: i32 = (min.get_y() * inv).floor() as i32;
let max_col: i32 = (max.get_x() * inv).floor() as i32;
let max_row: i32 = (max.get_y() * inv).floor() as i32;
let mut seen: HashSet<usize> = HashSet::new();
let mut result: Vec<usize> = Vec::new();
for col in min_col..=max_col {
for row in min_row..=max_row {
if let Some(entries) = self.get_cells().get(&(col, row)) {
for index in entries {
if seen.insert(*index) {
result.push(*index);
}
}
}
}
}
result
}
pub fn clear(&mut self) {
self.get_mut_cells().clear();
}
}
impl SpatialHashGrid3D {
pub fn create(cell_size: f64) -> SpatialHashGrid3D {
let safe_size: f64 = cell_size.max(EPSILON);
let mut grid: SpatialHashGrid3D = SpatialHashGrid3D::new(safe_size);
grid.set_inverse_cell_size(1.0 / safe_size);
grid
}
pub fn with_default_size() -> SpatialHashGrid3D {
Self::create(SPATIAL_DEFAULT_CELL_SIZE_3D)
}
pub fn insert(&mut self, index: usize, min: Vector3D, max: Vector3D) {
let inv: f64 = self.get_inverse_cell_size();
let min_col: i32 = (min.get_x() * inv).floor() as i32;
let min_row: i32 = (min.get_y() * inv).floor() as i32;
let min_layer: i32 = (min.get_z() * inv).floor() as i32;
let max_col: i32 = (max.get_x() * inv).floor() as i32;
let max_row: i32 = (max.get_y() * inv).floor() as i32;
let max_layer: i32 = (max.get_z() * inv).floor() as i32;
for col in min_col..=max_col {
for row in min_row..=max_row {
for layer in min_layer..=max_layer {
self.get_mut_cells()
.entry((col, row, layer))
.or_default()
.push(index);
}
}
}
}
pub fn query(&self, min: Vector3D, max: Vector3D) -> Vec<usize> {
let inv: f64 = self.get_inverse_cell_size();
let min_col: i32 = (min.get_x() * inv).floor() as i32;
let min_row: i32 = (min.get_y() * inv).floor() as i32;
let min_layer: i32 = (min.get_z() * inv).floor() as i32;
let max_col: i32 = (max.get_x() * inv).floor() as i32;
let max_row: i32 = (max.get_y() * inv).floor() as i32;
let max_layer: i32 = (max.get_z() * inv).floor() as i32;
let mut seen: HashSet<usize> = HashSet::new();
let mut result: Vec<usize> = Vec::new();
for col in min_col..=max_col {
for row in min_row..=max_row {
for layer in min_layer..=max_layer {
if let Some(entries) = self.get_cells().get(&(col, row, layer)) {
for index in entries {
if seen.insert(*index) {
result.push(*index);
}
}
}
}
}
}
result
}
pub fn clear(&mut self) {
self.get_mut_cells().clear();
}
}
impl Default for SpatialHashGrid2D {
fn default() -> SpatialHashGrid2D {
SpatialHashGrid2D::with_default_size()
}
}
impl Default for SpatialHashGrid3D {
fn default() -> SpatialHashGrid3D {
SpatialHashGrid3D::with_default_size()
}
}