Voronoi图的定义
2.给定平面上n个点的点集S={p1,p2,……pn}。定义V(pi)是所有j(i!=j)的H(pi,pj)的交集,即V(pi)表示比其他点更接近于pi的电的轨迹是n-1个半平面的交,这是一个不多于n-1条边的凸多边形区域,称为关联于pi的Voronoi多边形(域)
Voronoi图的特点:
1.Vor(S)把平面划分成n个多边形域,每个多边形域V(pi)包含且只包含S的一个点pi。
2.Vor(S)的边是S中某对点的中垂线的一个线段或者射线。
3.V(pi)是无界的,当且仅当pi属于凸包外界的点集。
4.Voronoi图至多有2*n-5个顶点和3*n-6条边。
5.每个Voronoi点恰好是三条Voronoi边的交点(假如任何四点都不共圆的话)。也就是说Voronoi点就是形成三边的三点的外界圆圆心,而且所有的这些外界圆有个特点:各自内部不含任何S点集的点(空心圆)。
利用第5条性质就可以线性扫描Voronoi图,解决最大空心圆问题。
Voronoi图在计算几何里的实现一般是用双向循环链表维护Voronoi图的有向边;生成时候利用分治思想,不过内部超级复杂,要求正切线(复杂度O(n)),构造穿梭的折线确定相交的边,删除释放、合并。有一种很巧妙的构造折线的方法(三角形顶点转移法)有利于降低代码编写难度。
Delaunay三角剖分
Delaunay三角剖分与Voronoi图互为偶图,也就是一一对应,这里我们先了解一下Voronoi图。
这里给出它的数学定义:[2](可以不看)
令P = {P1,P2,…,Pn}为平面域(R^2)上n个离散点的集合,一个完整的Voronoi图应该由多个Voronoi多边形组成,第i个Voronoi多边形的数学表达形式如下:
Vi = { x ∈R^2 : ||x – Pi|| <= ||x – Pj|| , j=1 ,…,n; j ≠ i }
式中,i = 1,2,…,n ,||x – Pi||表示平面域上点x和节点Pi之间的欧氏距离。从上式可知,Voronoi多边形Vi内任意点x到节点Pi的距离比到点集P中任何其他节点的距离更近,因此Vi由节点Pi和每个相邻节点的垂直平分线所形成的开式半平面的交集组成,故Vi必为凸多边形。
这段数学表述看懂了吗,如果看懂了,恭喜你,你很棒,如果还有些含糊,也没什么,其实Voronoi图就是由每个节点到相邻节点的垂直平分线组成的多边形构成的一个多边形集合,还有些迷糊,没关系,接着往下看,这里给出一个8节点的Voronoi图,其中的实线部分正是各个多边形。
一般情况下,Voronoi图的一个顶点同时属于三个Voronoi多边形,每个Voronoi多边形内有且仅有一个节点。连接三个共点的Voronoi多边形分别对应的三个节点则形成一个Delaunay三角形,所有这样的三角形的集合就是著名的Delaunay三角剖分。上图中的虚线部分就是与该Voronoi图对偶的Delaunay三角剖分。
Delaunay剖分出来的三角形网具有以下特征:[3]
1. Delaunay三角网是唯一的;
2. 三角网的外边界构成了点集P的凸多边形“外壳”;
3. 没有任何点在三角形的外接圆内部,反之,如果一个三角网满足此条件,那么它就是Delaunay三角网;
4. 如果将三角网中的每个三角形的最小角进行升序排列,则Delaunay三角网的排列得到的数值最大,从这个意义上讲,Delaunay三角网是“最接近于规则化的”的三角网。
从上面的算法和特征可以看出该剖分算法对于带洞多边形等非简单多边形不适用,会产生一些多余的三角形,假如上图中外面的一圈五个顶点构成带洞多边形的外环,而内部的三个顶点构成内环,则会多剖分出来一个三角形.
Delaunay剖分出来的三角形网具有很好的特性,但这些对于我这个应用来说并不那么重要,我的目标是让D3D帮我渲染出多边形,至于什么唯不唯一、规不规则并无大碍。
该算法的优点于我并不重要,而缺点于我却至关重要,因此结论是不选用该方法。
其它三角剖分
对于简单多边形,有基于凹凸顶点判定的方法,就是判定多边形的每一个顶点是凹点还是凸点,发现凹点后,判断凹点之后两边能否形成三角形,如不行则继续寻找凹点;如果可以形成三角形,记录下三角形并将其移去,继续寻找凹点,直到分解完毕或没有凹点,没有凹点的凸多边形可由任意一点引线段将凸多边形分割。这种方法适用范围有限并且有特例不能分解,特例如下图。[5]
当然基于凹凸顶点判定的方法不是仅此一种,但在我找到的论文中就发现了这一个,还是作为反例出现的。
其它的对于非简单多边形的剖分算法基本上思路是一致的,就是连接内外环,化非简单多边形为简单多边形[1][5],然后再用其它的方法来处理简单多边形,例如基于凹凸顶点判定等等,以下两幅图给出了一个大致的思路。