parry3d_f64/transformation/
convex_hull_utils.rs

1use crate::math::Real;
2use crate::num::Bounded;
3use na;
4#[cfg(feature = "dim3")]
5use {crate::bounding_volume, crate::math::Point};
6
7/// Returns the index of the support point of a list of points.
8pub fn support_point_id<const D: usize>(
9    direction: &na::SVector<Real, D>,
10    points: &[na::Point<Real, D>],
11) -> Option<usize> {
12    let mut argmax = None;
13    let _max: Real = Bounded::max_value();
14    let mut max = -_max;
15
16    for (id, pt) in points.iter().enumerate() {
17        let dot = direction.dot(&pt.coords);
18
19        if dot > max {
20            argmax = Some(id);
21            max = dot;
22        }
23    }
24
25    argmax
26}
27
28/// Returns the index of the support point of an indexed list of points.
29pub fn indexed_support_point_id<I, const D: usize>(
30    direction: &na::SVector<Real, D>,
31    points: &[na::Point<Real, D>],
32    idx: I,
33) -> Option<usize>
34where
35    I: Iterator<Item = usize>,
36{
37    let mut argmax = None;
38    let mut max = -Real::MAX;
39
40    for i in idx.into_iter() {
41        let dot = direction.dot(&points[i].coords);
42
43        if dot > max {
44            argmax = Some(i);
45            max = dot;
46        }
47    }
48
49    argmax
50}
51
52/// Returns the number `n` such that `points[idx.nth(n)]` is the support point.
53#[cfg(feature = "dim3")] // We only use this in 3D right now.
54pub fn indexed_support_point_nth<I, const D: usize>(
55    direction: &na::SVector<Real, D>,
56    points: &[na::Point<Real, D>],
57    idx: I,
58) -> Option<usize>
59where
60    I: Iterator<Item = usize>,
61{
62    let mut argmax = None;
63    let mut max = -Real::MAX;
64
65    for (k, i) in idx.into_iter().enumerate() {
66        let dot = direction.dot(&points[i].coords);
67
68        if dot > max {
69            argmax = Some(k);
70            max = dot;
71        }
72    }
73
74    argmax
75}
76
77/// Scale and center the given set of point depending on their Aabb.
78#[cfg(feature = "dim3")]
79pub fn normalize(coords: &mut [Point<Real>]) -> (Point<Real>, Real) {
80    let aabb = bounding_volume::details::local_point_cloud_aabb(&*coords);
81    let diag = na::distance(&aabb.mins, &aabb.maxs);
82    let center = aabb.center();
83
84    for c in coords.iter_mut() {
85        *c = (*c + (-center.coords)) / diag;
86    }
87
88    (center, diag)
89}