use num_traits::AsPrimitive;
pub fn aabb2<Real>(vtx2xy: &[[Real; 2]]) -> [Real; 4]
where
Real: num_traits::Float,
{
let mut aabb = [vtx2xy[0][0], vtx2xy[0][1], vtx2xy[0][0], vtx2xy[0][1]];
vtx2xy.iter().skip(1).for_each(|v| {
aabb[0] = if v[0] < aabb[0] { v[0] } else { aabb[0] };
aabb[1] = if v[1] < aabb[1] { v[1] } else { aabb[1] };
aabb[2] = if v[0] > aabb[2] { v[0] } else { aabb[2] };
aabb[3] = if v[1] > aabb[3] { v[1] } else { aabb[3] };
});
aabb
}
pub fn aabb2_indexed<Index, T>(idx2vtx: &[Index], vtx2xy: &[[T; 2]], eps: T) -> [T; 4]
where
T: num_traits::Float,
Index: AsPrimitive<usize>,
{
assert!(!idx2vtx.is_empty());
let mut aabb = [T::zero(); 4];
{
let i_vtx: usize = idx2vtx[0].as_();
aabb[0] = vtx2xy[i_vtx][0] - eps;
aabb[2] = vtx2xy[i_vtx][0] + eps;
aabb[1] = vtx2xy[i_vtx][1] - eps;
aabb[3] = vtx2xy[i_vtx][1] + eps;
}
for &i_vtx in idx2vtx.iter().skip(1) {
let i_vtx = i_vtx.as_();
let cgx = vtx2xy[i_vtx][0];
aabb[0] = if cgx - eps < aabb[0] {
cgx - eps
} else {
aabb[0]
};
aabb[2] = if cgx + eps > aabb[2] {
cgx + eps
} else {
aabb[2]
};
let cgy = vtx2xy[i_vtx][1];
aabb[1] = if cgy - eps < aabb[1] {
cgy - eps
} else {
aabb[1]
};
aabb[3] = if cgy + eps > aabb[3] {
cgy + eps
} else {
aabb[3]
};
}
assert!(aabb[0] <= aabb[2]);
assert!(aabb[1] <= aabb[3]);
aabb
}
pub fn normalize<Real>(vtx2xy: &[[Real; 2]], center_pos: &[Real; 2], size: Real) -> Vec<[Real; 2]>
where
Real: num_traits::Float,
{
let aabb = aabb2(vtx2xy);
let cnt = del_geo_core::aabb2::center(&aabb);
let max_edge_size = del_geo_core::aabb2::max_edge_size(&aabb);
let tmp = size / max_edge_size;
vtx2xy
.iter()
.map(|v| {
[
(v[0] - cnt[0]) * tmp + center_pos[0],
(v[1] - cnt[1]) * tmp + center_pos[1],
]
})
.collect()
}