将三角形拆分为较小的三角形

时间:2014-07-17 14:24:35

标签: algorithm geometry computational-geometry triangulation

我有一个三角网。我想限制最大边长。因此,我采用长边(长度超过限制)的所有三角形,并将它们分成更小的三角形。

我的想法如下: 我将最长的边缘分成两半并得到两个三角形。如果这些也太大我递归地做。这很好用,因为我也拆分了相应的相邻三角形,并且顶点再次折叠。

问题:当存在锐角三角形时。结果看起来有点奇怪。小角度变得更小,......

enter image description here

是否有更好的方法来分割这样的三角形。 另一个想法是,将边缘分成k个等距边缘(k为最小值,使得边缘长度/ k <极限)。 我可以在三角形的所有3个边上执行此操作。但是我应该如何连接这些顶点呢?

1 个答案:

答案 0 :(得分:3)

当你被小角度和小三角形困扰时,我会建议你使用Delaunay triangulation,因为它的一个属性是它最大化了最小角度并避免了小三角形。

Delaunay三角测量需要点作为输入。由于你没有这个,你可以递归地执行算法,当它们太长时将它们分开。

以下Python代码完全符合您的要求。

def splitViaDelaunay(points, maxLength):
    from scipy.spatial import Delaunay
    from math import sqrt, ceil
    print "Perform Delaunay triangulation with "+str(len(points))+" points" 
    tri = Delaunay(points)
    # get set of edges from the simpleces
    edges = set()
    for simplex in tri.simplices:
        # simplex is one triangle: [ 4  5 17]
        edges.add((simplex[0], simplex[1]))
        edges.add((simplex[1], simplex[2]))
        edges.add((simplex[0], simplex[2]))
    # check if all edges are small enough
    # and add new points if not
    isFinished = True
    for edge in edges:
        p1, p2 = edge
        [x1, y1] = points[p1]
        [x2, y2] = points[p2]
        length = sqrt((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1))
        if length > maxLength:
            isFinished = False
            # split in how many pieces?
            nPieces = ceil(length/maxLength)
            for piece in range(1, int(nPieces)):
                points.append([x1+piece/float(nPieces)*(x2-x1), y1+piece/float(nPieces)*(y2-y1)])
    if not isFinished:
        splitViaDelaunay(points, maxLength)

让我们尝试一下。

points = [[0,0], [10,3], [9.5,4]]
splitViaDelaunay(points, 0.5)

输出

Perform Delaunay triangulation with 3 points
Perform Delaunay triangulation with 45 points
Perform Delaunay triangulation with 97 points
Perform Delaunay triangulation with 105 points

现在让我们在图中看到结果,通过python的matplotlib库创建。

def plotPointsViaDelaunayTriangulation(pnts):
    from scipy.spatial import Delaunay
    import numpy as np
    points = np.array(pnts)
    tri = Delaunay(points)
    import matplotlib.pyplot as plt
    plt.triplot(points[:,0], points[:,1], tri.simplices.copy())
    plt.plot(points[:,0], points[:,1], 'o')
    plt.show()

plotPointsViaDelaunayTriangulation(points)

结果如下:

Output of Delaunay triangulation