基础
向量
即
a
⃗
=
(
x
1
,
y
1
)
\vec a=(x_1,y_1)
a=(x1,y1),
b
⃗
=
(
x
2
,
y
2
)
\vec b=(x_2,y_2)
b=(x2,y2)
两个向量间的常见的运算有点积和叉积(内积和外积)。
点积:
a
⃗
⋅
b
⃗
=
x
1
x
2
+
y
1
y
2
\vec a·\vec b=x_1x_2+y_1y_2
a⋅b=x1x2+y1y2
叉积:
a
⃗
×
b
⃗
=
x
1
y
2
−
y
1
x
2
\vec a×\vec b=x_1y_2-y_1x_2
a×b=x1y2−y1x2
点积可以用于判断两向量的夹角是锐角还是钝角
叉积比较有用,其值能表示两个向量组成的平行四边形的面积(并且是有向的,遵守右手法则)
eg.
P2785 这里就是应用了三角形叉积能表示面积这一点,将多边形以平面上某点分割成很多三角形,从而计算出任意多边形的面积
P4894 这是用到了三维叉积,所得结果垂直于二维两向量的特点,可以快速求出法向量。
直线
记录直线需要两个参数,直线上的一个点和直线的方向向量。
多边形
按顺序记录其所有顶点即可保存一个多边形
凸多边形是研究的比较多的一个领域。
多边形和点的关系比较重要,即多边形是否包含点
一般有两种办法:
①从这个点引出一条射线,如果穿越多边形边界奇数次则在内,穿越偶数次在外
②这个点与相邻顶点连线构成的有向角,如果其加和为
2
π
2\pi
2π 则在多边形内,加和0在外。但这个速度较慢(用反三角函数多次),一般采用从点引出一条向右的水平线,判断多边形有向边
穿越这个线多少次
eg.
POJ2318 判断点是否在某个多边形内,特化了方法②,用二分法缩减多边形
P1355 判断点是否在三角形内,边上,顶点上。做法是类似的
进阶
凸包
用n个点构造最小凸多边形的O(n)算法,运用了外积表示了当前边的前进方向。
本身并不难,但是经常一些和它相距甚远的结构可以通过建模
转化为它,这是最难的
小知识点:旋转卡壳,即凸包直径,凸包上的两个最远顶点
eg.
P2742 构建凸包模板题
P2116通过建模才能想到要把城堡这个任意多边形转化成凸多边形
P1452先构建凸包,再找直径的模板题
最小圆覆盖
给出n个点,构造最小的能覆盖它们的圆
看似很像旋转卡壳,但是对于正奇数边形很容易发现都不符合最小圆覆盖。
这里用的是随即增量(即先打乱再数学归纳)
eg.
P1742模板题
半平面交
和数学里的动态规划一致,但是代码上实现比较复杂。
eg.
P4196 构建半平面交后,求多边形面积