【算法】计算几何
【计算几何基础】
【极角】点(x,y)的极角是向量(x,y)与x轴正半轴的夹角,记为atan2(y,x),范围是 ( -π , π ] ,第一第二象限为正。
极角排序:调用atan(y,x)进行排序,注意共线时按x坐标排序(对立象限)。
例题:【BZOJ】1914: [Usaco2010 OPen]Triangle Counting 数三角形
【斜率】k=Δy/Δx,★斜率不存在时,直线平行于y轴(Δx=0)。
1.两点确定一条直线,所以枚举斜率时只需要枚举任意两点。
2.枚举同一直线上的点,利用在同一直线上的点必定在其中两个点组成的直线上的原理,只需枚举任意两点,再枚举第三点是否在该直线上即可,复杂度O(1/6*n^3)。
3.枚举多少直线交于一点,利用交于同一点的直线必然经过其中两条直线相交点的原理,直接枚举两条直线后再枚举第三条看是否经过前两条的交点。
例题:【Atcoder】ARC082 E - ConvexScore
【点积】每个点都可以视为原点到该点的向量。
运算结果是数值,主要利用坐标运算计算夹角。
$$a \cdot b=|a||b|cos \theta=x_ax_b+y_ay_b$$
向量a⊥向量b当且仅当a*b=0。(cosθ=0)
【叉积】两个向量为邻边构成的有向平行四边形面积。
$$a \times b=|a||b|sin \theta=x_ay_b-x_by_a$$
向量a∥向量b当且仅当a·b=0。(sinθ=0)
叉积不满足交换律,顺着第一个向量a看,b在左边则叉积>0,否则<0。
应用:
1.
【直线的交】
1.
两条直线的交点坐标:直线AB和直线CD的交点
应用:引用自——计算几何基础——【点积和叉积的用处】
1:通过结果的正负判断两矢量之间的顺逆时针关系
2:判断折线拐向,可转化为判断第三点在前两的形成直线的顺逆时针方向,然后判断拐向。
3:判断一个点在一条直线的那一侧,同样上面的方法。
4:判断点是否在线段上,可利用叉乘首先判断是否共线,然后在判断是否在其上。
5:判断两条线段是否相交(跨立实验):根据判断点在直线那一侧我们可以判断一个线段的上的两点分别在另一个线段的两侧,然后对另一条线段也进行相同的判断就ok。
向量旋转:
x'=xcosa-ysina
y'=xsina+ycosa
【凸包】
极角排序后,顺序扫描所有点,通过判断与栈顶线段的叉积来维护单调栈。
实数背包: