凸包
1. 定义:
凸多边形:
过多边形的任意一边做一条直线,如果其他各个顶点都在这条直线的同侧,则把这个多边形叫做凸多边形。
凸包即构成凸多边形的点构成的集合,点称为极点,边称为极边。
2.求解凸包的高效算法:
(1)Jarvis March
纵坐标最小横坐标最小的点一定是凸包上的点记为P0。
把剩下的点按照 点到P0的连线与水平线夹角 的大小进行排序。
最小的就是下一个凸包上的点。
将下一个凸包上的点当做P0,重复上述操作直至回到P0。
时间复杂度为O(nH),和凸包上点的个数有关。
(2)Graham Scan
此算法也需要先找到P0,并以P0为原点建立直角坐标系。
然后进行预处理,即将各个点根据与x轴夹角大小排序。
将P0,P1入栈。
从按照极角排好的集合里,把 P1,后面的那个点拿出来做当前点,即P2。
然后进行以下步骤:
1.连接栈顶的点与次栈顶的点,得到直线L。看当前点是在直线L的右边还是左边。
如果在直线的右边就执行步骤2;
如果在直线上,或者在直线的左边就执行步骤3。
2.如果在右边,则栈顶的那个元素不是凸包上的点,把栈顶元素出栈。执行步骤1。
3.当前点是凸包上的点,把它压入栈,执行步骤4。
4.检查当前的点Pi是不是步骤3那个结果的最后一个元素。
是最后一个元素的话就结束。如果不是的话就把 Pi后面那个点做当前点,返回步骤1。
(即判断栈顶与次栈顶连线与当前点的位置关系,若在右侧则将栈顶出栈,继续比较,直到在线右侧。当当前点为最后一个点则结束)
最后栈中元素就是凸包上的点。
时间复杂度为O(nlogn)
(3)Andrew
和Graham Scan相比数值稳定性更好。
首先把所有点按照 Leftmost Then Lowest 原则排序,删除重复点后得到序列P1,P2,P3. . . . . .
当新点在凸包的“前进”方向的左边时继续,否则依次删除最近加入凸包的点,直到新点在左边。
时间复杂度为O(nlogn)