【问题标题】:Split a triangle into smaller triangles将三角形分割成更小的三角形
【发布时间】:2014-09-08 11:35:35
【问题描述】:

我有一个三角网格。我想限制最大边长。因此,我将所有具有长边的三角形(长于限制),并将它们分成较小的三角形。

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

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

有没有更好的方法来分割这些三角形。 另一个想法是,将一条边分割成 k 个等距边,(其中 k 是最小值,使得边长/k

【问题讨论】:

  • 澄清一下,您正在寻找一条长边,在该边上找到中心点,并且(这是我不太清楚的部分)将该中心点连接到连接到该边的三角形之一。这是正确的吗?
  • 看起来您无法在此处制作出相当好的 all 子三角形 - 但您可以剪掉格式不正确的三角形并对剩余的梯形进行三角剖分。我会说:没有内部顶点 - 为什么需要它们?
  • 在您的第二种方法中,您首先标记可能要拆分的点。如何确定它的优先级,以便在所有可能首先在这些点之间绘制的边缘中绘制 最短 的边缘?然后根据需要拆分新边缘,并添加到潜在边缘池中。重复该过程。 (虽然不知道如何有效地实施)

标签: algorithm geometry computational-geometry triangulation


【解决方案1】:

由于您对小角度和小三角形感到困扰,我建议您使用Delaunay triangulation,因为它的一个属性是它可以最大化最小角度并避免小三角形。

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

以下 Python 代码完全符合您的要求。 它使用 scipy 中包含的Delaunay class

    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)

这是结果:

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-06-08
    • 1970-01-01
    • 2011-03-29
    • 1970-01-01
    • 1970-01-01
    • 2016-02-08
    • 2014-01-21
    相关资源
    最近更新 更多