mod convergent;
mod idw;
mod min_curvature;
mod nearest;
pub use convergent::ConvergentGridder;
use crate::foundation::{AlgoError, Lattice, Result};
use ndarray::Array2;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum GridMethod {
Nearest,
InverseDistance,
MinimumCurvature,
}
pub fn grid(coords: &[[f64; 3]], lattice: &Lattice, method: GridMethod) -> Result<Array2<f64>> {
if coords.is_empty() {
return Err(AlgoError::EmptyInput("grid: no points to grid"));
}
Ok(match method {
GridMethod::Nearest => nearest::grid_nearest(coords, lattice),
GridMethod::InverseDistance => idw::grid_idw(coords, lattice),
GridMethod::MinimumCurvature => min_curvature::grid_min_curvature(coords, lattice, None),
})
}
pub fn grid_min_curvature_seeded(
coords: &[[f64; 3]],
lattice: &Lattice,
seed: Option<&Array2<f64>>,
) -> Result<Array2<f64>> {
if coords.is_empty() {
return Err(AlgoError::EmptyInput(
"grid_min_curvature_seeded: no points to grid",
));
}
Ok(min_curvature::grid_min_curvature(coords, lattice, seed))
}
#[cfg(test)]
mod tests {
use super::*;
use crate::foundation::Lattice;
#[test]
fn empty_input_errors() {
let g = Lattice::regular(0.0, 0.0, 1.0, 1.0, 4, 4);
assert!(matches!(
grid(&[], &g, GridMethod::Nearest),
Err(AlgoError::EmptyInput(_))
));
}
#[test]
fn seeded_empty_input_errors() {
let g = Lattice::regular(0.0, 0.0, 1.0, 1.0, 4, 4);
assert!(matches!(
grid_min_curvature_seeded(&[], &g, None),
Err(AlgoError::EmptyInput(_))
));
}
#[test]
fn seeded_none_equals_cold_grid() {
let g = Lattice::regular(0.0, 0.0, 1.0, 1.0, 8, 7);
let coords = [[1.0, 1.0, 3.0], [6.0, 5.0, 12.0], [3.0, 4.0, 7.0]];
let cold = grid(&coords, &g, GridMethod::MinimumCurvature).unwrap();
let seeded_none = grid_min_curvature_seeded(&coords, &g, None).unwrap();
assert_eq!(cold, seeded_none);
let warm = grid_min_curvature_seeded(&coords, &g, Some(&cold)).unwrap();
for (w, c) in warm.iter().zip(cold.iter()) {
assert!((w - c).abs() < 1e-3);
}
}
}