凸包点集的性质
凸包点集中,取出相邻的两个点所构成的边一定能将所有点分割在一边,而另一边并无任何点。
若我们可以按顺序构建凸包点集,则对该集合来说任意相邻元素所构成的边都有此性质。
凸包算法
由凸包点集的性质我们可知凸包算法的思想,按顺序构建凸包点集,并且维护它,直到完成点的遍历。
其精髓在于顺序和维护该性质。网上的算法代码第一步往往是寻找边角点和其相邻点,因为边角点必会在凸包点集中。但是其实多此一举,由于需要顺序,我们先将所有点按坐标排列,排列完的最初元素也必为边角点。
首先在凸包点集中加入排序后的前两个点,接下来我们在凸包点集中取出末尾两个点,以这两点构成的边对接下来的点进行处理。每次处理通过向量判断是否在边的内侧,若在内侧则跳过这个点,视为已处理,若在外侧则说明我们所用的边并不是凸包所要的边,故抛弃当前凸包点集的最后一个点,然后再取末尾两个点,进行迭代判断,直到将该点加入。由此遍历完即产生凸包点集。(雾)应该正序遍历完倒序遍历一次回到起始点,才是一个封闭凸包,不然只有一半
向量的妙用
判断是否在内侧,如下
绿色为内侧点,红色为外侧点。
图片发自简书App
算法优化
我们观察算法可知,内部点不对凸包点集产生任何影响,故我们若能排除显然在内部的点,或者挑出包含凸包点集的子集合,可减少时间。
易得在y值相同的情况下,x最大和最小的点可能为所求点,并且不同y值可能有所求点。故将不同y值所对应的x最大和最小的点都取出作为题目点集的子集,缩小时间复杂度。