半平面交

算法目的:求 N 个半平面的交

定义:一个半平面指的是由满足 ax+by+c>0 ax+by+c>=0 的点集组成的二维区域。一般来说在写代码的时候,我们可以把一个半平面想象成一个向量所在的直线右面的一片区域
半平面的交可能是一个封闭图形也可能是没有边界的区域或者为空

大概思路:先将所有的向量按照与x轴的夹角排序(此处的夹角在 [ππ] 这个区间内),然后按顺序将半平面插入,每次插入的时候从队头及队尾弹出一些之前加入的、现在已经没用的半平面。最后得到的就是这些半平面的交

算法步骤:1.先把所有的半平面用”向量的右侧”这种方法表示出来。具体来说我们开一个结构体line{node a,b;double ang;};代表这个向量是从点a到点b的,与x轴夹角为ang,半平面指的是向量右侧
     2.把所有向量按照ang从小到大排序,ang相同的我们只保留限制条件最紧的那一个(其他的都没用)
     3.维护一个半平面队列q,队列中的元素按照ang大小排序,并且全部都是有用的(没有一个半平面被其他两个半平面挡住)。再维护一个交点队列p,其中p[i]为q[i]和q[i+1]的交点
半平面交_第1张图片
当出现以上这种情况时,我们需要把队尾q[t]弹出,因为他已经被q[t-1]和L[i]覆盖
那么如何检验这个事情呢?我们只需判断p[t-1]是否在L[i]左侧就行(图中L[i]方向是向下的,所以p[t-1]在其左侧)

半平面交_第2张图片
当出现这种情况时,我们需要把队头弹出
这时L[i]已经绕了半圈,有可能覆盖掉队头了,判断的方法和上面同理,只需判断p[h]是否在L[i]左侧就可以了

     4.这样逐次将所有的半平面插入,看起来貌似得到了最终的结果,但是还有可能出现这样的情况
半平面交_第3张图片
最后加入的两个半平面是没有用的
所以我们要将队尾一些没用的半平面删掉
剩下的就都是关键半平面和关键交点了,半平面交也就求完了

算法复杂度:设半平面有 O(N) 个,总时间复杂度是 O(NlogN)

算法应用:可以用来求多边形的核,半平面交点,半平面解析式,封闭区域面积、周长等等

一份样例代码可以参见 POJ1279题解

你可能感兴趣的:(知识点,计算几何,半平面交)