蒟蒻刚刚开始系统学习计算几何。所有的东西都学自这篇大佬的文章。(不过可能存在一些错误,代码已纠正)

后面有时间了应该会进行一些精修。

//sto command_block orz
#include<bits/stdc++.h>
using namespace std;
#define int long long
const double pi=acos(-1),eps=1e-8;
int sign(double x){return (x<-eps)?-1:(x>eps)?1:0;}//忽略浮点数精度误差 
struct point//其实我们可以把一个点看作原点连向这个点的向量,这样对于计算几何来说相对容易理解一点 
{
	double x,y;
	point operator+(point b){return {x+b.x,y+b.y};}
	point operator-(point b){return {x-b.x,y-b.y};}
	point operator*(double b){return {x*b,y*b};}
	point operator/(double b){return {x/b,y/b};}
	double operator|(point b){return x*b.x+y*b.y;}//内积(数量积)
	double operator^(point b){return x*b.y-y*b.x;}//叉积 
};
point rotate(point a,double rd)//将某个点绕原点逆时针旋转(幅角这里用弧度来表示,便于使用内置 sin 函数) 
{
	double s1=sin(rd),s2=cos(rd);
	return {a.x*s2-a.y*s1,a.x*s1+a.y*s2};
	/*
	原向量 (x1,y1) -> (cosθ*l,sinθ*l),其中 θ 为原幅角,l 为原向量长度 
	新幅角 -> ɑ+θ,ɑ 为旋转幅角(rd) 
	新向量长度不变,等价于 -> (cos(ɑ+θ)*l,sin(ɑ+θ)*l) 
	用三角恒等变换 -> ((cosθcosɑ-sinθsinɑ)*l,(sinθcosɑ+sinɑcosθ)*l) 
	*/
}
double dis(point p1,point p2){return sqrt((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y));}//距离公式 
struct line
{
	point a,b;
	double len(){return dis(a,b);}
};
bool onl0(point a,line l)//判断一个点是否在一条直线上 
{
	return sign((a-l.a)^(a-l.b))==0;
	//三点共线也同时意味着这三点形成的三角形面积为 0,直接判断叉积即可
}
bool onl2(point a,line l)//判断一个点是否在一个线段上 
{
	return onl0(a,l)&&//首先你肯定要共线 
		sign(a.x-min(l.a.x,l.b.x))>=0&&
		sign(a.y-min(l.a.y,l.b.y))>=0&&
		sign(a.x-max(l.a.x,l.b.x))<=0&&
		sign(a.y-max(l.a.y,l.b.y))<=0;//然后判断这个点是否位于这条线所处的矩形内 
}
point inter(line l1,line l2)
{
	double ls=(l1.b-l1.a)^(l2.a-l1.a);//算出左半三角形的面积的 2 倍
	double rs=(l1.b-l1.a)^(l2.b-l1.a);//算出右半三角形的面积的 -2 倍
	return l2.a+(l2.b-l2.a)*ls/(ls-rs); //根据面积比算出对应向量的长度,用 l2 左端点加上就是交点(原笔记上的记成了 l1,在这里予以更正) 
}
double disl0(point a,line l)//计算一个点到一条直线的最短距离 
{
	return abs((l.a-a)^(l.b-a)/l.len());
	//计算三个点的三角形面积除去直线长度即为垂线段长度(即所求距离) 
}
double disl2(point a,line l)//计算一个点到一条线段的最短距离 
{
	if(sign((a-l.a)|(l.b-l.a))<0||sign((a-l.b)|(l.a-l.b))<0)
		return min(dis(a,l.a),dis(a,l.b));
	//计算点 A 连向线段的两个与线段的夹角是否有一个为钝角,这里只需要判断两个内积是否有一个为负就行了。 
	return disl0(a,l);
}
signed main()
{
	//完全胜利!!! 
	return 0; 
}
//completed: 2026/8/27 21:00

无注释版:

#include<bits/stdc++.h>
using namespace std;
#define int long long
const double pi=acos(-1),eps=1e-8;
int sign(double x){return (x<-eps)?-1:(x>eps)?1:0;}
struct point
{
	double x,y;
	point operator+(point b){return {x+b.x,y+b.y};}
	point operator-(point b){return {x-b.x,y-b.y};}
	point operator*(double b){return {x*b,y*b};}
	point operator/(double b){return {x/b,y/b};}
	double operator|(point b){return x*b.x+y*b.y;}
	double operator^(point b){return x*b.y-y*b.x;}
};
point rotate(point a,double rd)
{
	double s1=sin(rd),s2=cos(rd);
	return {a.x*s2-a.y*s1,a.x*s1+a.y*s2};
}
double dis(point p1,point p2){return sqrt((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y));}
struct line
{
	point a,b;
	double len(){return dis(a,b);}
};
bool onl0(point a,line l)
{
	return sign((a-l.a)^(a-l.b))==0;
}
bool onl2(point a,line l)
{
	return onl0(a,l)&&
		sign(a.x-min(l.a.x,l.b.x))>=0&&
		sign(a.y-min(l.a.y,l.b.y))>=0&&
		sign(a.x-max(l.a.x,l.b.x))<=0&&
		sign(a.y-max(l.a.y,l.b.y))<=0;
}
point inter(line l1,line l2)
{
	double ls=(l1.b-l1.a)^(l2.a-l1.a);
	double rs=(l1.b-l1.a)^(l2.b-l1.a);
	return l2.a+(l2.b-l2.a)*ls/(ls-rs);
}
double disl0(point a,line l)
{
	return abs((l.a-a)^(l.b-a)/l.len());
}
double disl2(point a,line l)
{
	if(sign((a-l.a)|(l.b-l.a))<0||sign((a-l.b)|(l.a-l.b))<0)
		return min(dis(a,l.a),dis(a,l.b));
	return disl0(a,l);
}
signed main()
{
	return 0; 
}