计算几何笔记之凸包

计算几何笔记之凸包_第1张图片

Convex Hull(凸包)

在一个实数向量空间 V 中,对于给定集合 X ,所有包含X的凸集的交集 S 被称为 X 的凸包。

在二维欧几里得空间中,凸包可想象为一条刚好包着所有点的橡皮圈。

葛立恒(Graham)扫描法:

由最底的一点A_1开始(如果有多个这样的点,那么选择最左边的),计算它跟其他各点的连线和x轴正向的角度,按小至大将这些点排序,称它们的对应点为 A2 , A3 , . . . , An 。这里的时间复杂度可达 O(nlog n)。
考虑最小的角度对应的点 A3。若由 A2 到 A3 的路径相对 A1 到 A2 的路径是向右转的表示 A3 不可能是凸包上的一点,考虑下一点由 A2 到 A4 的路径;否则就考虑 A3 到 A4 的路径是否向右转……直到回到 A1。
这个算法的整体时间复杂度是 O(nlog n),注意每点只会被考虑一次.
这个算法由葛立恒在1972年发明。[1]它的缺点是不能推广到二维以上的情况。

算法实现思想:

我们首先要有一个 to_left_test的方法:

bool ToLeft(p,q,s);

假设p,q为极点,那么s一定位于pq连线的左侧,是则返回True,否则返回False.对于极边,非p,q的所有点都应满足这一条件。(对于判断是否在左侧,我觉得具体可以结合到斜率来判断)。
对于convex hull,其最下方(上,左,右同理)点一定是极点。我们可以让最下方点为Graham算法的起始极点A0。根据其他点与A0的角度从下到大来编号,从而继续进行Graham算法。A1也一定是极点。
我们应该维持两个栈S,T。S用于存放在当下满足极点要求的点,初始值为A0,A1。T存放还未判断的点(剩余的Ai逆序存放,即下标大的在栈底)。每次从T中pop出一个点Ai,满足ToLeft(S[-2],S[-1],Ai)==True,则push进S(所谓的LeftTurn),否则将S[-1]pop出,继续测试ToLeft(S[-2],S[-1],Ai)(所谓的RightTurn,进行了一次BackTrack).
最后S中的所有点都应该是极点。
计算几何笔记之凸包_第2张图片

参考链接:https://zh.wikipedia.org/wiki...
http://www.xuetangx.com/cours...

你可能感兴趣的:(计算几何)