从点创建 OOBB

发布于 2024-11-11 14:00:14 字数 298 浏览 4 评论 0原文

如何为给定点创建最小 OOBB?创建 AABB 或球体非常容易,但创建最小的 OOBB 时遇到问题。

[编辑]

第一个答案没有给我带来好的结果。我没有大量的积分。我的积分很少。我正在做碰撞几何生成。例如,立方体有 36 个点(6 个边,每个边 2 个三角形,每个三角形 3 个点)。第一篇文章中的算法给出了立方体的糟糕结果。立方体的示例点: http://nopaste.dk/download/3382 (应返回身份轴)

How can I create minimal OOBB for given points? Creating AABB or sphere is very easy, but I have problems creating minimal OOBB.

[edit]

First answer didn't get me good results. I don't have huge cloud of points. I have little amount of points. I am doing collision geometry generation. For example, cube has 36 points (6 sides, 2 triangles each, 3 points for each triangle). And algorithm from first post gave bad results for cube. Example points for cube: http://nopaste.dk/download/3382 (should return identity axis)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

清欢 2024-11-18 14:00:14

PCA/协方差/特征向量方法本质上是找到近似于对象顶点的椭球体的轴。它应该适用于随机对象,但对于像立方体这样的对称对象会给出不好的结果。这是因为立方体的近似椭球体是球体,而球体没有明确定义的轴。所以你没有得到你期望的标准轴。

也许,如果您事先知道一个对象是一个立方体,例如,您可以使用专门的方法,并将 PCA 用于其他所有事情。

另一方面,如果您想计算真正的 OBB,可以使用现有的实现,例如 http://www.geometrictools.com/LibMathematics/Containment/Containment.html
(存档于 https://web.archive.org /web/20110817024344/geometrictools.com/LibMathematics/Containment/Containment.htmlhttps://github.com/timprepscius/GeometricTools/blob/master/WildMagic5/LibMathematics/Containment/Wm5ContMinBox3.cpp)。我相信这实现了您问题的评论中提到的算法。

引用该页面:

ContMinBox3 文件实现了
计算的算法
最小体积的盒子包含
点。该方法计算
点的凸包,凸
多面体。最小容积箱
要么有一张与
凸多面体的面或有
轴方向由三个给出
相互垂直的边
凸多面体。每张脸的
凸多面体的加工过程为
将多面体投影到平面
的脸部,计算
包含的最小面积矩形
预测,并计算
包含的最小长度间隔
投影到垂直于
脸。最小面积矩形
和最小长度间隔结合起来
形成一个候选框。然后所有三元组
凸多面体的边数为
已处理。若任意三元组互有
垂直边,最小的盒子
与轴的方向
计算边缘。在所有这些盒子中,
体积最小的是
最小体积的盒子包含
原始点集。

如果正如您所说,您的对象没有大量顶点,则运行时间应该是可以接受的。

http://www.gamedev 的讨论中.net/topic/320675-how-to-create-orient-bounding-box/ 上述库的作者对这个主题有更多的了解:

Gottschalk 构建 OBB 的方法是计算点集的协方差矩阵。该矩阵的特征向量是 OBB 轴。点的平均值就是 OBB 中心。不保证 OBB 具有所有容纳盒的最小体积。 OBB树是通过递归分割以点集为顶点的三角形网格来构建的。提到了一些关于分割的启发式方法。

包含点集的最小体积框(MVB)是包含点的凸包的最小体积框。船体是凸多面体。根据 Joe O'Rourke 的结果,MVB 由多面体的一个面或多面体的三个垂直边支撑。 “由面支撑”是指MVB具有与多面体面重合的面。 “由三个垂直边支撑”是指MVB的三个垂直边与多面体的边重合。

正如 jyk 所指出的,这些算法的实现都不是微不足道的。然而,永远不要因此而放弃尝试:) AABB 可能很合适,但也可能非常不合适。考虑一个端点位于 (0,0,0) 和 (1,1,1) 的“薄”圆柱体[想象圆柱体是连接这些点的线段]。 AABB 为 0 <= x <= 1、0 <= y <= 1、0 <= z <= 1,体积为 1。MVB 的中心为 (1,1,1 )/2,轴 (1,1,1)/sqrt(3),以及该轴的范围 sqrt(3)/2。它还具有垂直于第一个轴的两个附加轴,但范围为 0。该盒子的体积为 0。如果给线段一点粗细,MVB 会变得稍大,但体积仍然比AABB 的。

您选择哪种类型的盒子应取决于您自己的应用程序的数据。

所有这些的实现都在我的 www.geometrictools.com 网站上。我对包围体树使用中值分割启发式。 MVB 构造需要一个 2D 凸包查找器、一个 3D 凸包查找器以及计算包含一组平面点的最小面积框的方法 - 我为此使用旋转卡尺方法。

The PCA/covariance/eigenvector method essentially finds the axes of an ellipsoid that approximates the vertices of your object. It should work for random objects, but will give bad results for symmetric objects like the cube. That's because the approximating ellipsoid for a cube is a sphere, and a sphere does not have well defined axes. So you're not getting the standard axes that you expect.

Perhaps if you know in advance that an object is, for example, a cube you can use a specialized method, and use PCA for everything else.

On the other hand, if you want to compute the true OBB there are existing implementations you can use e.g. http://www.geometrictools.com/LibMathematics/Containment/Containment.html
(archived at https://web.archive.org/web/20110817024344/geometrictools.com/LibMathematics/Containment/Containment.html and https://github.com/timprepscius/GeometricTools/blob/master/WildMagic5/LibMathematics/Containment/Wm5ContMinBox3.cpp). I believe this implements the algorithm alluded to in the comments to your question.

Quoting from that page:

The ContMinBox3 files implement an
algorithm for computing the
minimum-volume box containing the
points. This method computes the
convex hull of the points, a convex
polyhedron. The minimum-volume box
either has a face coincident with a
face of the convex polyhedron or has
axis directions given by three
mutually perpendicular edges of the
convex polyhedron. Each face of the
convex polyhedron is processed by
projecting the polyhedron to the plane
of the face, computing the
minimum-area rectangle containing the
projections, and computing the
minimum-length interval containing the
projections onto the perpendicular of
the face. The minimum-area rectangle
and minimum-length interval combine to
form a candidate box. Then all triples
of edges of the convex polyhedron are
processed. If any triple has mutually
perpendicular edges, the smallest box
with axes in the directions of the
edges is computed. Of all these boxes,
the one with the smallest volume is
the minimum-volume box containing the
original point set.

If, as you say, your objects do not have a large number of vertices, the running time should be acceptable.

In a discussion at http://www.gamedev.net/topic/320675-how-to-create-oriented-bounding-box/ the author of the above library casts some more light on the topic:

Gottschalk's approach to OBB construction is to compute a covariance matrix for the point set. The eigenvectors of this matrix are the OBB axes. The average of the points is the OBB center. The OBB is not guaranteed to have the minimum volume of all containing boxes. An OBB tree is built by recursively splitting the triangle mesh whose vertices are the point set. A couple of heuristics are mentioned for the splitting.

The minimum volume box (MVB) containing a point set is the minimum volume box containing the convex hull of the points. The hull is a convex polyhedron. Based on a result of Joe O'Rourke, the MVB is supported by a face of the polyhedron or by three perpendicular edges of the polyhedron. "Supported by a face" means that the MVB has a face coincident with a polyhedron face. "Supported by three perpendicular edges" means that three perpendicular edges of the MVB are coincident with edges of the polyhedron.

As jyk indicates, the implementations of any of these algorithms is not trivial. However, never let that discourage you from trying :) An AABB can be a good fit, but it can also be a very bad fit. Consider a "thin" cylinder with end points at (0,0,0) and (1,1,1) [imagine the cylinder is the line segment connecting the points]. The AABB is 0 <= x <= 1, 0 <= y <= 1, and 0 <= z <= 1, with a volume of 1. The MVB has center (1,1,1)/2, an axis (1,1,1)/sqrt(3), and an extent for this axis of sqrt(3)/2. It also has two additional axes perpendicular to the first axis, but the extents are 0. The volume of this box is 0. If you give the line segment a little thickness, the MVB becomes slightly larger, but still has a volume much smaller than that of the AABB.

Which type of box you choose should depend on your own application's data.

Implementations of all of this are at my www.geometrictools.com website. I use the median-split heuristic for the bounding-volume trees. The MVB construction requires a convex hull finder in 2D, a convex hull finder in 3D, and a method for computing the minimum area box containing a set of planar points--I use the rotating caliper method for this.

月牙弯弯 2024-11-18 14:00:14

首先,您必须计算点的质心,

mu = sum(0..N, x[i]) / N

然后用伪代码计算协方差矩阵。

C = sum(0..N, mult(x[i]-mu, transpose(x[i]-mu)));

请注意,mult 执行 (3x1) 矩阵乘以 (1x3) 矩阵乘法,结果是一个 3x3 矩阵。

C 矩阵的特征向量定义了 OBB 的三个轴。

First you have to compute the centroid of the points, in pseudcode

mu = sum(0..N, x[i]) / N

then you have to compute the covariance matrix

C = sum(0..N, mult(x[i]-mu, transpose(x[i]-mu)));

Note that the mult performs an (3x1) matrix multiplication by (1x3) matrix multiplication, and the result is a 3x3 matrix.

The eigenvectors of the C matrix define the three axis of the OBB.

想你的星星会说话 2024-11-18 14:00:14

在线 C++ 中有一个新库 ApproxMVBB,它可以计算最小体积边界框的近似值。它是根据 MPL 2.0 许可证发布的,由我编写。

如果您有时间,请查看: http://gabyx.github.io/ApproxMVBB/

该库是兼容 C++11,仅需要 Eigen http://eigen.tuxfamily.org
测试表明,根据您的近似设置,可以在合理的时间内(大约 5-7 秒)计算出 3D 中 1.4 亿个点的近似值。

There is a new library ApproxMVBB in C++ online which computes an approximation for the minimum volume bounding box. Its released under MPL 2.0 Licences, and written by me.

If you have time look at: http://gabyx.github.io/ApproxMVBB/

The library is C++11 compatible and only needs Eigen http://eigen.tuxfamily.org.
Tests show that an approximation for 140Million points in 3D can be computed in reasonable time (arround 5-7 seconds) depending on your settings for the approximation.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文