浅谈平面几何
最近做题的时候由于平面几何的问题被搞得痛不欲生,于是决定来研究一下平面几何那些事儿,反正高中迟早都得学。
向量
基本概念
定义:既有大小又有方向的量称为向量,记作 \(\overrightarrow{\textbf a}\)。
有向线段:有方向的线段,有起点、方向、长度三要素,用于表示向量。
模:有向线段 \(\overrightarrow{AB}\) 的长度,记为 \(\Big|\overrightarrow{AB}\Big|\)。
零向量:模为 \(0\) 的向量,记为 \(\vec0\) 或 \(0\)。
单位向量:模为 \(1\) 的向量记为该方向上的单位向量。
平行向量:又称共线向量,方向相同或相反的向量,记为 \(\mathbf a\parallel\mathbf b\)。
相等向量:模相等且方向相同的向量。
相反向量:模相等且方向相反的向量。
向量的夹角:已知两个非零向量 \(\mathbf a\),\(\textbf b\),作 \(\overrightarrow{OA}=\textbf a\)、\(\overrightarrow{OB}=\textbf b\),则 \(\theta=\angle AOB\) 就是 \(\textbf a\) 与 \(\textbf b\) 的夹角,记作 \(\left\langle \textbf a,\textbf b\right\rangle\)。规定 \(\theta\in[0,\pi]\)。特别的,当 \(\theta=\dfrac{\pi}{2}\) 时,这两个向量垂直,记作 \(\textbf a\perp \textbf b\)。
线性运算
加法
- 三角形法则:若向量的头尾顺次相连,则它们的和为第一个向量的起点指向最后一个向量的终点,即 \(\overrightarrow{AB}+\overrightarrow{BC}=\overrightarrow{AC}\)。
- 平行四边形法则:若两个向量共起点,则它们的和为以这两个向量为邻边的平行四边形的对角线,起点为共起点,方向沿对角线方向。
向量加法满足交换律与结合律。
减法
共起点向量的差向量为减向量的终点指向被减向量的终点,即 \(\overrightarrow{AB}-\overrightarrow{AC}=\overrightarrow{CB}\)。
数乘
实数 \(\lambda\) 与向量 \(\textbf a\) 的积为一个向量 \(\lambda\textbf a\)。
- \(|\lambda \textbf a|=|\lambda||\textbf a|\);
- 当 \(\lambda>0\) 时,\(\lambda\textbf a\) 与 \(\textbf a\) 同向;当 \(\lambda=0\) 时,\(\lambda\textbf a=0\);当 \(\lambda<0\) 时,\(\lambda\textbf a\) 与 \(\textbf a\) 方向相反。
满足结合律、分配律。
当存在唯一实数 \(\lambda\) 使得 \(\lambda\textbf a=\textbf b\ (\textbf a,\textbf b\not=0)\) 时,\(\textbf a\)、\(\textbf b\) 共线。
平面向量
平面向量基本定理:若两向量 \(\textbf a\)、\(\textbf b\) 不共线,则存在唯一实数对,使得与 \(\textbf a\)、\(\textbf b\) 共面的任意向量 \(\textbf p\) 满足 \(\textbf p=x\textbf a+y\textbf b\)。
基底:在同一平面内不共线的两个向量。
坐标表示
若取与 \(x\)、\(y\) 轴方向相同的单位向量 \(i\)、\(j\) 作为基底,则根据平面向量基本定理,平面上的每一个向量都唯一对应一个有序实数对 \((x,y)\),而有序实数对 \((x,y)\) 与平面直角坐标系上的点一一对应,那么我们作 \(\overrightarrow{OP}=\textbf p\),那么终点 \(P(x,y)\) 也是唯一对应的。由于我们研究的都是自由向量,可以自由平移起点,这样,在平面直角坐标系里,每一个向量都可以用有序实数对唯一表示。
平面向量的坐标运算
设有两个向量 \(\textbf x=(\alpha,\beta)\)、\(\textbf y=(\gamma,\delta)\),则:
- \(\textbf x+\mathbf y=(\alpha+\gamma,\beta+\delta)\)
- \(\textbf x-\textbf y=(\alpha-\gamma,\beta-\delta)\)
- \(\lambda\textbf x=(\lambda\alpha,\lambda\beta)\)
已知两点 \(A(\alpha,\beta)\)、\(B(\gamma,\delta)\),则 \(\overrightarrow{AB}=(\gamma-\alpha,\delta-\beta)\)。
若 \(A\)、\(B\)、\(C\) 三点共线,则 \(\overrightarrow{OB}=\lambda\overrightarrow{OA}+(1-\lambda)\overrightarrow{OC}\)。
向量的叉积
又称向量积、外积、矢积。已知两向量 \(\textbf x\),\(\textbf y\) 及它们的夹角 \(\theta\),它们的叉积为 \(\textbf z=\textbf x\times\textbf y\),则
\(\textbf z\) 的方向垂直于 \(\textbf x\) 与 \(\textbf y\) 所决定的平面,并遵循右手定则。\(\textbf z\) 是一个伪向量,因为在不同的坐标系中 \(\textbf z\) 可能不同,不过一般在计算时不用管它的方向,只需要计算它的模。\(|\textbf z|\) 相当于以 \(\textbf a\)、\(\textbf b\) 为邻边的平行四边形的面积。
在平面向量的计算中,若 \(\textbf x=(\alpha,\beta)\),\(\textbf y=(\gamma,\delta)\),则
向量的点积
又称数量积、内积、标积。已知两向量 \(\textbf x\),\(\textbf y\) 及它们的夹角 \(\theta\),则
其中 \(|\textbf x|\cos\theta\) 为 \(\textbf x\) 在 \(\textbf y\) 方向上的投影。点积所得到的结果是一个实数。
在平面向量的运算中,若 \(\textbf x=(\alpha,\beta)\),\(\textbf y=(\gamma,\delta)\),则
点积的应用如下:
- \(\textbf x\perp\textbf y\iff\textbf x\cdot\textbf y=0\),即 \(\cos\theta=0\);
- \(\textbf x\parallel\textbf y\iff\textbf x\cdot\textbf y=|\textbf x||\textbf y|\),即 \(\cos\theta=1\);
- \(\cos\theta=\dfrac{\textbf x\cdot\textbf y}{|\textbf x||\textbf y|}\)
顺便提一嘴,若 \(\textbf x=(\alpha,\beta)\),则
向量的旋转
设 \(\textbf a=(x,y)\),倾角为 \(\theta\),长度为 \(l=\sqrt{x^2+y^2}\)。则 \(x=l\cos\theta\),\(y=\cos\theta\)。令其逆时针旋转 \(\alpha\) 度角,得向量
代码实现
提了那么多,还是上代码吧。
尽管叉积所得的是一个向量,但在代码中只返回了它的模。
inline int sgn(double x)
{
if(fabs(x)<eps) return 0;
if(x<0) return -1;
return 1;
}
struct point
{
double x,y;
point(){}
point(double _x,double _y):x(_x),y(_y){}
bool operator==(point b)const{return sgn(x-b.x)==0&&sgn(y-b.y)==0;}
point operator+(const point& b)const{return point(x+b.x,y+b.y);}//加法
point operator-(const point& b)const{return point(x-b.x,y-b.y);}//减法
double operator^(const point& b)const{return x*b.y-y*b.x;}//叉积
double operator*(const point& b)const{return x*b.x+y*b.y;}//点积
double len(){return hypot(x,y);}//模
double len2(){return x*x+y*y;}//模的平方
point operator*(const double& k)const{return point(x*k,y*k);}//数乘
point operator/(const double& k)const{return point(x/k,y/k);}//数除
point rorate(double alpha){return point(x*cos(alpha)-y*sin(alpha),y*cos(alpha)+x*sin(alpha));}
};
前方准备
正弦定理
在 \(\triangle\text{ABC}\) 中,若角 \(A\)、\(B\)、\(C\) 所对边分别为 \(a\)、\(b\)、\(c\),其外接圆半径为 \(R\),则
余弦定理
在 \(\triangle\text{ABC}\) 中,若角 \(A\)、\(B\)、\(C\) 所对边分别为 \(a\)、\(b\)、\(c\),则
交点
两直线交点
至少在我的世界里 (不是mc!),直线只有一种表示方法:
设有两直线 \(f_1(x)=k_1x+b_1\)、\(f_2(x)=k_2x+b_2\),则它们的交点为 \(\bigg(\dfrac{b_2-b_1}{k_1-k_2},\dfrac{k_1b_2-k_2b_1}{k_1-k_2}\bigg)\)。
判断两线段是否有交点
首先我们要判断一些特殊情况,如平行(也就是 \(k\) 相等)或重合(\(k\)、\(b\) 相等且一线段的端点在另一线段内)。
规定线段区域为以该线段为对角线,四边均平行与坐标轴的矩形。若这两条线段没有公共区域,则它们一定不相交。这叫做 快速排斥实验。我们可以初步排除一些情况。
通过快速排斥试验后,我们只需要判断一条线段的两个端点是否在另一条线段的两侧,若是,则它们有交点。这叫做 跨立实验。
多边形面积
线性平面上的多边形面积
将多边形上的点逆时针标记为 \(P_{1\dots n}\),再作一辅助点 \(O\),记向量 \(\mathbf v_i=p_i-O\),则该多边形的面积为
平面直角坐标系上的多边形面积
将多边形上的点逆时针标记为 \(P_1(x_1,y_1)\)、\(P_2(x_2,y_2)\)、\(P_3(x_3,y_3)\)……\(P_n(x_n,y_n)\),则该多边形的面积为
皮克定理
如果该多边形是在一个网格图上,且所有的顶点都在格点上,那么令多边形内部格点数目为 \(a\),边上的格点数目为 \(b\),则其面积为
判断一点是否在多边形内
从该点引出一条射线(不与任何边共线),若与多边形有奇数个交点,则其在多边形内,否则在多边形外。这称之为 奇内偶外,因为每次与多边形相交,就改变了其与多边形的内外关系。
极坐标系
极点:在平面上选定的一点 \(O\)。
极轴:自极点引出的一条射线 \(Ox\)。
正方向:在极坐标系中一般为逆时针方向。
极坐标:设 \(A\) 为平面上一点,则 \(|OA|\) 称为 极径,记为 \(\rho\);以极轴为始边,\(OA\) 为终边的角 \(\angle xOA\) 称为 极角,记为 \(\theta\),则 \(A\) 该平面上的坐标为有序数对 \((\rho,\theta)\)。一般规定 \(\rho>0\),\(0\leqslant\theta<2\pi\)。
极坐标与直角坐标的转换
假设极点为原点,极轴为 \(x\) 轴的正半轴,点 \(A\) 的极坐标为 \((\rho,\theta)\),直角坐标为 \((x,y)\),则
距离
欧几里得距离
在平面直角坐标系中有两点 \(A(x_1,y_1)\)、\(B(x_2,y_2)\),则该两点之间的欧几里得距离为
扩展到 \(n\) 维空间中,假设有两点 \(\vec A(x_{1\dots n})\)、\(\vec B(y_{1\dots n})\),则它们之间的欧几里得距离为
曼哈顿距离
在平面直角坐标系中有两点 \(A(x_1,y_1)\)、\(B(x_2,y_2)\),则该两点之间的曼哈顿距离为
这就好比曼哈顿网格状的街道上,你想从 \(A\) 点到 \(B\) 点,只能沿着道路直来直往,所能达到的最短距离。
扩展到 \(n\) 维空间中,假设有两点 \(\vec A(x_{1\dots n})\)、\(\vec B(y_{1\dots n})\),则它们之间的曼哈顿距离为
切比雪夫距离
在平面直角坐标系中有两点 \(A(x_1,y_1)\)、\(B(x_2,y_2)\),则该两点之间的切比雪夫距离为
扩展到 \(n\) 维空间中,假设有两点 \(\vec A(x_{1\dots n})\)、\(\vec B(y_{1\dots n})\),则它们之间的切比雪夫距离为
曼哈顿距离与切比雪夫距离之间的转换
将一个点 \((x,y)\) 的坐标变为 \((x+y,x-y)\) 后,原坐标系中的曼哈顿距离变成了新坐标系中的切比雪夫距离。
将一个点 \((x,y)\) 的坐标变为 \(\bigg(\dfrac{x+y}{2},\dfrac{x-y}{2}\bigg)\) 后,原坐标系中的切比雪夫距离变成了新坐标系中的曼哈顿距离。
凸包
凸多边形:所有内角都在 \([0,\pi]\) 范围内的简单多边形。
简单点说,凸包就是用一个绳子把简单多边形围起来,然后勒紧所得的图形。凸包满足在围住多边形所有点的情况下周长最小。
凸包的求法:
-
将所有点按横坐标为第一关键字,纵坐标为第二关键字进行排序。
-
排序后最小和最大的点必定都在凸包上,因此我们用这两个点将凸包分为上凸壳和下凸壳。
-
可以发现,如果我们从一个点逆时针出发,那么凸包边必然是全程左拐,如果右拐,就说明刚刚我们走的一段不在凸包上,需要退回去。这可以用一个单调栈维护。
-
枚举时,我们先升序枚举求出下凸壳,再降序枚举求出上凸壳。
-
令当前栈顶为 \(S_1\),次栈顶为 \(S_2\),枚举到的点为 \(P\),如果需要右转才能到 \(P\)(即 \(\overrightarrow{S_2S_1}\times\overrightarrow{S_1P}<0\)),则弹出栈顶,回到上一步,直到可以左转或是栈只剩一个元素。
-
设凸包上的 \(m\) 个点分别为 \(P_{1\dots m}\),则整个凸包的周长为
\[\sum_{i=1}^n\Big|\overrightarrow{P_{i}P_{i\bmod m+1}}\Big| \]