我有一个三角网。我想限制最大边长。因此,我采用长边(长度超过限制)的所有三角形,并将它们分成更小的三角形。
我的想法如下: 我将最长的边缘分成两半并得到两个三角形。如果这些也太大我递归地做。这很好用,因为我也拆分了相应的相邻三角形,并且顶点再次折叠。
问题:当存在锐角三角形时。结果看起来有点奇怪。小角度变得更小,......
是否有更好的方法来分割这样的三角形。 另一个想法是,将边缘分成k个等距边缘(k为最小值,使得边缘长度/ k <极限)。 我可以在三角形的所有3个边上执行此操作。但是我应该如何连接这些顶点呢?
答案 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)
结果如下: