Use ApproxMVBB::approximateMVBB to find an approximate minimal volume oriented bounding box for a 3D point cloud.
Important Considerations:
- Degenerate Boxes: If the input points define a plane or line, the resulting box might have zero volume in some axes. Use
oobb.expandToMinExtentRelative(0.1) to enlarge the box by a percentage of its largest extent to avoid zero-width dimensions. - Point Coverage: Because the algorithm uses internal sampling for speed, the resulting OOBB might not contain all original points. To ensure all points are enclosed, you must manually iterate through your points and use
oobb.unite(). - Coordinate Frames: The returned
oobb object uses a local coordinate frame K. To transform a point from the local frame K back to the world frame I, multiply the local point by the rotation quaternion oobb.m_q_KI.
#include <iostream>
#include "ApproxMVBB/ComputeApproxMVBB.hpp"
int main(int argc, char** argv)
{
// 1. Setup points (e.g., 10,000 points in 3D)
ApproxMVBB::Matrix3Dyn points(3, 10000);
points.setRandom();
// 2. Compute approximate MVBB
// Params: points, epsilon, pointSamples, gridSize, mvbbDiamOptLoops, mvbbGridSearchOptLoops
ApproxMVBB::OOBB oobb = ApproxMVBB::approximateMVBB(points, 0.001, 500, 5, 0, 5);
// 3. Handle potential degeneracy
oobb.expandToMinExtentRelative(0.1);
// 4. Ensure all points are contained (Compensation loop)
ApproxMVBB::Matrix33 A_KI = oobb.m_q_KI.matrix().transpose();
auto size = points.cols();
for( unsigned int i=0; i<size; ++i ) {
oobb.unite(A_KI * points.col(i));
}
// 5. Transform local point to world frame
// ApproxMVBB::Vector3 p_world = oobb.m_q_KI * p_local;
return 0;
}