半平面交笔记 Half Plane Intersection
Half Plane Intersection
半平面
一条直线和直线的一侧。半平面是一个点集,因此是一条直线和直线的一侧构成的点集。当包含直线时,称为闭半平面;当不包含直线时,称为开半平面。
解析式一般为 。
在计算几何中用向量表示,整个题统一以向量的左侧或右侧为半平面。
半平面交
半平面交是指多个半平面的交集。因为半平面是点集,所以点集的交集仍然是点集。在平面直角坐标系围成一个区域(可以理解为向量集中每一个向量的左侧交)。
这就很像普通的线性规划问题了,得到的半平面交就是线性规划中的可行域。一般情况下半平面交是有限的,经常考察面积等问题的解决。
多边形的核
如果一个点集中的点与多边形上任意一点的连线与多边形没有其他交点,那么这个点集被称为多边形的核。
把多边形的每条边看成是首尾相连的向量,那么这些向量在多边形内部方向的半平面交就是多边形的核。
解法 - S&I算法
极角排序
利用 atan2(y, x) 函数将向量(线段)按极角排序,排序时,若遇到贡献向量(且方向相同),则取靠近可行域的一个(即靠近左侧的向量)。判断方法为取一个向量的起点与另一个向量的起点、终点构成向量,通过叉积符号判断。
1 | /*cross product of two Vec2 vector (starting point is zero)*/ |
维护单调队列
因为半平面交是一个凸多边形,所以需要维护一个凸壳。因为后来加入边的只可能会影响最开始加入的或最后加入的边(此时凸壳连通),只需要删除队首和队尾的元素,所以需要用单调队列。
具体维护方法见 oi-wiki.org
得到半平面交
如果半平面交是一个凸 边形,最后在交点数组里会得到 个点。我们再把它们首尾相连,就是一个统一方向(顺或逆时针)的多边形。
此时就可以用三角剖分求面积了。(求面积是最基础的考法)
偶尔会出现半平面交不存在或面积为 0 的情况,注意考虑边界。
代码
1 | struct Vec2 { //点向量类 |
线段类(极角排序,对应直线的交点)
1 | struct Seg { //线段类 起点s, 终点t |
半平面交
1 | //求向量左侧的半平面交 |
例题
A CQOI2006 凸多边形
Description
Code
1 |
|
B UVA1304 Art Gallery
Description
Solution
求凸多边形的核的面积,即求边的半平面交的面积。有的时候需要注意给出点的顺逆时针方向。
C ZJOI2008 瞭望塔
Description
题目链接
在山的轮廓线上选取一个位置建瞭望塔,使得在瞭望塔最顶端能看到山的每一个角落,求瞭望塔高的最小值。
Solution
先求出轮廓左侧半平面交(非闭合),可以证明瞭望塔高取最小值时一定在 或半平面交的交点所对应的 处。
对于每个 ,做垂直于水平方向的直线与半平面交的边界相交,求出 。
对于半平面交的交点,同样做垂线,与轮廓线相交,求出 。
注意:半平面交没有闭合,线段的取值范围为(l, r)。
Code
1 |
|
D UVA1396 Most Distant Point from the Sea
Description
题目链接
求凸多边形的最大内切圆半径。
Solution
将多边形的边向内平移,当半平面交面积为 0 或不存在时,即所平移的距离为最大内切圆的半径。接下来二分移动的距离即可。
Code
1 |
|