1use crate::math::{Isometry, Point, Real, Rotation, Translation, Vector, DIM};
2use crate::shape::Cuboid;
3
4pub fn obb(pts: &[Point<Real>]) -> (Isometry<Real>, Cuboid) {
9 let cov = crate::utils::cov(pts);
10 let mut eigv = cov.symmetric_eigen().eigenvectors;
11
12 if eigv.determinant() < 0.0 {
13 eigv = -eigv;
14 }
15
16 let mut mins = Vector::repeat(Real::MAX);
17 let mut maxs = Vector::repeat(-Real::MAX);
18
19 for pt in pts {
20 for i in 0..DIM {
21 let dot = eigv.column(i).dot(&pt.coords);
22 mins[i] = mins[i].min(dot);
23 maxs[i] = maxs[i].max(dot);
24 }
25 }
26
27 #[cfg(feature = "dim2")]
28 let rot = Rotation::from_rotation_matrix(&na::Rotation2::from_matrix_unchecked(eigv));
29 #[cfg(feature = "dim3")]
30 let rot = Rotation::from_rotation_matrix(&na::Rotation3::from_matrix_unchecked(eigv));
31
32 (
33 rot * Translation::from((maxs + mins) / 2.0),
34 Cuboid::new((maxs - mins) / 2.0),
35 )
36}