use std::iter::zip;
use crate::{usage_types::coordinates::Coordinate, VectorGrid};
impl<ItemType> VectorGrid<ItemType> {
pub fn step_sizes(&self) -> Vec<usize> {
let mut result = vec![1];
for dimension in self.defined_shape.iter() {
result.push(result.last().unwrap() * dimension.get())
}
result.push(self.len());
result
}
pub fn step_sizes_i(&self) -> Vec<isize> {
let mut result = vec![1];
for dimension in self.defined_shape.iter() {
result.push(result.last().unwrap() * dimension.get() as isize)
}
result
}
pub fn is_inside_grid(&self, at: &Coordinate) -> bool {
for (axis, length) in zip(at.iter(), self.defined_shape.iter()) {
if axis.is_negative() {
return false;
}
if *axis as usize >= length.get() {
return false;
}
}
self.get_coordinate_index(&at) < self.items.len()
}
pub fn get_coordinate_index(&self, at: &Coordinate) -> usize {
let mut index = 0;
for (distance, step_size) in zip(at.iter(), self.step_sizes_i()) {
index += *distance * step_size
}
index as usize
}
pub fn get_index_coordinate(&self, at: usize) -> Coordinate {
let at = at as isize;
let mut coordinate = Vec::new();
let step_sizes = self.step_sizes_i();
for (i, step_size) in step_sizes.iter().enumerate() {
let dimension = *step_sizes.get(i + 1).unwrap_or(&isize::MAX) as isize;
coordinate.push((at % dimension) / step_size)
}
Coordinate::new(coordinate)
}
}