导致Gottschalk定向边界框算法问题的数字精度

时间:2015-11-15 17:27:04

标签: c# graphics floating-accuracy bounding-box mathdotnet

我正在尝试使用Gottschalk's算法(代码available here)为3D三角网格创建一个定向边界框(OBB)。由于我正在处理网格,我使用协方差矩阵和特征值分解方法来创建定向边界框。我已经意识到特征值分解的数值精度会导致错误的OBB计算。

让我们用一个例子来澄清。假设我有一个单位立方体网格,由[0,1]范围内的8个顶点组成(如下所示)。显然,这个立方体的OBB本身就是。

Unit cube

如果我运行Gottschalk的算法,我最终会得到一个边界框,如下所示:

OBB

(旋转以获得更好的视图)

OBB rotated

显然结果是错误的。我已经将问题追溯到特征值分解。由于我处理单位立方体,因此轴必须是单位xyz方向。然而,特征值分解在其他方向上产生轴。错误的结果源于协方差矩阵。我为这个立方体计算的协方差矩阵如下:

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

得到的特征向量如下:

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

将此矩阵的每一列作为OBB的轴将产生如上图所示的错误结果。如果我将协方差矩阵中的超小值替换为零,我将获得正确的特征向量和(通过扩展)轴:

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

对于具有更多顶点的对象,这往往不是问题。但是,我确实有8个顶点的对象,我需要能够正确计算它们的OBB。

我应该如何解释这些准确性问题?如何使OBB算法更加健壮?

如果有帮助,我在C#中实现算法。凸壳是使用CGAL计算的,特征值分解是使用Math.NET进行的。

1 个答案:

答案 0 :(得分:1)

经过多次挖掘,我看到了this related question。基本上,似乎你不能指望Gottschalk的算法适用于所有情况。因此,最好使用近似方法。

用于计算近似定向边界框的一个好库是ApproxMVBB。在与图书馆的作者来回走动之后,我终于能够在Windows下编译和工作了。下面是我在问题中使用的单位多维数据集的算法输出的屏幕截图:

correct OBB

特别感谢图书馆的作者为图书馆的编辑提供帮助:)