参照学校大佬的模板整理出文章来源地址https://www.toymoban.com/news/detail-622228.html
定义
const double eps=1e-18;
//记录点的横纵坐标
struct Pot{
double x,y;
};
//记录线段的起始点和终点
struct Line{
Pot st,ed;
};
//记录圆的圆心和半径
struct Circle{
Pot p;
double r;
};
判断小数大小和正负
//判断小数的正负,如果绝对值小于精度就返回0,小于0就返回-1,否则返回1
int sign(double x){
if(fabs(x)<eps)return 0;
if(x<0)return -1;
return 1;
}
//比较小数的大小,如果x-y小于精度那么认为他们相等,如果x<y就返回-1,x大于y就返回1
int dcmp(double x,double y){
if(fabs(x-y)<eps)return 0;
if(x<y)return -1;
return 1;
}
两个点的坐标加减乘除运算
Pot operator + (Pot a,Pot b){
return {(a.x+b.x),(a.y +b.y )};
}
//两个点相减的坐标
Pot operator - (Pot a,Pot b){
return {(a.x -b.x ),(a.y -b.y )};
}
//判断两个点是否坐标相等
bool operator == (Pot a,Pot b){
if(dcmp(a.x,b.x)==0&&dcmp(a.y,b.y)==0)return 1;
return 0;
}
两个向量运算
//求一个向量长度乘c之后的向量
Pot operator * (Pot a,double c){
return {(a.x*c),(a.y *c)};
}
//求一个向量除以c之后的向量
Pot operator / (Pot a,double c){
return {(a.x/c),(a.y /c)};
}
//向量a在向量b上的投影与b长度的乘积
//a*b=|a||b|cos(c)
double dot(Pot a,Pot b){
return a.x*b.x+a.y *b.y ;
}
//向量a与b张成的平行四边形的有向面积,b在a的逆时针方向为正
//a*b=|a||b|sin(c)
double cross(Pot a,Pot b){
return a.x *b.y -b.x *a.y ;
}
点到点的距离
//a到原点的距离
double get_length(Pot a){
return sqrt(dot(a,a));
}
//点a和点b之间的距离
double dist(Pot a,Pot b){
return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
点到线的距离
//点p到直线ab的距离
double dist_to_line(Pot p,Pot a,Pot b){
Pot v1=b-a,v2=p-a;
return fabs(cross(v1,v2)/get_length(v1));
}
//点p到线段ab的距离
double dist_to_seg(Pot p,Pot a,Pot b){
if(a==b)return get_length(p-a);
Pot v1=b-a,v2=p-a,v3=p-b;
if(sign(dot(v1,v2))<0)return get_length(v2);
if(sign(dot(v1,v3))>0)return get_length(v3);
return dist_to_line(p,a,b);
}
两直线交点,判断线段是否相交
//求两直线的交点,v为p的向量,w为q的向量
Pot get_Line_inter(Pot p,Pot v,Pot q,Pot w){
Pot u=p-q;
double t=cross(w,u)/cross(v,w);
return p+v*t;
}
//判断两线段是否相交
bool xiangjiao(Pot a1,Pot a2,Pot b1,Pot b2){
double c1=cross(a2-a1,b1-a1),c2=cross(a2-a1,b2-a1);
double c3=cross(b2-b1,a2-b1),c4=cross(b2-b1,a1-b1);
return sign(c1)*sign(c2)<=0&&sign(c3)*sign(c4)<=0;
}
返回点aob形成的角的角度
//返回角aOb的角度,返回的是弧度
double get_angle(Pot a,Pot b){
return acos(dot(a,b)/get_length(a)/get_length(b));
}
已知三点坐标求形成的三角形面积
//返回三个点构成的三角形面积的两倍
double area(Pot a,Pot b,Pot c){
return cross(b-a,c-a);
}
已知三条边长求三角形面积
//三条边长求三角形面积
double helen(double a,double b,double c){
double p=(a+b+c)/2;
return sqrt(p*(p-a)*(p-b)*(p-c));
}
一个点绕原点顺时针旋转x度
//返回三个点构成的三角形面积的两倍
double area(Pot a,Pot b,Pot c){
return cross(b-a,c-a);
}
判断点是否在线段上
//判断点p是否在线段ab上
bool on_seg(Pot p,Pot a,Pot b){
return sign(cross(p-a,p-b))==0&&sign(dot(p-a,p-b))<=0;
}
n个点组成的多边形的面积
//n个点从0到n-1求多边形面积
double Polygon_area(Pot p[],int n){
double s=0;
for(int i=1;i+1<n;i++){
s+=cross(p[i]-p[0],p[i+1]-p[i]);
}
return s/2;
}
点在直线上的投影
//点p在直线ab上的投影
Pot get_line_pro(Pot p,Pot a,Pot b){
Pot v=b-a;
return a+v*(dot(v,p-a)/dot(v,v));
}
文章来源:https://www.toymoban.com/news/detail-622228.html
到了这里,关于计算几何公式(点到直线距离,点到线段距离等)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!