wip: Spacial index coming along pretty well, some tests and documentation left to write and should be good to go

This commit is contained in:
jeangab 2023-08-14 10:05:46 -04:00
parent c4cbef68d9
commit 996f83e92a
2 changed files with 111 additions and 0 deletions

View File

@ -5,6 +5,7 @@ pub use point::*;
mod space_colonization;
pub use space_colonization::*;
mod math;
mod spacial_index;
#[wasm_bindgen]
extern "C" {

View File

@ -0,0 +1,110 @@
use super::Point;
#[derive(Debug)]
struct SpatialIndex<T> {
elements: Vec<Vec<T>>,
number_cells_x: i32,
cell_size: i32,
}
impl<T> SpatialIndex<T> {
pub fn new(max_point: Point, cell_size: i32) -> SpatialIndex<T> {
// Here we add 1 to number cells x and y to handle the right and bottom edges where
// x = max_point.x or y = max_point.y
// For example, with max_point of (100,100)
// the point 100,100 is valid but 100/10 = 10, which is out of bounds of a zero based
// array of length 10. So we add 1 to the length and 10 is a valid index in a zero based
// array of length 11
let number_cells_x = (max_point.x / cell_size) + 1;
let number_cells = number_cells_x * ((max_point.y / cell_size) + 1);
let mut elements = Vec::with_capacity(number_cells as usize);
for _ in 0..number_cells {
elements.push(Vec::new());
}
SpatialIndex {
elements,
cell_size,
number_cells_x,
}
}
/// Adds an element in the cell of point
///
/// panics if the point is outside of
pub fn add(&mut self, point: &Point, element: T) {
let element_index = self.get_index_from_position(point);
dbg!(element_index);
self.elements
.get_mut(element_index as usize)
.unwrap()
.push(element);
}
pub fn get_surrounding_elements<'a>(&'a self, point: &Point) -> Vec<&'a Vec<T>> {
let element_index = self.get_index_from_position(point);
dbg!(element_index);
vec![&self.elements[element_index]]
}
fn get_index_from_position(&self, point: &Point) -> usize {
((point.x / self.cell_size) + ((point.y / self.cell_size) * self.number_cells_x)) as usize
}
}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn when_no_element_surrounding_nodes_returns_empty_vec() {
let index: SpatialIndex<usize> = SpatialIndex::new(Point::new((100, 100)), 10);
assert_eq!(
index.get_surrounding_elements(&Point::new((0, 0))),
vec![&Vec::<usize>::new()]
);
}
#[test]
fn added_point_is_surrounding_itself() {
let mut index: SpatialIndex<usize> = SpatialIndex::new(Point::new((100, 100)), 10);
index.add(&Point::new((50, 50)), 132);
assert_eq!(
index.get_surrounding_elements(&Point::new((50, 50))),
vec![&vec![132]]
);
}
#[test]
fn adding_point_outside_grid_panics() {
todo!();
}
#[test]
fn point_on_top_edge_is_close_to_first_cell() {
todo!();
}
#[test]
fn point_on_bottom_edge_is_close_to_first_cell() {
todo!();
}
#[test]
fn point_on_right_edge_is_close_to_first_cell() {
todo!();
}
#[test]
fn point_on_left_edge_is_close_to_first_cell() {
todo!();
}
#[test]
fn when_elements_too_far_surrounding_is_empty() {
let mut index: SpatialIndex<usize> = SpatialIndex::new(Point::new((100, 100)), 10);
index.add(&Point::new((0, 0)), 132);
assert_eq!(
index.get_surrounding_elements(&Point::new((99, 99))),
vec![&Vec::<usize>::new()]
);
}
}