计算几何大模板
#include<map>
#include<cmath>
#include<queue>
#include<vector>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=1e5+100;
const double Pi=3.14159265358979323846,eps=1e-9;
struct Vector{
double x,y;
Vector(double xx=0,double yy=0){
x=xx,y=yy;
}
};
struct Point{
double x,y;
Point(double xx=0,double yy=0){
x=xx,y=yy;
}
};
struct Line{
Point p;
Vector v;
double ang;
Line(Point a=Point(),Vector b=Vector()){
p=a,v=b;
ang=atan2(v.y,v.x);
}
}q[maxn];
int dcmp(double p){return fabs(p)<eps?0:p>0;}
Vector operator + (Vector a,Vector b){return Vector(a.x+b.x,a.y+b.y);}
Vector operator - (Vector a,Vector 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 * (double p,Vector a){return Vector(a.x*p,a.y*p);}
Vector operator / (Vector a,double p){return Vector(a.x/p,a.y/p);}
Vector operator - (Point a,Point b){return Vector(a.x-b.x,a.y-b.y);}
Point operator + (Point a,Vector b){return Point(a.x+b.x,a.y+b.y);}
Point operator - (Point a,Vector b){return Point(a.x-b.x,a.y-b.y);}
bool operator == (Point a,Point b){return a.x==b.x&&a.y==b.y;}
bool operator < (Point a,Point b){return a.x==b.x?a.y<b.y:a.x<b.x;}
double operator * (Vector a,Vector b){return a.x*b.y-a.y*b.x;}//叉积 b在a左为正
double operator * (Point a,Point b){return a.x*b.y-a.y*b.x;}//面积计算用到
bool operator < (Line a,Line b){return dcmp(a.ang-b.ang)==0?dcmp(a.v*(b.p-a.p))>0:(a.ang<b.ang);}
double dot(Vector a,Vector b){return a.x*b.x+a.y*b.y;}//点积
double len(Vector a){return sqrt(dot(a,a));}//向量长
double angle(Vector a,Vector b){return acos(dot(a,b)/len(a)/len(b));}//向量夹角
Vector unit(Vector a){int l=len(a); return Vector(a.x/l,a.y/l);}//单位向量
Vector rotate(Vector a,double p){return Vector(a.x*cos(p)-a.y*sin(p),a.x*sin(p)+a.y*cos(p));}//转
Vector normal(Vector a){return rotate(unit(a),Pi/2);}//单位法向量
double distl(Point p,Point a,Point b){Vector u=p-a,v=b-a; return fabs(u*v)/len(v);}//a到直线bc距离
double dists(Point p,Point a,Point b){
if(a==b) return len(a-p);
Vector v1=b-a,v2=p-a,v3=p-b;
if(dcmp(dot(v1,v2))<0) return len(v2);
else if(dcmp(dot(v1,v3))>0) return len(v3);
return fabs(v1*v2)/len(v1);
}//a到线段bc距离
bool setment(Point a,Point b,Point c,Point d){
Vector x=b-a,y=d-c;
Vector v1=a-c,v2=b-c;
if(dcmp(y*v1)==dcmp(y*v2)) return 0;
v1=c-a,v2=d-a;
if(dcmp(x*v1)==dcmp(x*v2)) return 0;
return 1;
}//判断两线段是否相交(端点在两侧)
Point glt(Point a,Point b,Point c,Point d){
Vector v1=b-a,v2=d-c,v3=a-c;
double t=v2*v3/(v1*v2);
return a+v1*t;
}//两直线交点
Point glt(Line a,Line b){Vector v=a.p-b.p; return a.p+b.v*v/(a.v*b.v)*a.v;}//两直线交点
bool onleft(Line l,Point b){return dcmp(l.v*(b-l.p))>0;}//点在向量左边
bool onright(Line a,Line b,Line t){Point p=glt(a,b); return dcmp(t.v*(p-t.p))<0;} //右边
int pointin(Point p,Point *a,int n){
int cnt=0;
for(int i=1;i<=n;i++){
if(dcmp(dists(p,a[i],a[i%n+1]))==0) return -1;
int x=dcmp(a[i].y-p.y),y=dcmp(a[i%n+1].y-p.y);
double z=(a[i%n+1]-a[i])*(p-a[i]);
if(x<=0&&y>0&&z>0) cnt++;
if(y<=0&&x>0&&z<0) cnt--;
}
if(cnt) return 1;
return 0;
} //判断点在多边形内
double S(Point *p,int n){
p[n+1]=p[1];
double ans=0;
for(int i=1;i<=n;i++)
ans+=p[i]*p[i+1];
return fabs(ans)/2;
}//多边形面积
Point cog(Point *p,int n){
double x=0,y=0,m=0;
for(int i=2;i<n;i++){
double mq=(p[i]-p[1])*(p[i+1]-p[1]);
x+=mq*(p[i].x+p[i%n+1].x+p[1].x)/3,y+=mq*(p[i].y+p[i%n+1].y+p[1].y)/3,m+=mq;
}
return Point(x/m,y/m);
} //重心
double C(Point *p,int n){
double ans=0;
for(int i=1;i<n;i++)
ans+=len(p[i+1]-p[i]);
return ans+len(p[1]-p[n]);
}//周长
void tb(Point *p,int n,Point *q,int &m){
q[m=1]=p[1];
if(n==1)
return;
sort(p+1,p+n+1);
for(int i=1;i<=n;i++){
while(m>1&&dcmp((q[m]-q[m-1])*(p[i]-q[m-1]))<=0)
m--;
q[++m]=p[i];
}
int k=m;
for(int i=n-1;i>1;i--){
while(m>k&&dcmp((q[m]-q[m-1])*(p[i]-q[m-1]))<=0)
m--;
q[++m]=p[i];
}
} //凸包
void bpm(Line *b,int &n,Point *p){
sort(b+1,b+n+1);
int l=0,r=1,tot=0;
for(int i=1;i<=n;i++){
if(b[i].ang!=b[i-1].ang) tot++;
b[tot]=b[i];
}
n=tot,q[0]=b[1],q[1]=b[2];
for(int i=3;i<=n;i++){
while(l<r&&onright(q[r],q[r-1],b[i])) r--;
while(l<r&&onright(q[l],q[l+1],b[i])) l++;
q[++r]=b[i];
}
while(l<r&&onright(q[r],q[r-1],q[l])) r--;
while(l<r&&onright(q[l],q[l+1],q[r])) l++;
n=0,q[r+1]=q[l];
for(int i=l;i<=r;i++)
p[++n]=glt(q[i],q[i+1]),b[n]=q[i];
}//离线求半平面交
void cut(Line a,Point *p,int &n){
int cnt=0;
Point tmp[maxn];
for(int i=1;i<=n;i++){
int x=dcmp(a.v*(p[i]-a.p));
int y=dcmp(a.v*(p[i%n+1]-a.p));
if(x<=0) tmp[++cnt]=p[i];
if(x*y<0) tmp[++cnt]=glt(Line(p[i],p[i%n+1]-p[i]),a);
}
n=cnt;
for(int i=1;i<=cnt;i++) p[i]=tmp[i];
}//半平面交加入一个半平面
double kake(Point *p,int n){
if(n==1) return 0;
if(n==2) return len(p[1]-p[2]);
int now=1;
double ans=0;
p[n+1]=p[1];
for(int i=1;i<=n;i++){
while(dcmp(distl(p[now],p[i],p[i+1])-distl(p[now+1],p[i],p[i+1]))<=0)
now=now%n+1;
ans=max(ans,dot(p[now]-p[i],p[now]-p[i]));
ans=max(ans,dot(p[now]-p[i+1],p[now]-p[i+1]));
}
return ans;
} //旋转卡壳
double minl(Point *p,int n,Point *q,int m){
int x=1,y=1;
double ans=1e10;
for(int i=1;i<=n;i++)
x=p[x].y>p[i].y?i:x;
for(int i=1;i<=m;i++)
y=q[y].y<q[i].y?i:y;
p[n+1]=p[1],q[m+1]=q[1];
for(int i=1;i<=n;i++){
int t;
while((t=dcmp((p[x]-p[x+1])*(q[y+1]-q[y])))<0)
y=(y+1)%m;
if(t==0){
ans=min(ans,dists(p[x],q[y],q[y+1]));
ans=min(ans,dists(p[x+1],q[y],q[y+1]));
ans=min(ans,dists(q[y],p[x],p[x+1]));
ans=min(ans,dists(q[y+1],p[x],p[x+1]));
}
else
ans=min(ans,dists(q[y],p[x],p[x+1]));
x=(x+1)%n;
}
return ans;
}//求两凸壳间最近点对
int main(){
return 0;
}