Delaunay三角剖分其实并不是一种算法,它只是给出了一个“好的”三角网格的定义,它的优秀特性是空圆特性和最大化最小角特性,这两个特性避免了狭长三角形的产生,也使得Delaunay三角剖分应用广泛。
空圆特性其实就是对于两个共边的三角形,任意一个三角形的外接圆中都不能包含有另一个三角形的顶点,这种形式的剖分产生的最小角最大。
实现思路采用Bowyer逐点插入法实现:
代码实现思路如下
subroutine triangulate
input : vertex list 输入:顶点链表
output : triangle list 输出:三角形链表
initialize the triangle list 初始化三角形链表
determine the supertriangle 确定超级三角形
add supertriangle vertices to the end of the vertex list 将超级三角形的顶点加入到顶点链表中
add the supertriangle to the triangle list 将超级三角形加入到三角形链表中
for each sample point in the vertex list 对顶点链表中的每一个点
initialize the edge buffer 初始化边数组
for each triangle currently in the triangle list 对于三角形链表中的每一个三角形
calculate the triangle circumcircle center and radius 计算出外接圆圆心和半径
if the point lies in the triangle circumcircle then 如果这个点在三角形的外接圆内
add the three triangle edges to the edge buffer 把这个三角形的三条边加入到边数组中
remove the triangle from the triangle list 从三角形链表中将这个三角形删除
endif
endfor
delete all doubly specified edges from the edge buffer 把边数组中所有重复的边都删除,注意这里是把所有的重复边都删除,比如有边e1,e2,e2,e3,删除后应该只剩e1和e3
this leaves the edges of the enclosing polygon only 这步会得到一个闭合的多边形
add to the triangle list all triangles formed between the point 用这个点和边数组中的每一条边都组合成一个三角形,加入到三角形链表中
and the edges of the enclosing polygon
endfor
remove any triangles from the triangle list that use the supertriangle vertices从三角形链表中删除使用超级三角形顶点的三角形
remove the supertriangle vertices from the vertex list将超级三角形的顶点从顶点链表中删除
end
理解思路如下:
我们需要进行三角形剖分的四个点(A B C D)如下,在他们外面建立一个足够大的超级三角形PQR
分析A点,因为A点在PQR超级三角形内部,把A点和PQR三点分别连线;
再考虑B点,看B点在哪个子三角形的内部,结果发现只在AQR三角形内部,于是B点分别和AQR这个三角形的三个顶点连线
到现在我们可以看到有五个三角形,分别画出这五个三角形的外接圆,对C点检查是否在这五个三角形的外接圆内
结果发现它在三角形APR和三角形ABR的外接圆内
上述可发现C点在APR和ABR的外接圆内,则删除这两个三角形的公共边AR,然后从C点分别向这两个三角形组合起来的
四边形的四个顶点连线,得到下图
接着对D点进行分析,发现该点在三角形ABC和三角形BCR的外接圆内
再用D点和这两个三角形组成的四边形连线,并且删除这两个三角形的公共边,得到下图
最后把含有超级三角形PQR顶点的三角形全部删除,得到三角形剖分结果如下