我希望能够将凹形网格分解为一组凸形网格,原因有两个:
- 透明渲染
- 物理形状
是否有一种算法将一组三角形(凹面)作为输入并输出许多三角形(凸面)?我希望它不填充原始网格的各个部分之间的孔。
我已经遇到了一个小主意:找到所有凹形边缘,然后沿边缘环将网格划分。我在正确的轨道上吗?我该如何实施?
我希望能够将凹形网格分解为一组凸形网格,原因有两个:
是否有一种算法将一组三角形(凹面)作为输入并输出许多三角形(凸面)?我希望它不填充原始网格的各个部分之间的孔。
我已经遇到了一个小主意:找到所有凹形边缘,然后沿边缘环将网格划分。我在正确的轨道上吗?我该如何实施?
Answers:
我会说您走在正确的道路上,但是想出一个最佳和/或高效的算法是另一回事:这是一个难题。但是,除非您的兴趣是学术上的,否则足够好的解决方案可能就足够了。
首先,如果您对自己的解决方案不感兴趣,则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 Bayazit产生的分解,它贪婪(因此速度更快),看起来更好,但也有一些缺点。它基本上是通过尝试将反射顶点连接到与其相对的最佳顶点(通常是另一个反射顶点)来工作的:
缺点之一是它通过创建Steiner点(在现有边上不存在的点)而忽略了“更好的”分解:
3D中的问题可能相似。您可以识别“缺口边缘”,而不是反射顶点。一个简单的实现是识别槽口边缘,并在多面体上重复执行平面切割,直到所有多面体都凸出为止。退房“多面体凸分区:绑定较低的和最坏情况优化算法”,由伯纳德·查泽尔的更多细节。
请注意,这种方法可能在最坏的情况下产生指数数量的子多面体。这是因为您可能会产生类似以下的情况:
但是,如果您使用的是非平凡的网格(想想凹凸不平的表面),无论如何您都会得到较差的结果。如果您需要将其用于复杂的网格,则很有可能需要事先进行很多简化。
计算表面S的精确凸分解是一个NP难题,通常会产生大量簇。为了克服这些限制,可以放宽精确的凸度约束,而代之以计算S的近似凸度分解。在此,目标是确定具有最小数量簇的网格三角形的分区,同时确保每个簇的凹度低于用户定义的阈值。
检查以下近似凸分解库:https : //code.google.com/p/v-hacd/ http://sourceforge.net/projects/hacd/