pub(super) fn point_enclosed(point: [f64; 3], scale: f64, tris: &[[[f64; 3]; 3]]) -> bool {
let dirs = [[1.0, 0.0, 0.0], [0.0, 1.0, 0.0], [0.0, 0.0, 1.0]];
let mut valid = 0u32;
let mut inside = 0u32;
for (k, dir) in dirs.iter().enumerate() {
let j = (k as f64 + 1.0) * 1e-7 * scale;
let origin = [point[0] + j, point[1] + 1.3 * j, point[2] + 1.7 * j];
match count_crossings(origin, *dir, scale, tris) {
Some(n) => {
valid += 1;
if n % 2 == 1 {
inside += 1;
}
}
None => continue, }
}
valid >= 2 && inside >= 2
}
fn count_crossings(
origin: [f64; 3],
dir: [f64; 3],
scale: f64,
tris: &[[[f64; 3]; 3]],
) -> Option<u32> {
const BARY_EPS: f64 = 1e-9;
let t_eps = 1e-9 * scale;
let mut crossings = 0u32;
for tri in tris {
let (a, b, c) = (tri[0], tri[1], tri[2]);
let e1 = [b[0] - a[0], b[1] - a[1], b[2] - a[2]];
let e2 = [c[0] - a[0], c[1] - a[1], c[2] - a[2]];
let pv = [
dir[1] * e2[2] - dir[2] * e2[1],
dir[2] * e2[0] - dir[0] * e2[2],
dir[0] * e2[1] - dir[1] * e2[0],
];
let det = e1[0] * pv[0] + e1[1] * pv[1] + e1[2] * pv[2];
if det.abs() < 1e-16 {
continue; }
let inv = 1.0 / det;
let tv = [origin[0] - a[0], origin[1] - a[1], origin[2] - a[2]];
let u = (tv[0] * pv[0] + tv[1] * pv[1] + tv[2] * pv[2]) * inv;
if u < -BARY_EPS || u > 1.0 + BARY_EPS {
continue;
}
let qv = [
tv[1] * e1[2] - tv[2] * e1[1],
tv[2] * e1[0] - tv[0] * e1[2],
tv[0] * e1[1] - tv[1] * e1[0],
];
let v = (dir[0] * qv[0] + dir[1] * qv[1] + dir[2] * qv[2]) * inv;
if v < -BARY_EPS || u + v > 1.0 + BARY_EPS {
continue;
}
let t = (e2[0] * qv[0] + e2[1] * qv[1] + e2[2] * qv[2]) * inv;
if t <= -t_eps {
continue; }
if t < t_eps {
return None; }
if u < BARY_EPS || v < BARY_EPS || u + v > 1.0 - BARY_EPS {
return None; }
crossings += 1;
}
Some(crossings)
}