计算几何 学习笔记
作者:互联网
前置芝士
向量
OI-wiki说是人教版高中数学必修四内容,我好害怕。
向量:既有大小又有方向的量称为向量。数学上研究的向量为自由向量,即只要不改变它的大小和方向,起点和终点可以任意平行移动的向量。记作 \(ve a\) 或 \(a\) 。
有向线段:带有方向的线段称为有向线段。有向线段有三要素:起点,方向,长度,知道了三要素,终点就唯一确定。我们用有向线段表示向量。
向量的模:有向线段 \(\overrightarrow{AB}\) 的长度称为向量的模,即为这个向量的大小。记为: \(|\overrightarrow{AB}|\) 或 \(|a|\) 。
如果取与横轴与纵轴方向相同的单位向量 作为一组基底,根据平面向量基本定理,平面上的所有向量与有序实数对 一一对应。
平面向量的坐标表示
而有序实数对 \((x,y)\) 与平面直角坐标系上的点一一对应,那么我们作 \(\overrightarrow{OP}\) ,那么终点 \(P\) 也是唯一确定的。由于我们研究的都是自由向量,可以自由平移起点,这样,在平面直角坐标系里,每一个向量都可以用有序实数对唯一表示。 ——摘自OI-wiki
向量的运算
我们定义了一种量,就希望让它具有运算。向量的运算可以类比数的运算,但是我们从物理学的角度出发研究向量的运算。
向量的加减法
不难得出,对于两个向量 \(\overrightarrow{AB}\) 和 \(\overrightarrow{BC}\) 我们定义:
\(\overrightarrow{AB}+\overrightarrow{BC}=\overrightarrow{AC}\)
\(\overrightarrow{AB}-\overrightarrow{AC}=\overrightarrow{BC}\)
那么,对于平面直角坐标系上的任意向量,我们如果知道它的端点 \(A\) 和 \(B\) 我们就通过减法可以得到这个向量: \(\overrightarrow{OA}-\overrightarrow{OB}=\overrightarrow{AB}\) 。
我们发现,向量的加减法和力的加减法是一样的。
所以向量的加减法符合三角形法则和平行四边形法则。
- 向量加法的三角形法则:若要求和的向量首尾顺次相连,那么这些向量的和为第一个向量的起点指向最后一个向量的终点;
- 向量加法的平行四边形法则:若要求和的两个向量 共起点,那么它们的和向量为以这两个向量为邻边的平行四边形的对角线,起点为两个向量共有的起点,方向沿平行四边形对角线方向。
不难证明,向量的加法满足交换律和结合律,减法满足减法性质。
向量的叉积
既然向量可以进行加减运算,那么,向量是否能进行乘法运算呢。
当然是可以的。
如图假设平面上有三个点,记为 \(A,B,C\) , 其中\(\overrightarrow{OA}+\overrightarrow{OC}=\overrightarrow{OB}\) ,换句话说,四边形 \(OABC\) 是平行四边形。
我们规定: \(\overrightarrow{OA}\times\overrightarrow{OC}=S_{平行四边形OABC}\)
其实这样是不对的,因为向量是有方向的,所以说这两个向量的叉积也是有方向的,如果这第二个向量相对于第一个向量是顺时针旋转,那么得到平面的方向是垂直于屏幕向里,结果是负数,反之亦然。(怎么有点像右手螺旋定则)
如果两个向量平行或者方向相反,那么这两个向量的叉积为 \(0\) 。
所以说向量的叉积不具备交换律,而是这样: \(\overrightarrow{AB}\times\overrightarrow{AC}=-\left(\overrightarrow{AC}\times\overrightarrow{AB}\right)\)
基础代码
typedef long long ll;
struct Vector{
ll x,y;
Vector operator + (const Vector &x) const{
return (Vector){this->x+x.x,this->y+x.y};
}
Vector operator - (const Vector &x) const{
return (Vector){this->x-x.x,this->y-x.y};
}
double operator * (const Vector &x) const{
return this->x*x.y - this->y*x.x;
}
};
深入探究
有了向量,我们就可以开始学习计算几何了。
判断点是否在直线或者线段上
问题:给出点 \(A\) 点 \(B\) 点 \(P\) 的坐标,请问点 \(P\) 是否在直线 \(AB\) 上。
我们发现,只要满足 \(\overrightarrow{AP}\times\overrightarrow{AB}=0\) 即可。
问题:给出点 \(A\) 点 \(B\) 点 \(P\) 的坐标,请问点 \(P\) 是否在线段 \(AB\) 上。
我们只需要保证点 \(P\) 在直线 \(AB\) 上并且点 \(P\) 在 \(AB\) 两点之间(xy坐标都可以)
求点到直线或者线段的距离
问题:给出点 \(A\) 点 \(B\) 点 \(P\) 的坐标,请问点 \(P\) 到直线 \(AB\) 的距离。
其实很简单,不难发现距离其实就是
至于求点到线段的距离,只要判断求的是点到直线的距离还是点到线段两端点的距离就可以了。
判断两直线或线段是否相交
对于两条直线 \(AB\) 和 \(XY\) 我们只要判断 \(\overrightarrow{AB}\times\overrightarrow{XY}\) 是否等于 \(0\),如果等于 \(0\) 就是平行或者是重合,否则就是相交的。
对于两条线段 \(AB\) 和 \(XY\) 我们需要让线段的两个端点分别跨立才能保证线段相交。也就是保证
并且
\[\left( \overrightarrow{XA}\times\overrightarrow{XB} \right)\times\left( \overrightarrow{YA}\times\overrightarrow{YB} \right)<0 \]。
求一个多边形的面积
假设我们逆时针给出这个多边形的所有点,这些点分别为 \(A_0,A_1,A_2\dots A_n-1\) 共 \(n\) 个点。
那么不难得出
至于证明其实自己画个图不就好了吗?
判断点是否在一个多边形内
从这个点引一条射线,如果和这个多边形的交点数量是奇数个,那么这个点就在多边形内,否则就在多边形外。
当然射线是很难做到的,为了方便我们就直接用一条很长的线段就可以了,当然如果运气不好我们的线段经过了多边形的端点的时候,答案就会出错,因为端点会算两次,所以需要一点点随机化,还有就是看RP了。
卡精度
有些时候由于进制的原因,我们会导致一些问题,比如说:
if(0.1+0.2==0.3) printf("Y");
else printf("N");
事实证明,这里输出的是N
!
为什么呢?因为对于一个有理数,只有使用 \(e\) 进制的时候才不会产生无限小数,但是电脑里的存储是二进制,所以会产生一些误差。
但是这些误差会很小,所以我们不妨这样写:
原来的写法 | 更正写法 |
---|---|
a==b |
fabs(a-b)<EPS |
a>b |
a>b-EPS |
a<b |
a<b+EPS |
其中 EPS
是一个很小的数字,大概在 \([1e-9,1e-7]\) 这个区间。
当然,我们发现,向量没有除法,向量的运算也不会涉及除法,所以这样计算几何在运算的过程中损失的精度较小,所以才可以广泛的运用,而解析几何则多多少少都有除法,容易造成精度的损失。
END.
标签:AB,overrightarrow,线段,笔记,times,学习,Vector,几何,向量 来源: https://www.cnblogs.com/jiangtaizhe001/p/14418295.html