1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
use crate;
/// Returns the index of the support point of a list of points.
///
/// The support point is the point that extends furthest in the given direction.
/// This is a fundamental operation used in convex hull algorithms and collision
/// detection (especially GJK/EPA algorithms).
///
/// # Arguments
/// * `direction` - The direction vector to test against
/// * `points` - A slice of points to search
///
/// # Returns
/// * `Some(index)` - Index of the support point (furthest in the given direction)
/// * `None` - If the points slice is empty
///
/// # Example
///
/// ```ignore
/// # // This is a pub(crate) function. Can't really run it.
/// # #[cfg(all(feature = "dim3", feature = "f32"))] {
/// use parry3d::transformation::convex_hull_utils::support_point_id;
/// use parry3d::na::{Vector3, Vector3};
///
/// let points = vec![
/// Vector::ZERO,
/// Vector::new(1.0, 0.0, 0.0),
/// Vector::new(0.0, 1.0, 0.0),
/// Vector::new(0.0, 0.0, 1.0),
/// ];
///
/// // Find point furthest in the positive X direction
/// let dir = Vector::new(1.0, 0.0, 0.0);
/// let support_id = support_point_id(&dir, &points);
/// assert_eq!(support_id, Some(1)); // Vector at (1, 0, 0)
///
/// // Find point furthest in the positive Y direction
/// let dir = Vector::new(0.0, 1.0, 0.0);
/// let support_id = support_point_id(&dir, &points);
/// assert_eq!(support_id, Some(2)); // Vector at (0, 1, 0)
/// # }
/// ```
/// Returns the index of the support point of an indexed list of points.
///
/// This is similar to [`support_point_id`], but only considers points at the indices
/// provided by the iterator. This is useful when you want to find the support point
/// within a subset of points without creating a new array.
///
/// # Arguments
/// * `direction` - The direction vector to test against
/// * `points` - The full array of points
/// * `idx` - Iterator yielding indices of points to consider
///
/// # Returns
/// * `Some(index)` - Index into the original `points` array of the support point
/// * `None` - If the iterator is empty
///
/// # Example
///
/// ```ignore
/// # // This is a pub(crate) function. Can't really run it.
/// # #[cfg(all(feature = "dim3", feature = "f32"))] {
/// use parry3d::transformation::convex_hull_utils::indexed_support_point_id;
/// use parry3d::na::{Vector3, Vector3};
///
/// let points = vec![
/// Vector::ZERO,
/// Vector::new(1.0, 0.0, 0.0),
/// Vector::new(2.0, 0.0, 0.0),
/// Vector::new(0.0, 1.0, 0.0),
/// ];
///
/// // Only consider points at indices 0, 1, and 3 (skip index 2)
/// let subset = vec![0, 1, 3];
/// let dir = Vector::new(1.0, 0.0, 0.0);
///
/// let support_id = indexed_support_point_id(&dir, &points, subset.into_iter());
/// // Returns 1 (not 2, since we skipped that index)
/// assert_eq!(support_id, Some(1));
/// # }
/// ```
/// Returns the position in the iterator where the support point is found.
///
/// This is similar to [`indexed_support_point_id`], but returns the position within
/// the iterator rather than the index in the original points array. In other words,
/// if the iterator yields indices `[5, 7, 2, 9]` and the support point is at index 2,
/// this function returns `Some(2)` (the 3rd position in the iterator), not `Some(2)`.
///
/// # Arguments
/// * `direction` - The direction vector to test against
/// * `points` - The full array of points
/// * `idx` - Iterator yielding indices of points to consider
///
/// # Returns
/// * `Some(n)` - The `n`th element of the iterator corresponds to the support point
/// * `None` - If the iterator is empty
///
/// # Example
///
/// ```ignore
/// # // This is a pub(crate) function. Can’t really run it.
/// # #[cfg(all(feature = "dim3", feature = "f32"))] {
/// use parry3d::transformation::convex_hull_utils::indexed_support_point_nth;
/// use parry3d::na::{Vector3, Vector3};
///
/// let points = vec![
/// Vector::ZERO, // index 0
/// Vector::new(1.0, 0.0, 0.0), // index 1
/// Vector::new(5.0, 0.0, 0.0), // index 2
/// Vector::new(0.0, 1.0, 0.0), // index 3
/// ];
///
/// // Consider points at indices [3, 0, 2, 1]
/// let indices = vec![3, 0, 2, 1];
/// let dir = Vector::new(1.0, 0.0, 0.0);
///
/// let nth = indexed_support_point_nth(&dir, &points, indices.into_iter());
/// // The support point is at original index 2, which is position 2 in our iterator
/// assert_eq!(nth, Some(2));
/// # }
/// ```
// We only use this in 3D right now.
/// Normalizes a point cloud by centering and scaling it to fit within a unit cube.
///
/// This function computes the axis-aligned bounding box (AABB) of the input points,
/// then translates all points so they're centered at the origin, and scales them
/// so the bounding box diagonal has length 1. This normalization is useful for
/// improving numerical stability in geometric algorithms like convex hull computation.
///
/// The transformation is reversible using the returned center and scale values.
///
/// # Arguments
/// * `coords` - Mutable slice of points to normalize in-place
///
/// # Returns
/// A tuple `(center, scale)` where:
/// * `center` - The original center point of the AABB (before normalization)
/// * `scale` - The original AABB diagonal length (before normalization)
///
/// To reverse the transformation: `original_point = normalized_point * scale + center`
///
/// # Example
///
/// ```ignore
/// # // This is a pub(crate) function. Can’t really run it.
/// # #[cfg(all(feature = "dim3", feature = "f32"))] {
/// use parry3d::transformation::convex_hull_utils::normalize;
/// use parry3d::math::Vector;
///
/// let mut points = vec![
/// Vector::new(10.0, 10.0, 10.0),
/// Vector::new(20.0, 20.0, 20.0),
/// Vector::new(15.0, 15.0, 15.0),
/// ];
///
/// let (center, scale) = normalize(&mut points);
///
/// // Vectors are now centered around origin and scaled
/// // The AABB diagonal is now approximately 1.0
/// println!("Original center: {:?}", center);
/// println!("Original scale: {}", scale);
///
/// // To recover original points:
/// for p in &mut points {
/// *p = *p * scale + center;
/// }
/// # }
/// ```