• 计算几何模板


    计算几何大模板

    #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; 
    }
    
  • 相关阅读:
    Oracle:windows下,纯控制台方式(即前台,而不是后台服务)启动oracle实例、及tnslsnr实例
    创建本地离线 .deb包 仓库:ubuntu、debian、mint等:dpkgdev工具包中的“dpkgscanpackages”
    ubuntu22.04liveserveramd64.iso:安装界面的高级应用
    Golang 实现 Redis(11): RDB 文件格式 Finley
    Golang 实现 Redis(10): 本地原子性事务 Finley
    threadX
    嵌入式调试
    网络定位
    linux驱动移植usb驱动基础
    linux驱动移植LCD触摸屏驱动案例
  • 原文地址:https://www.cnblogs.com/nianheng/p/10066563.html
Copyright © 2020-2023  润新知