计算几何
全文仅关于平面计算几何。
参考资料
- 【ACM】 jls和dls教你计算几何 wannafly 2019 算法冬令营 by杜瑜皓 吉如一 ACM ICPC 录播
- 计算几何学习笔记 | Menci's OI Blog
- 计算几何 学习笔记 - xht
- 【洛谷日报#142】计算几何初步 - 知乎
点 / 向量的基本运算
每个点 / 向量可以被表示为 \((x,y)\) 这样一个二元组。这说明点和向量的本质相同,所以代码中也用同一个结构体表示。
struct Pt {
double x, y;
Pt(double x = 0, double y = 0) : x(x), y(y) {}
};
typedef Pt Vec;
点 / 向量的加减法
设 \(A = (x_1, y_1), B = (x_2, y_2)\)。
- 加法:\(A+B = (x_1 + y_1, x_2 + y_2)\)。
- 减法:\(A-B = (x_1 - y_1, x_2 - y_2)\)。
即对应位置相加减。
点 / 向量的(绕原点)旋转
将 \((x,y)\) 绕原点逆时针旋转 \(\alpha\),得到 \((x',y')\),满足:
向量单位化
记 \(\text{unit} A\) 为与 \(A\) 方向相同的单位向量。
TODO:
\(\bigstar\) 向量的点积
(\(\langle A,B \rangle\) 代表 \(A,B\) 的夹角,当 \(B\) 在 \(A\) 的逆时针方向时为正,顺时针方向为负)
向量 \(A\) 与 \(B\) 的点积 \(A \cdot B\) 定义为 \(|A||B| \cos\langle A,B \rangle\)。两个向量的点积是一个数。
点积的几何意义:将 \(A\) 投影到 \(B\) 上得到的投影长(可以为负)乘 \(B\) 的长度。
点积具有交换律:\(A \cdot B = B \cdot A\)。
点积很容易计算:\(A \cdot B = |A||B| \cos\langle A,B \rangle = x_1 y_1 + x_2 y_2\)。(公式推导留作习题)
double dot(const Vec &a, const Vec &b) {
return a.x * b.x + a.y * b.y;
}
这个运算定义得很奇怪!在后面的部分会介绍其用途。
\(\bigstar\) 向量的叉积
(两个向量的叉积应该是一个向量,但是 OI 中一般只会用到这个向量的模长,而不会用到其作为向量的性质,故略去不写。)
向量 \(A\) 与 \(B\) 的叉积为一个数 \(A \times B = |A||B| \sin\langle A,B \rangle\)。在 OI 中,两个向量的叉积是一个数。
叉积的几何意义:\(A\) 与 \(B\) 构成的平行四边形的有向面积。
叉积具有类似交换律的性质:\(A \times B = - B \times A\)。
叉积很容易计算:\(A \times B = |A||B| \sin\langle A,B \rangle = x_1 y_2 - x_2 y_1 = \begin{vmatrix} x_1 & y_1 \\ x_2 & y_2 \end{vmatrix}\)。(公式推导留作习题)
double cross(const Vec &a, const Vec &b) {
return a.x * b.y - a.y * b.x;
}
这个运算定义得也很奇怪!在后面的部分会介绍其用途。
点和向量的应用
向量夹角
点在直线上的投影
即已知 \(A,B,C\) 三点,\(CH \perp AB\) 且 \(H\) 在 \(AB\) 上,求 \(H\)。
设 \(AB,AC\) 夹角为 \(\theta\)。
计算几何经典问题
三点共线判断
\(A,B,C\) 三点共线,当且仅当 \((A-C) \times (B-C) = 0\)。
例题:P1142 轰炸、[ABC248E] K-colinear Line。
(注:平面上给定 \(n\) 个点求是否有三点共线出现,此问题的多项式次数为 \(2\)。即 \(\forall \varepsilon>0, T(n) = o(n^{2+\varepsilon}), T(n) = \omega(n^{2-\varepsilon})\)。好像可以归约到 3SUM 问题)
点在多边形内判断
求 \(O\) 是否在多边形 \(Poly\) 的形内。
(光线投射算法)随机从 \(O\) 引一射线 \(OA\),若 \(OA\) 与奇数条边相交则 \(O\) 在形内,否则在形外。(正好在边界上的情况直接特判)
例题:P1355 神秘大三角。
平面最近点对
TODO:
浙公网安备 33010602011771号