计算几何之凸包----Graham扫描法

计算几何之凸包(convexHull)----Graham扫描法
关于凸包的严格定义,这里不打算写出来,大家可以自行Google或者百度,因为严格的数学定义反而不太好理解,用最通俗的话来解释凸包:给定二维平面上的点集,凸包就是将最外层的点连接起来构成的凸多边型,它能包含点集中所有的点。如图所示(图片来自wiki)

凸包最常见的应用是求平面上距离最远的两个点,一般有两种算法来计算包含n个点的点集的凸包。这种两种算法都是按逆时针方向的顺序输出凸包。第一种算法就是接下来要介绍的Graham扫描法(Graham's scan),时间复杂度为O(nlgn)。第二种算法是Jarvis步进法(Jarvis march),时间复杂度为O(nh),其中h为凸包顶点的个数。第二种算法下次介绍,先介绍Graham扫描法(Graham's scan):
Graham扫描法主要用一个栈来解决凸包问题,点集Q中每个点都会进栈一次,不符合条件的点会被弹出,算法终止时,栈中的点就是凸包的顶点(逆时针顺序在边界上)。该算法具体步骤为:
先给出算法导论中的算法步骤:
计算几何之凸包----Graham扫描法_第1张图片


















下面是我自己理解的步骤:
1、先选出点集中y坐标最小的点记为,

如果y坐标相同则相同点中x坐标最小的点

2、把按照极角(polar angle)从小到大排序(以  为极点),极角相同的点按照到的距离从小到大排序。
3、把压入栈。
4、遍历剩下的点,while循环把发现不是凸包顶点的点移除出去,因为当逆时针遍历凸包时,我们应该在每个顶点向左转。因此当while循环发现在一个顶点处没有向左转时,就把该顶点移除出去。至于如何判断向左向右则是根据叉积来判断,好吧,看来又出现了一个新概念,又要介绍下叉积。。。。其实对极角排序,也是根据叉积来判断的。如下图所示的向量我们可以把叉积理解为由点(0,0),+=所构成的平行四边形有向面积.

计算几何之凸包----Graham扫描法_第2张图片







比较简洁的定义是矩阵行列式:,若值为正,则相对原点来说,右侧(顺时针方向),值为负,左侧(逆时针方向)。所以相对公共端点,可以计算叉积

如果叉积为正,右侧。为负,左侧。好吧。。。终于把叉积介绍完了,只能说画图写公式真的很费时间,所以请尊重原创,真的不容易!!!
下面介绍如何用叉积确定向左转还是向右转,其实把上面的叉积介绍了下,也差不多了,因为凸包顶点必然都是向左转,不能向右转。简答贴一段算法导论中的介绍,脑补一下吧:
计算几何之凸包----Graham扫描法_第3张图片

基本上把叉积介绍完了,回到寻找凸包上,把graham扫面的算法也介绍了,这时候其实已经可以撸代码了,但是为了让路过的同学更清晰明白算法的执行过程,放个步骤图:
计算几何之凸包----Graham扫描法_第4张图片

计算几何之凸包----Graham扫描法_第5张图片
计算几何之凸包----Graham扫描法_第6张图片
看完步骤图应该很清晰明了,希望能帮助大家。

下面给出模板代码:放在了GitHub上:https://github.com/tz28/ConvexHull





具体应用请关注下一篇博客。http://blog.csdn.net/u012328159/article/details/50809277

你可能感兴趣的:(algorithm&data,structure)