很多人都有这样的习惯,当要做一件自己没有接触过的事情时,先不着急下手从零做起,而是通过各种渠道去了解这个问题是否已经有人思考过,并且是否已经很好的解决了,或者能否给自己一些启迪。这是个好习惯,但是在参考别人的解决方案时要保持一个旁观者的心态,并时刻注意哪一部分对我有用,有多少用,他这样做的好处是什么,这样做的不足又是什么,我所处理的问题是否和他面对的完全一致,出入在什么地方,切不可拿来主义!
    我就有这样的习惯,下面是对我在刚接触任意平面多边形三角剖分这个问题时找到的一些解决方案的分析,其中不乏经典。

一、三角剖分的定义
    谈到三角剖分,不得不先摆一下它的定义:[1]
    1. 产生的三角形不相重叠;
    2. 不产生新的顶点。
    这样的一个定义并不必那么教条,达到这样的目标是好的,但如果考虑到其它的一些因素,比如说通用性、复杂度、性能等等,可以适当的违反一些,三角剖分的目的就是一个:用三角形拟合多边形。
    一般来说第一条是不该违反的,毕竟产生的三角形有重叠部分就可以将其进一步分解成无重叠。但第二条遵守起来就不那么容易了,就在摆出这个定义的同一篇文章,也就是参考文献1,它给出的算法就可能产生额外的顶点。
    在本专题下一篇文章中我将会阐述我提出的新算法,你将发现,通过这样的算法进行处理,产生的不规则三角形网严格遵守第一条,但严重违反第二条!但是这个算法有一个好处,就是从更广泛的意义上做到了对任意多边形的处理。如果你读过本专题的首页,会发现我提出了一种新的多边形:分离多边形。分离多边形是由不相交的多个多边形组合为一个逻辑主体,以一个整体的形式对外表示。对于这样的多边形该算法仍然能够很好的工作,在算法看来,它与其它多边形没有什么区别,其实,算法并不关心多边形的类别,哪个顶点是凹的,哪个顶点是凸的。呵呵,提到自己的算法多少有些激动,话多了些,回到本篇的主题,关注一下别人的算法,回望经典。

二、Delaunay三角剖分

Boris Delaunay
生于: 1890年3月15日
圣彼得堡 
卒于: 1980年7月17日
莫斯科 
    谈到三角剖分,这个名字你不得不熟悉,这就是经典。
    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三角网是“最接近于规则化的”的三角网。
    从上面的算法和特征可以看出该剖分算法对于带洞多边形等非简单多边形不适用,会产生一些多余的三角形,假如上图中外面的一圈五个顶点构成带洞多边形的外环,而内部的三个顶点构成内环,则会多剖分出来一个三角形,为了让该算法更普适一些,很多人做出了努力,如[2][4]等等。
    由于这个算法普适性差,优化算法较为晦涩,所以望而生畏了,由于我看的是论文,这种行文方式令我大为不爽,可能没有很好的领会作者的精妙思想,在此强烈呼吁各位论文作者,在完成论文后,能否用通俗易懂的话来表达一下你们的思想,一定要那么学究吗?
    跑题了~
    Delaunay剖分出来的三角形网具有很好的特性,但这些对于我这个应用来说并不那么重要,我的目标是让D3D帮我渲染出多边形,至于什么唯不唯一、规不规则并无大碍。
    该算法的优点于我并不重要,而缺点于我却至关重要,因此结论是不选用该方法。
 

三、其它三角剖分
    对于简单多边形,有基于凹凸顶点判定的方法,就是判定多边形的每一个顶点是凹点还是凸点,发现凹点后,判断凹点之后两边能否形成三角形,如不行则继续寻找凹点;如果可以形成三角形,记录下三角形并将其移去,继续寻找凹点,直到分解完毕或没有凹点,没有凹点的凸多边形可由任意一点引线段将凸多边形分割。这种方法适用范围有限并且有特例不能分解,特例如下图。[5]  


    当然基于凹凸顶点判定的方法不是仅此一种,但在我找到的论文中就发现了这一个,还是作为反例出现的。
    其它的对于非简单多边形的剖分算法基本上思路是一致的,就是连接内外环,化非简单多边形为简单多边形[1][5],然后再用其它的方法来处理简单多边形,例如基于凹凸顶点判定等等,以下两幅图给出了一个大致的思路。 



 
四、总结
    说了这么多,其实只是涉及到了这个领域的冰山一小小角,我看到的算法都或多或少的与我的需求有出入,于是就开始构思一种概念简单,实现方便,性能优良,适用度广的剖分方法,幸而我找到了这样的一种方法,并且在实际运用中表现不俗,从下一篇开始我将详细的阐述这个算法。

五、参考文献:
1. 徐春蕾, 李思昆 . 一种适用任意平面多边形的三角剖分算法[J] . 国防科技大学学报 . 第22卷第2期
2. 丁永祥,夏巨湛,王英,肖景容 . 任意多边形的Delaunay三角剖分[J] . 计算机学报. 第17卷第4期
3. http://baike.baidu.com/view/501103.htm
4. 涂治红, 桑农 . 用VC语言实现任意多边形的Delaunay完全三角剖分算法. 计算机与数字工程. 第33卷
5. 陈向平, 应道宁. 任意多边形三角剖分算法[J]. 浙江大学学报. 第六期第22卷. 1988年11月

 

 posted on 2008-03-27 11:21  floodpeak  阅读(4721)  评论(25编辑  收藏  举报