use super::DiscretizeError;
use crate::geometry::{LocalBasis, Segment};
const MIN_RELATIVE_EXTENT: f64 = 1e-7;
pub(super) fn validate(
segment: &Segment,
basis: &LocalBasis,
widths: &[(f64, f64)],
heights: &[(f64, f64)],
(nw, nh, ratio): (usize, usize, f64),
) -> Result<(), DiscretizeError> {
let shape_scale = segment.length().max(segment.width).max(segment.height);
let envelope = segment.a.position().abs().sup(&segment.b.position().abs())
+ basis.width.abs() * (0.5 * segment.width)
+ basis.height.abs() * (0.5 * segment.height);
for (axis, direction, cells) in [
("width", basis.width, widths),
("height", basis.height, heights),
] {
let coordinate_scale = direction.abs().dot(&envelope);
let minimum =
(MIN_RELATIVE_EXTENT * shape_scale).max(32.0 * f64::EPSILON * coordinate_scale);
let extent = cells
.iter()
.map(|&(_, size)| size)
.fold(f64::INFINITY, f64::min);
let valid = cells.iter().all(|&(centre, size)| {
size.is_finite()
&& size > 0.0
&& size >= minimum
&& centre.is_finite()
&& centre - 0.5 * size < centre
&& centre + 0.5 * size > centre
}) && cells.windows(2).all(|pair| pair[0].0 < pair[1].0);
if !valid {
return Err(DiscretizeError::UnusableGrading {
axis,
nw,
nh,
ratio,
extent,
minimum,
});
}
}
Ok(())
}