凸包定义:
平面点集S的凸包定义为包含S中的所有点的最小凸多边形。
凸包问题:
- 给出点集S,求出S的凸包的顶点(极点)。
- 以顺(逆)时针方向输出求得的凸包的顶点。
算法:
- Graham扫描算法 ( O( n*logn) )
- QuickHull算法( O( n*logn) )
算法预备知识:
- 考虑从点p1=(x1,y1)到另一个点p2=(x2,y2)的有向线段<p1,p2>. 如果q=(x3,y3)是另外一个点。定义:q在<p1,p2>的左(右)边,若向量<p1,p2>与<p2,q>的外积大(小)于0
算法基本思想:
- Graham扫描算法 : 大体思路是将不是凸包顶点的点从点集中去掉。
- 找出S中具有最小y坐标的点p(通过选取最左边的点打破平局)
- 根据点和p的连线 与 x轴正方向所成的角度,对S中的点进行排序(由小到大),并将p放在最前面。
- 从p点开始扫描排序后的S集合。如果这些点都在凸包上,则每三个相继的点p1,p2,p3满足以下性质:p3在向量<p1,p2>的左边.如果出现相继的三个点p1,p2,p3不满足上述性质,则p2点一定不是凸包的顶点,应立即去除。
以下是Graham扫描算法具体实现:实现过程中使用了链表。实际上,使用双向链表会使得代码更加简洁,但同时会增加空间。 该算法实现面向过程。