计算几何全家桶(基础)

计算几何全家桶(基础)

其实只是记录一些可能会用到的非常基础的东西(懒得多次反复写了)。

一:【准备工作】

#include <bits/stdc++.h>
#define dd double
using namespace std;
const int N=1e5;const dd eps=1e-8,PI=acos(-1.0);
int jd(dd x){return a<-eps?-1:(a>eps?1:0);}//精度控制
dd ABS(dd x){return x*jd(x);}//求绝对值 
struct d{
	dd x,y;d(X=0,Y=0){x=X;y=Y;}
	void in(){scanf("%lf%lf",&x,&y);}
	void out(){printf("%.5lf %.5lf\n",x,y);}
};//结构体存点或向量 以及输入输出 

没啥好说的,就是一些初始化。

二:【向量】

1.【模】

对于 a=(x,y)|a|=x2+y2=|a|2=aa,所以可以用下面的 点积 解决。

dd len(d a){return sqrt(dj(a,a);}//模

2.【向量加减】

对于 a=(x1,y1),b=(x2,y2)a+b=(x1+x2,y1+y2)
对于 a=(x1,y1),b=(x2,y2)ab=(x1x2,y1y2)

d operator+(d a,d b){return d(a.x+b.x,a.y+b.y);}
d operator-(d a,d b){return d(a.x-b.x,a.y-b.y);}

3.【向量数乘】

对于 a=(x,y)λa=(λx,λy)
对于 a=(x,y)aλ=(xλ,yλ)(其实向量除就是向量乘的逆运算)

d operator*(d a,dd b){return d(a.x*b,a.y*b);}
d operator/(d a,dd b){return d(a.x/b.a.y/b);}

4.【向量点积(数量积)(内积)】

定义:ab=|a||b|cosθ(θ=a,b)
对于 a=(x1,y1),b=(x2,y2)ab=x1x2+y1y2
夹角 θ 与点积的关系:

  • θ=0ab=|a||b|
  • θ=180ab=|a||b|
  • θ<90ab>0
  • θ=90ab=0
  • θ>90ab<0
dd dj(d a,d b){return a.x*b.x+a.y*b.y;}//点积 

5.【向量叉积(向量积)(外积)】

定义:a×b=|a||b|sinθ(θ=a,b)
对于 a=(x1,y1),b=(x2,y2)a×b=x1y2+x2y1
向量 a,b 的位置与叉积的关系:

  • a//b,a×b=0
  • ab 左侧,a×b<0
  • ab 右侧,a×b>0
dd cj(d a,d b){return a.x*b.y-a.y*b.x;}//叉积

6.【向量夹角】

因为 ab=|a||b|cosθ(θ=a,b),所以 cosθ=ab|a||b|(θ=a,b)

dd angle(d a,d b){return acos(dj(a,b)/len(a)/len(b));}//两向量夹角

三:【点、向量的位置变换】

1.【点、向量绕原点的旋转】

对于点或向量 (x,y),将其顺时针旋转 θ 度: |xy|×|cosθsinθsinθcosθ|=|xcosθ+ysinθxsinθ+ycosθ|

d turn(d a,dd theta){
    dd x=a.x*cos(theta)+a.y*sin(theta);
    dd y=-a.x*sin(theta)+a.y*cos(theta);
    return d(x,y);
}//点或向量 A 绕原点顺时针旋转 theta 度

2.【点绕点的旋转】

对于点 A(x1,y1) 绕点 B(x2,y2) 顺时针旋转 θ 度: |(x1x2)cosθ+(y1y2)sinθ+x2(x1x2)sinθ+(y1y2)cosθ+y2|

d turn_(d a,d b,dd theta){
    dd x=(a.x-b.x)*cos(theta)+(a.y-b.y)*sin(theta)+b.x;
    dd y=-(a.x-b.x)*sin(theta)+(a.y-b.y)*cos(theta)+b.y;
    return d(x,y);
}//点 A 绕点 B 顺时针旋转 theta 度

3.【法向量】

对于向量 a=(x,y),法向量就是垂直于向量 a 的向量。
联系上面的向量绕原点旋转可知,求一个向量的法向量就是将这个向量顺时针旋转 90

d Normal(d a){return d(-a.y,a.x);}//求法向量

计算几何全家桶(基础)综合代码

#include <bits/stdc++.h>
#define dd double
using namespace std;
/*--------------------------------------------*/
const int N=1e5;const dd eps=1e-8,PI=acos(-1.0);
int jd(dd x){return x<-eps?-1:(x>eps?1:0);}//精度控制
dd ABS(dd x){return x*jd(x);}//求绝对值 
struct d{
    dd x,y;d(dd X=0,dd Y=0){x=X;y=Y;}
    void in(){scanf("%lf%lf",&x,&y);}
    void out(){printf("%.5lf %.5lf\n",x,y);}
};//结构体存点或向量 以及输入输出 
/*--------------------------------------------*/
dd dj(d a,d b){return a.x*b.x+a.y*b.y;}//点积 
dd cj(d a,d b){return a.x*b.y-a.y*b.x;}//叉积
dd len(d a){return sqrt(dj(a,a));}//模
dd angle(d a,d b){return acos(dj(a,b)/len(a)/len(b));}//两向量夹角 
/*向量四则运算*/
d operator+(d a,d b){return d(a.x+b.x,a.y+b.y);}
d operator-(d a,d b){return d(a.x-b.x,a.y-b.y);}
d operator*(d a,dd b){return d(a.x*b,a.y*b);}
d operator/(d a,dd b){return d(a.x/b,a.y/b);}
d Normal(d a){return d(-a.y,a.x);}//求法向量
bool operator==(d a,d b){return !jd(a.x-b.x)&&!jd(a.y-b.y);}//判相等 
/*-------------------------------------------*/
d turn(d a,dd theta){
    dd x=a.x*cos(theta)+a.y*sin(theta);
    dd y=-a.x*sin(theta)+a.y*cos(theta);
    return d(x,y);
}//点或向量 A 绕原点顺时针旋转 theta 度
d turn_(d a,d b,dd theta){
    dd x=(a.x-b.x)*cos(theta)+(a.y-b.y)*sin(theta)+b.x;
    dd y=-(a.x-b.x)*sin(theta)+(a.y-b.y)*cos(theta)+b.y;
    return d(x,y);
}//点 A 绕点 B 顺时针旋转 theta 度 
/*-------------------------------------------*/

int main(){}
posted @   AIskeleton  阅读(64)  评论(0编辑  收藏  举报
编辑推荐:
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具
· AI 智能体引爆开源社区「GitHub 热点速览」
· C#/.NET/.NET Core技术前沿周刊 | 第 29 期(2025年3.1-3.9)
点击右上角即可分享
微信分享提示