凸包算法综述

  凸包算法综述

1.         凸包问题

凸包问题可以描述为:给定一个点集P,求最小点集S,使得S构成的形状能包含P[1]。一般的研究主要针对二维平面上和三维空间上的凸包,因为他们在更多的应用中能发挥作用。

凸包的定义为:平面的一个子集S被称为是“凸”的,当且进当对于任意两点p,q∈S,线段 都完全属于S。几何S的凸包CH(S),就是包含S的最小凸集,更准确地说,它是包含S的所有凸集的交[2]。由此还可以推出凸包的很多性质,包括一条直线如果与凸包相交(不是相切)的话,最多交于两条边或者两个面。其他可见性等性质将在第4节介绍。

本文中,我们假设:凸包上的每个平面的法向量朝外,或者说都是半平面;因此某个点到面对距离有可能为负,当p点和面的法向量不处在同一侧时,p点到面的距离为负,距离计算公式为点点乘平面法向量在加上平面d值。此外,所求得到凸包为流形,1条边最多只能连接2个面。

 

2.         传统算法

计算几何的算法,大致可以分为增量法和分治法。

 

2.1 增量法

增量法就是一直k个顶点的解集,与第k+1个顶点合并得到新的解集。分治法解决凸包问题有两个方向,无序地增加顶点和Gift-Wrapping查询。

 

2.1.1 增点法

直接使用增量法的思想,可以将凸包算法简述为:

(1)       遍历所有点

(2)       对于新增加的每个点p,分析其是否在当前构成的凸包内,如果在则直接忽略该点,如果不在则将当前凸包和p整合成一个新的凸包。

为了加快平均速度,可以使用随机的顺序增加顶点[3]~[8]

可以想到,整合时,可能会删去原有凸包中的某些点。

对于二维的凸包,由于二维平面上可以增加很多判断,所以直接增加顶点不是一个理想的方法。但三维空间内求凸包时,这种算法是比较常见的。

判断点pr是否在凸包CH(Pr-1)内,只要判断p是否在CH(Pr-1)每个面的背面(点与面点乘为负数)。即如果它在某个面的正面,它必在CH(Pr-1)外。

若点p在凸包CH(Pr-1)外,则需要整合凸包与点p,即求CH(Pr-1)p组成的新凸包CH(Pr),此时需要删除合成后处在CH(Pr)内的CH(Pr-1)的点和面,即删除在凸包上相对于p点的“可见面”,再连接p点和所有的“地平线”,最终构成新的凸包。

这里的“可见面”并不是三维中的是否可见,因为只有视点p而没有视向量。判断“可见面”的依据是p点和需要判断的面的法向量处在同一侧,即判断点到面的距离是否为正。

而“地平线”指的是符合以下条件的边:它连接的2个面一面对于p可见而另一面不可见。也有文章反过来想象,把p与原凸包整合好后,原来相对于p“可见”的面都会被包含在凸包中,因此需要把这些面删除。删除后原凸包上会出现一个洞,这个洞就是有“地平线”组成的,因此可以通过把p和地平线连接来修补破洞的凸包。

为了加速整合时的处理,可以利用“冲突图”来记录点和面对可见关系。冲突图实质是一个二分图,一边是目前凸包上的面,另一边是目前为考察的顶点;如果面对与点可见,则将它们连接。初始时通过完全遍历建立一个最初四面体和剩余点的冲突表(需要线性时间);在每次考察点p时,如果p在冲突表内没有面与它相连,则说明p在凸包内部;整合时,可以直接得到p的所有可见面;而插入新的面到凸包后,只需要考察新面上地平线两边面对可见点,得到新面的可见点集合。具体过程参考文献[2]

 

2.1.2 Gift-Wrapping查询

Gift-Wrapping查询暂时限定在二维平面上,表述为:给定点集s,点q和过q的直线l,问l沿顺时针方向绕q旋转,第一个碰到的点是哪一个[9]

如果p为凸包上的点,且Gift-Wrapping查询得到的点为p,则s中的其他点必在pq的同一侧,就是说,q也为凸包上的点,且pq为凸包上的一条线。由此,可以得到一种较简单的凸包算法:由s的最左点p1开始,循环进行Gift-Wrapping查询,将得到的点加入凸包,循环至查询到p1点为止。

Gift-Wrapping查询引申到递增式策略,可以得到复杂度更小的算法:

(1)       将所有点由左至右排序,得p1, p2, … , pn

(2)       p1出发,一次遍历连接点,当出现V型时,去掉下部的点,直接连接上部的点。

(3)       遍历至pn,可得到凸包的上半部分。

(4)       反过来由pn遍历至p1,与(2)部原理相同,可得到凸包的下半部分。

如果直接将二维情况扩展到三维,则Gift-Wrapping查询应该是给定一个凸包上的面和一条边,求面绕边碰到的第一个点,不断利用Gift-Wrapping查询扩展也可构造三维凸包。但将其递增式策略是在三维空间有很多种连接方式和可能,目前没有找到参考文献。

 

2.2 分治法

2.1.1 基本分治法

分治法是一种很基础的算法。基本思路是将问题分解为等价的几个子问题,对子问题进行递归分解和求解,然后将子问题的解合成为所求的解。

由此,可以得到一种最简单的凸包分治算法:将点集依照某种划分方法分为N部分,对每个部分求子凸包,最后将几个子凸包合成一个更大的凸包。

这样的算法有两个优势:

首先,在计算子凸包时,可以去除很多已经在子凸包内的点,这种情况在点集很大时非常有效。

其次,需要合并的本身已为凸包,如果选择了合适的划分方式,则可以更快得合并。

这类的算法具体实现方式有许多。如M2M[10]算法,在二维平面上以栅格形式划分点集,并且在预处理时已经建立起了多分辨率式的映射关系,所以成块地删除和合并点集操作非常快,在预处理后利用分治法求凸包也可以起到加速的作用。而文献[11]中也就二维和三维的凸包点集合并提供了很多方法,包括将二维子凸包连接成三维凸包,利用Gift-Wrapping查询式的角度查询合并二维或三维的凸包。

 

2.1.2 Quick Hull算法。

分治法的另一个引申是QuickHull算法[1]

二维QuickHull思想如下:

(1)       在候选点点集中,在各坐标系上数值最大最小的点,我们称为极点。

(2)       对于凸包上的每条直线,取朝外的方向为正,因此每条线段也有一个垂直于它的朝外的“法向量”,我们称为扩展向量,同理每个点到直线的距离也有正负。

具体步骤如下:

(1)       选取2个极点。生成1条直线和2个扩展向量。把其他点分别分派到2个方向上,即如果该点到这个扩展方向为正,则将点分派到这个方向上。

(2)       每次扩展,取一个扩展向量,以及扩展向量末端的直线和分派到的点集Vs。选取离直线距离最远的点p,连接p跟直线的2端,生成新的2条直线,得到2个新的扩展方向,并把Vs中的其他点按照a)的规则分派到新的扩展向量上。

(3)       重复到每个扩展向量都没有点可以扩展时,结束。重复k次得到的凸包边数为k+2

(4)       证明(详见QuickHull的论文):

(5)       极点在最终的凸包上。

(6)       每次扩展取得最远点在最终的凸包上。

(7)       每次把点分治到不同的扩展向量上,理论上复杂度类似分治算法,为O(k log n)k为凸包的顶点数。

 

根据论文,QuickHull是可以扩展到任意R维的。只是要求初始化的时候建立一个R+1的几何体,此外每次加入后,还需要整合。

就是说,要生成三维的凸包,需要先构造一个四面体并分派候选点给各面,再按照4.1里边所提到的步骤b)开始执行。

这里说明一下为什么要把初始化搞得那么复杂。因为对于二维,对于取了2个极点的直线,不可能存在第3个点共线且在凸包上而且是必须的(如果共线的话应该在2个极点组成线段上了,可以不算入凸包)。而对于三维则不一定。最简单的例子,为一个立方体求凸包,可能取到3个极点在底面上,此时地面上第4个点无从分派,但它又是必须的。

为此,可以先求2个极点,组成直线;再求到直线距离绝对值最大的点,组成面;再求到面距离绝对值最大的点,组成四面体。

二维时,一个为扩展到点最多可以见到当前凸包上的一个面。如下图,β为当前凸包,相对于ABCB边都可见点区域只有α,而当α存在点时,B不能为最终凸包上的点。

三维情况则不同,如下图,如果已求得的凸包为ABCD,此时E点相对于ABCACD都是可见的,而且ABCDE都是必须的。因此扩展E点入凸包时,同样需要进行类似增量法的整合。

 

2.3 三维凸包的实现与效果

 

文献[1]中有QuickHull与随机增量法的对比。

本文利用VS2005也做了QuickHull与一般增量法计算三维凸包的简单程序。程序中利用半边表结构记录三维数据,用哈希表记录记录冲突表。实验机器配置:奔42.4G CPU 1G内存。下图为运行结果。

这里一共有三种方案,“增量法”为顺序增量。“QuickHull”为基本思路实现的QuickHull算法。

在理论上,增量法和分治法的时间复杂度上并没有很大区别。但是实际操作中,因为整合时需要查找相邻面和边,因此需要建立半边表之类的数据结构,而这样结构的操作是最耗时的。而在QuickHull算法中,整合的次数要少得多,因此以QuickHull算法为基础来做会更快些。

“冲突表+QuickHull”为利用冲突表排除在凸包内点集的方法。QuickHull过程中,会将待判断的点“分配”到当前的不通平面。分配时,一个点p可以分配到多个平面上,凡是p点“可见”的面都符合条件。而当选定点q做为扩展点时,需要删除q点所有的可见面做为整合。因此,同样利用冲突表记录点和面的可见关系,可以提高计算速度。

 

3.         凸包问题的一些新进展

[12]已经证明,凸包问题的复杂度与排序问题的复杂度等价,都为O(nlogn)。但是提高凸包计算速度的研究并没有中止。

一方面,可以利用预处理来加快点剔除的速度,这类方法对于分治类算法特别有效。[10][13]都是这方面的例子。[10]的方法是利用栅格将为点建立所属范围及映射,当某个范围处在凸包内部时,利用索引剔除整个范围内的所有点。[13]则是利用矩形和斜线方程合并的方法取得凸包内的一个极大四边形,也可以大量剔除凸包内的点。

此外,也有很多学者希望利用并行计算的方法提高凸包计算速度。[11]中的合并方法已经可以使用于二维和三维凸包的并行进算。数据结构方面,可以使用决策树或者BSP[14]来记录各个子结果。[15]中提到的并行算法已经将复杂度降低至O(logn),并由二维扩展到三维。

此外还有一些有意思的分支,例如[9]中解决了求移动中点的凸包的问题。它采用了KDS结构,这种结构在排序算法上有优势,因此可以记录移动中点的部分信息,利用KDS得到有序数列,然后求凸包。

 

4.         凸包的特性和应用

除了第1节中提到的特性外,这里再对凸包的几何特性做简单分析。

凸包是一个原点集的一个较小的子集,而且凸包上的点都落在物体的外围。因此,凸包点集带有一定的“特征性”。有向包围盒(OBB)算法中,就是先计算物体的凸包,在求凸包的特征向量并借包围盒方程。

同时,凸包的求交运算也相对简单,可以判断点是否在凸包内(直接判断点乘结果的正负)。文献[16]有更加详细的介绍。

从三维的角度上说,绘制一个凸包,可以只做背面剔除而不管遮挡剔除。想象一下:如果手拿一个凸包旋转,不能看到的面一定是法向背向自己的。这可以引申出很多结论:例如绘制一个凸包的某个面时,只有完全绘制和完全不绘制两种可能,不会出现某个面部分遮挡住某个面的情况;判断是否需要绘制时,只需要判断法向。为此,利用凸包进行模型简化也是一个不错的方向,因为可以直接用带alpha通道的纹理进行映射,即可以大限度的减少面数,也可以减少顶点消失对纹理的影响。

 

参考文献

[1] Barber C. B., Dobkin D. P. and Huhdanpaa H. The Quickhull Algorithm for Convex Hulls. ACM Transactions on Mathematical Software, Vol. 22, No. 4, December 1996, P 469483.

[2] Berg M. D., Kreveld M. V., Overmars M., Schwarzkopf O. Computational Geometry Algorithms and Applications(Second Edition). 计算几何——算法与应用2. 邓俊辉 . 2005. P 5. P262-278

[3] Chazelle B. and Matousek.J.. Randomizing an output-sensitive convex hull algorithm in three dimensions. Tech. Rep. TR-361-92, Princeton Univ., Princeton, N.J. 1992.

[4] Clarkson K. L., Mehlorn K., and Seidel R. Four results on randomized incremental constructions. Comput. Geom. Theory Appl. 3, 185211. Also in Lecture Notes in Computer Science. Vol. 577, pp. 463474. 1993.

[5] Edelsbrunner, H. AND Shan, N. Incremental topological flipping works for regular triangulations. In Proceedings of the Symposium on Computational Geometry. ACM, New York, 4352. 1992.

[6] Guibas, L., Knuth, D. and Sharir, M. Randomized incremental construction of Delaunay and Voronoi diagrams. Algorithmica 9, 534560. 1992.

[7] Joe, B.. Construction of three-dimensional Delaunay triangulations using local transformations. Comput. Aided Geom. Des. 8, 123142. 1991.

[8] Mulmuley, D. Computational Geometry, An Introduction through Randomized Algorithms. Prentice-Hall, Englewood Cliffs, N.J. 1994.

[9] M. A. Abam and M. d Berg. Kinetic Sorting and Kinetic Convex Hulls. SCG’05, June 6–8, 2005, Pisa, Italy.

[10] Y. P. Zhang, Z. Z. Zhang, and Q. Chen. A New Randomized Parallel Dynamic Convex Hull Algorithm based on M2M model. International Conference on Convergence Technology and Information Convergence, 2007, in-cooperation with ACM SIGAPP. 2007

 

[11] F. P. Preparata and S. J. Hong. Convex Hulls of Finite Sets of Points in Two and Three Dimensions. Communications of the ACM. February 1977, Volume 20, Number 2.

[12] F. Preparata and M. Shames. Computational Geometry. Springer, New York, 1985.

[13] M Golin and R. Sedgewick. Analysis of a Simple Yet Efficient Convex Hull Algorithm. Proceedings of the fourth annual symposium on Computational Geometry.

[14] M. T. Goodrich. Randomized Fully-Scalable BSP Techniques for Multi-Searching and Convex Hull Construction. Proceedings of the eighth annual ACM-SIAM symposium on Discrete algorithms. 1997

[15] N. M. Amato and F. P. Preparata. An NC1 Parallel 3D Convex Hull Algorithm. 9th Annual Computational Geometry,5/93/CA, USA. 1993.

[16] 郑立垠 and 张丽. 基于凸包特征的细分曲面求交研究. 计算机工程与设计. 29卷第1. 20081

  • 3
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 10
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值