将凹面网格分解为一组凸面网格


10

我希望能够将凹形网格分解为一组凸形网格,原因有两个:

  1. 透明渲染
  2. 物理形状

是否有一种算法将一组三角形(凹面)作为输入并输出许多三角形(凸面)?我希望它不填充原始网格的各个部分之间的孔。

我已经遇到了一个小主意:找到所有凹形边缘,然后沿边缘环将网格划分。我在正确的轨道上吗?我该如何实施?


什么是“凹/凸”网格?如果网格表示三角形网络,则它只是一组凸的三角形。还是您在谈论3D对象的数量?也许是多面体?
伊万·库基尔

@IvanKuckir网格或多面体也可以是凹凸的,其定义几乎相同。例如,没有一条直线会多次与多面体的内部相交。
congusbongus

Answers:


11

我会说您走在正确的道路上,但是想出一个最佳和/或高效的算法是另一回事:这是一个难题。但是,除非您的兴趣是学术上的,否则足够好的解决方案可能就足够了。

首先,如果您对自己的解决方案不感兴趣,则CGAL已包含用于凸多面体分解的算法:http : //doc.cgal.org/latest/Convex_decomposition_3/index.html

现在该方法了;像3D中的许多问题一样,考虑易于理解的2D问题通常会有所帮助。对于2D,任务是识别反射顶点,并通过从该反射顶点创建新的边(可能还有新的顶点)将多边形分为两个,然后继续进行操作,直到没有反射顶点(因此是全凸多边形)为止。 )。

反射顶点

J. Mark Keil的“多边形分解”包含以下算法(未优化形式):

diags = decomp(poly)
    min, tmp : EdgeList
    ndiags : Integer
    for each reflex vertex i
        for every other vertex j
            if i can see j
                left = the polygon given by vertices i to j
                right = the polygon given by vertices j to i
                tmp = decomp(left) + decomp(right)
                if(tmp.size < ndiags)
                    min = tmp
                    ndiags = tmp.size
                    min += the diagonal i to j
    return min

基本上,它详尽地比较了所有可能的分区,并返回对角线最少的分区。从这个意义上讲,它是蛮力的,也是最佳的。

如果您想要“看起来更清晰”的分解,即产生更紧凑的形状而不是细长的形状,则还可以考虑由Mark Ba​​yazit产生的分解,它贪婪(因此速度更快),看起来更好,但也有一些缺点。它基本上是通过尝试将反射顶点连接到与其相对的最佳顶点(通常是另一个反射顶点)来工作的:

巴亚济特新顶点 bayazit连接到另一个反射顶点

缺点之一是它通过创建Steiner点(在现有边上不存在的点)而忽略了“更好的”分解:

使用两个斯坦纳点分解三叶草

3D中的问题可能相似。您可以识别“缺口边缘”,而不是反射顶点。一个简单的实现是识别槽口边缘,并在多面体上重复执行平面切割,直到所有多面体都凸出为止。退房“多面体凸分区:绑定较低的和最坏情况优化算法”,由伯纳德·查泽尔的更多细节。

带缺口的多面体

请注意,这种方法可能在最坏的情况下产生指数数量的子多面体。这是因为您可能会产生类似以下的情况:

许多缺口多面体

但是,如果您使用的是非平凡的网格(想想凹凸不平的表面),无论如何您都会得到较差的结果。如果您需要将其用于复杂的网格,则很有可能需要事先进行很多简化。


6

计算表面S的精确凸分解是一个NP难题,通常会产生大量簇。为了克服这些限制,可以放宽精确的凸度约束,而代之以计算S的近似凸度分解。在此,目标是确定具有最小数量簇的网格三角形的分区,同时确保每个簇的凹度低于用户定义的阈值。

精确凸分解与近似凸分解

检查以下近似凸分解库:https : //code.google.com/p/v-hacd/ http://sourceforge.net/projects/hacd/


0

这是一些可以帮助您的代码。它在Java中,因此您必须将其转换为C ++。

这也是另一篇可以帮助您的文章


1
嗨,Masked Rebel,在这里不鼓励仅链接的答案。如果URL发生更改或资源变得不可用,它可能会留下完全取决于链接的答案,而这些链接对于将来的用户完全没有解决方案。只要您的答案仍然可以独立存在,并提供解决问题的指南,甚至可以在读者点击得更深之前,提供信用和进一步阅读的链接,就很好。请考虑编辑此答案,以至少包含要链接的解决方案的工作原理的广泛概述。
DMGregory

@DMGregory请删除我不能回答的答案。

答案不一定需要删除。只需对其进行编辑以包括更多信息,便可以得到很好的答案。
DMGregory

@DMGregory,但它将与该帖子的另一个答案重复。我将编辑另一个答案,然后将我的信息放在那里。

我想您一开始就共享此答案时,会觉得自己要添加一些新内容。我毫不怀疑,您可以用一种与现有答案无关的方式来解释所链接的代码。不过,如果您希望删除它,可以在网站的桌面版本上找到该链接。
DMGregory
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.