二维计算几何点线
废话不多说,直接入正题。
误差
const db eps=1e-9;
inline int sgn(T x){
return x<-eps?-1:x<eps?0:1;
}
我们浮点数计算计算几何的时候是存在误差的,我们用上面这个函数来修正。
对于 ,我们认为它属于负数,返回 .
对于 ,我们认为它属于是零,返回
剩下的属于正数,返回 .
这样我们先把比较运算写出来,然后移项成减法形式,再在外面套一层浮点数修正函数即可。
这个养成好习惯即可。
点(point)
我们已经非常熟悉的东西,由横纵坐标来组成。当然也有更高维的点,但是在这里我们暂且不提,只考虑二维的点。(不过高维的点也并不复杂,几维就是几个坐标)
我们这样存储:
struct node{
db x,y;
node(){}
node(int _x,int _y){
x=_x;y=_y;
}
};
//这个db 是我 double 的宏定义,下同
向量(vector)
简言就是有方向的量。
我们可以认为向量是一条有向线段,但是它的其中一个点在坐标原点上,因此它既可以用来表示长度,还可以用来表示方向。
可以这么存储:
struct vect{
db x,y;
vect(){}
vect(int _x,int _y){
x=_x;y=_y;
}
};
和物理里面的矢量差不多,好像就只有名字不一样。
所以显然,向量也是满足平行四边形法则的。具体来说就是对于两个向量,它们的和向量是满足其为两向量围成的平行四边形的对角线的。符号表示出来就是:
同理,有:
显然这种运算满足加法交换律,减法的结合律等。
那么我们可以为向量添加一些重载运算符。
inline vect operator + (const vect &a){
return (vect){x+a.x,y+a.y};
}
inline vect operator - (const vect &a){
return (vect){x-a.x,y-a.y};
}
加减介绍完了,现在介绍一下它的特殊运算。
点积(dot product)
先提出规定: 表示向量 , 之间的夹角。
对于向量
那么这个玩意有什么用呢?你发现这个东西的符号和 是同号的,所以可以判断两向量夹角是第几象限角。
如果点积为正,则夹角在第一、四象限
如果点积为负,那么在第二、三象限
浅显一点,可以用来判断夹角是钝角还是锐角还是直角。但是首先保证角度
如果点积为正,则夹角是锐角或者零角
如果点积为负,那么是钝角或平角
如果点积为 ,那么就是直接了
叉积(cross product)
如果叉积为正,则夹角在第一、二象限
如果叉积为负,那么在第三、四象限
显然满足 和
我们还有一个性质:
若 时, 位于 的顺时针方向
若 时, 与 共线,同向或反向
若 时, 位于 的逆时针方向
然后我们发现根本不需要单独的一个点,向量可以完全代替它。为了方便,我们鸠占鹊巢,给向量的结构体改名为 .
现在一个较为完整的向量结构体成型了。
struct point{
db x,y;
point(){}
point(db _x,db _y){
x=_x;y=_y;
}
inline point operator + (const point &a){
return {x+a.x,y+a.y};
}
inline point operator - (const point &a){
return {x-a.x,y-a.y};
}
inline bool operator == (const point &a){
return sgn(x-a.x)==0 and sgn(y-a.y)==0;
}
inline db operator * (const point &a){
return x*a.y-y*a.x;
}
};
inline db dot(const point &a,const point &b){
return a.x*b.x+a.y*b.y;
}
看起来挺不错的。
线(line)
对于线段,我们可以用两个向量(其端点)表示
对于直线和射线,我们考虑一个向量表示基础点,另外一个向量表示方向。但是直线不考虑正反,射线需要考虑。
然后我们判断两条线段是否相交。下面我们介绍一种方法。
设这两条线段为 和
首先我们进行快速排斥实验,如果 对角线形成的矩形与 对角线形成的矩形没有交点,那么直接可以判断线段无交。这个很好判断,用矩形的左下角和右上角的点来判断即可。
显然如果两线段相交,会满足他们互相跨立对方。而如果 跨立 那么,肯定有 和 都在 两侧,即 .等于 的情况我们考虑一下,发现:在经过的快速排斥实验的情况下, 的端点肯定在 上,所以有交点。
然后再同理判断 跨立 即可。然后可以判断两者相交。
好,这是点线相关的一些计算几何,就谈到这里。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具