半平面交

二维平面中直线可以用ax+by+c=0来描述,半平面则可以使

用不等式来描述。例如ax+by+c>=0或者ax+by+c<0等等。

 若干个半平面相交,可能得到不同性质的答案。例如凸多边形、

直线、射线、线段、点,也有可能不是封闭图形。

 半平面相交可以解决多边形核的问题。所谓多边形的核,就是

指多边形的一个点,该点与多边形的其他所有点的连线都在多

边形内。这样的点构成的点集称为多边形的核。显然,凸多边

形的核就是它自己。而凹多边形的核有可能是空集。

 半平面相交的算法:暴力法,对n个半平面逐一去遍历求交点

并进行取舍;分治法,两两相交再求交,应该是利用半平面相

交结果肯定不为凹的性质。这里说的是zzy提出来的排序增量法

——s&i算法。s&i算法与分治法都是O(nlgn)。

 将半平面按极角排序,所谓半平面的极角可以看作是其法向量

的极角。将半平面均写成ax+by+c>=0或者ax+by+c>0的形

式,则其方向量就是(a,b)。如果输入全部是整点,则排序最好

使用先象限后叉积,不要用反三角函数,避免精度问题。另外,

如果2个半平面极角相等也就是平行,只取更靠近法向量发现的

那个,其余全部删除。半平面平行,则a、b取值在归一化形式

下相等,因此谁更靠近法向量实质上就是比较c。另外,如果以

多边形边的形式给定半平面,则多边形必然是顺时针或者逆时针

方向,例如给定边的2个端点A、B,又知道是逆时针给定的,法

向量必然在AB方向的左侧且垂直,对所有的边都一样。因此实际

上可以不用排法向量,只要排序边的方向即可,它们是一一对应的。


 为了将平行半平面删除,首先规定更靠近法向量方向的半平面

更小,也就是排序时排在前面。如果使用STL,则sort以后可以

很方便的使用unique进行剔除。自己书写源代码也很容易。

 本质上维持一个双端队列,初始将最开始的2个半平面加入队列。

  循环,for每一个新的半平面

       while最顶端的2个半平面的交点在当前半平面外,删除最

顶端的半平面(当队列里只剩下1个就不用循环了)

       while最底端的2个半平面的交点在当前半平面外,删除最

底端的半平面(当队列里只剩下1个就不用循环了)  

       将当前半平面加入顶端

 循环完毕以后,做一个后处理,实际上跟上述循环类似while最

顶端的2个半平面的交点在最底端半平面外,删除最顶端的半平

面(当队列里只剩下1个就不用循环了)

       while最底端的2个半平面的交点在最顶端半平面外,删除最

底端的半平面(当队列里只剩下1个就不用循环了) 

 此时队列里剩下的半平面就是用来求交集的半平面。求交之前可做一个判断。对于多边形求核问题,因为多边形是封闭的,所以

半平面的交集一定是有界的,因此此时队列里至少剩下3个半平面,否则就是空集无解。如果是纯半平面相交问题,则可以根据数

据范围加一个包围盒,一样能够保证交集有界。

 如果还需具体求出半平面的交集,则将队列里相邻半平面求交点,

交点所围成的图形就是交集。如果半平面都是ax+by+c>0的形式,

则要求交集有面积。这个可以根据具体题意进行判断。

 算法的正确性以及其他理论问题可以参考zzy的论文考虑解决,使用

上述方法流程可以很容易的解决POJ3335、POJ3130、POJ1474、

POJ2451、POJ3525、POJ3384、POJ1755等。

转自:http://blog.sina.com.cn/s/blog_833d50630100xu0x.html


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值