计算几何基础


咕咕咕咕咕咕咕咕咕咕咕咕 <- 2021.2.19开的坑,现在还没填完 填好了。

前置芝士

向量

OI-wiki说是人教版高中数学必修四内容,我好害怕
向量:既有大小又有方向的量称为向量。数学上研究的向量为自由向量,即只要不改变它的大小和方向,起点和终点可以任意平行移动的向量。记作 veaa
有向线段:带有方向的线段称为有向线段。有向线段有三要素:起点方向长度,知道了三要素,终点就唯一确定。我们用有向线段表示向量。
向量的模:有向线段 AB 的长度称为向量的模,即为这个向量的大小。记为: |AB||a|
如果取与横轴与纵轴方向相同的单位向量 作为一组基底,根据平面向量基本定理,平面上的所有向量与有序实数对 一一对应。

平面向量的坐标表示

而有序实数对 (x,y) 与平面直角坐标系上的点一一对应,那么我们作 OP ,那么终点 P 也是唯一确定的。由于我们研究的都是自由向量,可以自由平移起点,这样,在平面直角坐标系里,每一个向量都可以用有序实数对唯一表示。 ——摘自OI-wiki

向量的运算

我们定义了一种量,就希望让它具有运算。向量的运算可以类比数的运算,但是我们从物理学的角度出发研究向量的运算。
向量的加减法
不难得出,对于两个向量 ABBC 我们定义:
AB+BC=AC
ABAC=BC
那么,对于平面直角坐标系上的任意向量,我们如果知道它的端点 AB 我们就通过减法可以得到这个向量: OAOB=AB
我们发现,向量的加减法和力的加减法是一样的。
所以向量的加减法符合三角形法则平行四边形法则

  1. 向量加法的三角形法则:若要求和的向量首尾顺次相连,那么这些向量的和为第一个向量的起点指向最后一个向量的终点;
  2. 向量加法的平行四边形法则:若要求和的两个向量 共起点,那么它们的和向量为以这两个向量为邻边的平行四边形的对角线,起点为两个向量共有的起点,方向沿平行四边形对角线方向。
    不难证明,向量的加法满足交换律和结合律,减法满足减法性质。

向量的叉积

既然向量可以进行加减运算,那么,向量是否能进行乘法运算呢。
当然是可以的。
如图假设平面上有三个点,记为 A,B,C , 其中OA+OC=OB ,换句话说,四边形 OABC 是平行四边形。

我们规定: OA×OC=SOABC
其实这样是不对的,因为向量是有方向的,所以说这两个向量的叉积也是有方向的,如果这第二个向量相对于第一个向量是顺时针旋转,那么得到平面的方向是垂直于屏幕向里,结果是负数,反之亦然。(怎么有点像右手螺旋定则)
如果两个向量平行或者方向相反,那么这两个向量的叉积为 0
所以说向量的叉积不具备交换律,而是这样: AB×AC=(AC×AB)

基础代码

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;
}
};

深入探究

有了向量,我们就可以开始学习计算几何了。

判断点是否在直线或者线段上

问题:给出点 ABP 的坐标,请问点 P 是否在直线 AB 上。
我们发现,只要满足 AP×AB=0 即可。
问题:给出点 ABP 的坐标,请问点 P 是否在线段 AB 上。
我们只需要保证点 P 在直线 AB 上并且点 PAB 两点之间(xy坐标都可以)

求点到直线或者线段的距离

问题:给出点 ABP 的坐标,请问点 P 到直线 AB 的距离。
其实很简单,不难发现距离其实就是

AB×AP|AB|

至于求点到线段的距离,只要判断求的是点到直线的距离还是点到线段两端点的距离就可以了。

判断两直线或线段是否相交

对于两条直线 ABXY 我们只要判断 AB×XY 是否等于 0,如果等于 0 就是平行或者是重合,否则就是相交的。
对于两条线段 ABXY 我们需要让线段的两个端点分别跨立才能保证线段相交。也就是保证

(AX×AY)×(BX×BY)<0

并且

(XA×XB)×(YA×YB)<0

求一个多边形的面积

假设我们逆时针给出这个多边形的所有点,这些点分别为 A0,A1,A2An1n 个点。
那么不难得出

S=i=0n1OAi×OA(i+1)modn2

至于证明其实自己画个图不就好了吗?

判断点是否在一个多边形内

从这个点引一条射线,如果和这个多边形的交点数量是奇数个,那么这个点就在多边形内,否则就在多边形外。
当然射线是很难做到的,为了方便我们就直接用一条很长的线段就可以了,当然如果运气不好我们的线段经过了多边形的端点的时候,答案就会出错,因为端点会算两次,所以需要一点点随机化,还有就是看RP了

卡精度

有些时候由于进制的原因,我们会导致一些问题,比如说:

if(0.1+0.2==0.3) printf("Y");
else printf("N");

事实证明,这里输出的是N!
为什么呢?因为在十进制之中 0.10.2 是有限小数,但是转化成二进制就是无限小数了,而电脑存储太精确,所以就会造成误差。
但是这些误差会很小,所以我们不妨这样写:

原来的写法 更正写法
a==b fabs(a-b)<EPS
a>b a>b-EPS
a<b a<b+EPS

其中 EPS 是一个很小的数字,大概在 [1e9,1e7] 这个区间。
当然,我们发现,向量没有除法,向量的运算也不会涉及除法,所以这样计算几何在运算的过程中损失的精度较小,所以才可以广泛的运用,而解析几何则多多少少都有除法,容易造成精度的损失。
END.

posted @   jiangtaizhe001  阅读(238)  评论(0编辑  收藏  举报
编辑推荐:
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
点击右上角即可分享
微信分享提示