use nalgebra::{Point3, Vector3};
use crate::geom::Cube;
pub struct Grid {
pub boundary: Cube,
pub num_voxels: [usize; 3],
pub voxel_size: Vector3<f64>,
pub voxel_inv_size: Vector3<f64>,
}
impl Grid {
#[inline]
#[must_use]
pub fn new(boundary: Cube, num_voxels: [usize; 3]) -> Self {
let widths = boundary.widths();
let voxel_size = Vector3::new(
widths.x / num_voxels[0] as f64,
widths.y / num_voxels[1] as f64,
widths.z / num_voxels[2] as f64,
);
Self {
boundary,
num_voxels,
voxel_size,
voxel_inv_size: Vector3::new(
1.0 / voxel_size.x,
1.0 / voxel_size.y,
1.0 / voxel_size.z,
),
}
}
#[inline]
#[must_use]
pub fn voxel_index(&self, point: &Point3<f64>) -> Option<[usize; 3]> {
if !self.boundary.contains(point) {
return None;
}
let x = ((point.x - self.boundary.mins.x) * self.voxel_inv_size.x) as usize;
let y = ((point.y - self.boundary.mins.y) * self.voxel_inv_size.y) as usize;
let z = ((point.z - self.boundary.mins.z) * self.voxel_inv_size.z) as usize;
Some([x, y, z])
}
#[inline]
#[must_use]
pub fn generate_voxel(&self, index: [usize; 3]) -> Cube {
let mins = Point3::new(
self.voxel_size
.x
.mul_add(index[0] as f64, self.boundary.mins.x),
self.voxel_size
.y
.mul_add(index[1] as f64, self.boundary.mins.y),
self.voxel_size
.z
.mul_add(index[2] as f64, self.boundary.mins.z),
);
let maxs = mins + self.voxel_size;
Cube::new(mins, maxs)
}
}