给定不规则多边形的顶点列表,如何创建内部三角形以有效地构建平面3D网格?

时间:2012-11-13 21:52:00

标签: geometry unity3d computational-geometry polygons

我正在使用Unity,但解决方案应该是通用的。 我将通过鼠标点击获得用户输入,鼠标点击定义了封闭的不规则多边形的顶点列表。 该顶点将定义平面3D网格的外边缘。

要在Unity中以程序方式生成网格,我必须指定所有顶点以及它们如何连接以形成三角形。

因此,对于凸多边形而言,它是微不足道的,我只是制作三角形,其顶点为1,2,3,然后是1,3,4等,形成类似孔雀尾的东西。

但对于凹面多边形而言,并非如此简单。 是否有一种有效的算法来查找内部三角形?

3 个答案:

答案 0 :(得分:6)

您可以使用受约束的Delaunay triangulation(实现起来并非易事!)。 TriangleCGAL中提供了良好的库实现,提供了高效的O(n*log(n))实现。

如果顶点集很小,ear-clipping算法也是可能的,虽然它不一定会给你一个Delaunay三角剖分(它通常会产生次优三角形)并在O(n^2)中运行。尽管如此,这很容易实现。

由于输入顶点存在于3d空间的平面上,因此可以通过投影到平面上获得2d问题,在2d中计算三角剖分,然后将相同的网格拓扑应用于3d顶点集。

答案 1 :(得分:2)

我已经实现了耳剪切算法如下:

  1. 迭代顶点,直到找到凸顶点,v
  2. 检查多边形上的任何点是否位于三角形内(v-1,v,v + 1)。如果有,则需要沿顶点v和距离线最远的点(v-1,v + 1)对多边形进行分区。递归评估两个分区。
  3. 如果顶点v周围的三角形不包含其他顶点,请将三角形添加到输出列表中并删除顶点v,重复直到完成。
  4. 注意:

    1. 即使在处理3D面部时,这本质上也是一种2D操作。要考虑2D中的问题,只需忽略具有最大绝对值的面法线的矢量坐标。 (这是您将3D面“投影到2D坐标”的方式)。例如,如果面具有法线(0,1,0),则忽略y坐标并在x,z平面中工作。
    2. 要确定哪些顶点是凸的,首先需要知道多边形的绕组。您可以通过找到多边形中最左边(最小的x坐标)顶点来确定这一点(通过查找最小的y来断开连接)。这样的顶点总是凸起的,所以这个顶点的缠绕可以让你绕过多边形。
    3. 使用带符号的三角形面积方程确定绕组和/或凸度。见:http://softsurfer.com/Archive/algorithm_0101/algorithm_0101.htm。根据多边形的绕组,所有凸三角形都具有正面积(逆时针缠绕)或负面积(顺时针缠绕)。
    4. 三角形点公式由有符号三角形区域公式构成。见:How to determine if a point is in a 2D triangle?
    5. 在步骤2中,您需要确定哪个顶点(v)离线最远,您可以通过形成三角形(L0,v,L1)并检查哪一个具有最大面积(绝对值)来实现,除非你假定一个特定的缠绕方向)
    6. 此算法没有很好地定义自相交多边形,并且由于浮点精度的性质,您可能会遇到这种情况。可以实现一些安全措施以确保稳定性: - 除非是凹点,否则不应将点视为三角形内部。 (这种情况表示自相交,你不应该沿着这个顶点划分你的集合)。您可能会遇到一个分区完全凹陷的情况(即它的缠绕与原始多边形的缠绕不同)。应该丢弃此分区。
    7. 由于算法是循环的并且涉及对集合进行分区,因此使用具有阵列的双向链接列表结构进行存储是非常有效的。然后,您可以在0(1)中对集合进行分区,但算法仍然具有平均O(n ^ 2)运行时。最佳案例运行时间实际上是需要多次分区的集合,因为这会迅速减少比较次数。

答案 2 :(得分:1)

triangulating concave多边形有一个社区脚本,但我个人并没有使用它。 author claims它适用于3D点和2D。

如果我想将问题约束为2D,我过去曾经使用的一个hack就是使用principal component analysis找到我的3D数据中最大变化的2个轴并将它们变成我的“X”和“ Y”。