0

I am trying to use Gottschalk's algorithm (code available here) to create an oriented bounding box (OBB) for 3D triangular meshes. Since I am dealing with meshes, I am using the covariance matrix and eigenvalue decomposition approach to create the oriented bounding box. I have realized that the numerical accuracy in eigenvalue decomposition will lead to wrong OBB computation.

Let's clarify that with an example. Say I have a unit cube mesh consisting of 8 vertices in the range [0, 1] (depicted below). Clearly the OBB of this cube will be itself.

Unit cube

If I run Gottschalk's algorithm, I'd end up with a bounding box as shown below:

OBB

(Rotated for a better view)

OBB rotated

Clearly the results are wrong. I've tracked down the problem to eigenvalue decomposition. Since the I'm dealing with a unit cube, the axes must be unit x, y and z directions. However, eigenvalue decomposition is producing axes in other directions. The wrong result stems from the covariance matrix. The covariance matrix I calculate for this cube is as follows:

Covariance matrix:
|     0.138889  -2.77556E-17         0 |
| -2.77556E-17      0.138889         0 |
|            0             0  0.138889 |

The resulting eigenvectors is as follows:

Eigenvectors:
| -0.7071         0   -0.7071 |
| -0.7071         0    0.7071 |
|       0    1.0000         0 |

Taking each column of this matrix as the OBB's axis will produce the wrong result shown in the picture above. If I replace the super small values in covariance matrix with zero, I will get the correct eigenvectors and (by extension) axes:

Correct eignenvectors:
| 1     0     0 |
| 0     1     0 |
| 0     0     1 |

This tends to be less of an issue with objects with more vertices. However, I do have objects with exactly 8 vertices and I need to be able to calculate their OBB correctly.

How should I account for these accuracy issues? How can I make my OBB algorithm more robust?

If it helps, I'm implementing the algorithm in C#. Convex hull is being computed using CGAL and the eigenvalue decomposition is carried out using Math.NET.

Maghoumi
  • 3,295
  • 3
  • 33
  • 49
  • Close?! Seriously?! How can this question not be programming related?! It's directly related to the robustness of an algorithm! – Maghoumi Nov 15 '15 at 17:40
  • The result is not actually wrong. The accurate covariance matrix is a simple scaling (diagonal with all values equal), and *every* vector is an eigenvector of this matrix. You should try this with a more realistic data set. – Matt Timmermans Nov 15 '15 at 18:53
  • @MattTimmermans I'm not sure I understand what you mean exactly. Can you elaborate? Also, what do you mean by "realistic data set"? The oriented bounding box of a shape consisting of 8 vertices is not realistic? – Maghoumi Nov 15 '15 at 19:42
  • 1
    An eigenvector of a matrix is M is a vector v that M transforms to a scaled version of itself, i.e., a vector v such that Mv = Av for some scalar A. For a diagonal matrix with all equal values, EVERY vector is just multiplied by some constant, so EVERY vector is an eigenvector. By realistic data I mean something that isn't so symmetrical. The principal eigenvector of the covariance matrix is the "longest" dimension (sort of). When your data is all symmetrical like that, the longest dimension is indeterminate. – Matt Timmermans Nov 15 '15 at 22:24
  • @MattTimmermans Sorry for taking a bit to get back to you... I see what you mean and that makes perfect sense... So how should I go about computing the OBB? I.E. clearly using Gottschalk's algorithm would not account for all cases. – Maghoumi Nov 22 '15 at 22:34

1 Answers1

1

After much digging around, I saw this related question. Basically, it seems that you cannot expect Gottschalk's algorithm to work for all cases. Therefore, it is better to use approximation methods.

One good library for computing approximate oriented bounding boxes is ApproxMVBB. After going back and forth with the author of the library, I was finally able to get it to compile and work under Windows. Below is the screenshot of the output of the algorithm for the unit cube I used in the question:

correct OBB

Special thanks go to the author of the library for his help for the compilation of the library :)

Community
  • 1
  • 1
Maghoumi
  • 3,295
  • 3
  • 33
  • 49