计算几何模板
不定期扩展!
#include<bits/stdc++.h> using namespace std; const double pi = acos(-1.0); const double inf = 1e100; const double eps = 1e-6; struct Point{ double x, y; Point(double x = 0, double y = 0):x(x),y(y){} //构造函数 方便代码编写 }; typedef Point Vector; //点的别名 Vector operator + (Vector A, Vector B){ return Vector(A.x+B.x, A.y+B.y); } //向量+向量=向量 Vector operator - (Point A, Point B){ return Vector(A.x-B.x, A.y-B.y); } //点-点=向量 Vector operator * (Vector A, double p){ return Vector(A.x*p,A.y*p); } //向量*数=向量 Vector operator / (Vector A,double p){ return Vector(A.x/p,A.y/p); } //向量/数=向量 bool operator < (const Point &a, const Point &b){ return a.x<b.x || (a.x==b.x && a.y<b.y); } //用于排序 int dcmp(double x){ if(fabs(x)<eps) return 0; else return x<0?-1:1; } //正数 1 负数 -1 零 0 bool operator == (const Point &a, const Point &b){ return dcmp(a.x-b.x)==0&&dcmp(a.y-b.y)==0; } //判断两向量是否相等 double Dot(Vector A, Vector B){ return A.x*B.x+A.y*B.y; } //点积 double Length(Vector A){ return sqrt(Dot(A,A)); } //向量的模长 double Angle(Vector A, Vector B){ return acos(Dot(A,B)/Length(A)/Length(B)); } //弧度表示的角度 double Cross(Vector A, Vector B){ return A.x*B.y-A.y*B.x; } //叉积 可用来判断两个向量的位置关系 如果B在A的逆时针方向 叉积为正 反之 叉积为正 //若两向量共线则叉积为0 double Area2(Point A,Point B,Point C){ return Cross(B-A,C-A); } //向量B-A和向量C-A的叉积 就是平行四边形的面积 Vector Rotate(Vector A, double rad){ return Vector(A.x*cos(rad)-A.y*sin(rad),A.x*sin(rad)+A.y*cos(rad)); } //向量旋转公式 rad为弧度 Vector Normal(Vector A){ double L=Length(A); return Vector(-A.y/L,A.x/L); } //求向量的法线 向量不能是零向量 Point GetLineIntersection(Point P,Vector v,Point Q,Vector w){ Vector u=P-Q; double t= Cross(w,u)/Cross(v,w); return P+v*t; } //计算两直线的交点 两直线不能平行 double DistanceToLine(Point P,Point A,Point B){ Vector v1=B-A; Vector v2=P-A; return fabs(Cross(v1,v2))/Length(v1); } //求点p到直线ab的距离 double DistanceToSegment(Point P,Point A,Point B){ if(A==B) return Length(P-A); Vector v1=B-A; Vector v2=P-A; Vector v3=P-B; if(dcmp(Dot(v1,v2))<0) return Length(v2); else if(dcmp(Dot(v1,v3))>0) return Length(v3); else return fabs(Cross(v1,v2))/Length(v1); } //求点p到线段ab的距离 bool SegmentProperIntersection(Point a1,Point a2,Point b1,Point b2){ double c1=Cross(a2-a1,b1-a1),c2=Cross(a2-a1,b2-a1), c3=Cross(b2-b1,a1-b1),c4=Cross(b2-b1,a2-b1); return dcmp(c1)*dcmp(c2)<0 && dcmp(c3)*dcmp(c4)<0; } //判断两线段规范相交(即两线段恰好只有一个公共点,且不再任何一条线段的端点) bool onSegment(Point p,Point a1,Point a2){ return dcmp(Cross(a1-p,a2-p))==0&&dcmp(Dot(a1-p,a2-p))<0; } //判断一个点是否在线段a1a2上 double PolygonArea(Point p[],int n){ double area=0; for(int i=1;i<n-1;i++) area+=Cross(p[i]-p[0],p[i+1]-p[0]); return area/2; } //求多边形的面积