快速凸包算法也可以看成是增量算法的一种变种,与随机增量算法相比,它们的不同就在于每次迭代从面的外部点集中选择的点不同。随机增量算法从外部点集中随机的选择一个点,但是快速凸包算法是选择距离最远的一个点,著名的开源代码Qhull[1]、 CGAL[2]都有快速凸包算法的C++实现。本篇文章介绍三维的快速凸包算法的原理和实现。
基本思想
在介绍快速三维凸包算法前,先介绍算法中会频繁使用到的两个基本的几何操作:
- 给定3个三维空间上的点,确定一个平面。
平面可以用方程
表示,设3个点分别是
,则有
,
,叉积的顺序影响法向量的方向,若
是零向量,说明
三点共线。
2. 计算三维空间上的点到平面的有符号距离。
设三维点为
,平面为
,那么点
到平面
的有符号距离表示为
。若
,称点P在平面上方(Above the Plane);若
,称点P在平面下方(Below the Plane);若
,称点P在平面上(On the Plane)。
快速凸包算法是基于Beneath Beyond理论,增量算法也同样基于该理论,该理论如下所示,这里只考虑三维空间下的凸包:
设
是一个
空间上的凸包,
是
上的一个点。
是凸包
上的面,当且仅当
-
是凸包的一个面且点在面的下方;
-
不是凸包的一个面,是由凸包的边和点构成,点在该边相邻的一个面的上方,在该边相邻的另一个面的下方。
若点
在
内,则
与
重合,显然,结论成立;若点
在
外,分为两种情况,以图1所示为例,
是由极点
构成的凸包,
是由极点
构成的凸包。对于凸包
来说,点
在三角形面片
,
,
,
的上方,点
在三角形面片
,
,
,
的下方,因此在边
,
,
,
一侧的面片是在点
的上方,另一侧的面片在点
的下方,我们称这样的边为临界边。当一个面
在
上时,若点
在面
的下方,则
是
的一个面,否则,它是由点
与临界边构成的面片。
快速凸包算法的伪码如下所示
用快速凸包算法求三维空间上的点集
的凸包
- 初始化一个由四个点构成的四面体;
- for 四面体的每个面
- for 点集中的每个未被分配的点