• 计算几何小结计算几何小结


    计算几何小结

    计算几何是个好东西,写代码感觉在写LemonLime(不你没真正写过),一层层堆叠起来,真(难)好(调)玩。

    占坑

    //@winlere
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #include<queue>
    #include<assert.h>
    #define pf(x) ((x)*(x))
    
    using namespace std;  typedef long long ll;
    inline int qr(){
    	int ret=0,f=0,c=getchar();
    	while(!isdigit(c))f|=c==45,c=getchar();
    	while(isdigit(c)) ret=ret*10+c-48,c=getchar();
    	return f?-ret:ret;
    }
    
    struct NODE{
    	double x,y;
    	NODE operator + (NODE b)const{return {x+b.x,y+b.y};}
    	NODE operator - (NODE b)const{return {x-b.x,y-b.y};}
    	NODE operator * (double b)const{return {x*b,y*b};}
    	double operator % (NODE b)const{return x*b.y-y*b.x;}
    	double operator ^ (NODE b)const{return sqrt(pf(x-b.x)+pf(y-b.y));}
    	bool operator < (NODE b)const{return atan2(y,x)<atan2(b.y,b.x);}
    	bool operator == (NODE b)const{return x==b.x&&y==b.y;}
    };
    
    double atan2(NODE a){return atan2(a.y,a.x);}
    
    struct LINE{
    	NODE vec,pt;
    	LINE(NODE a,NODE b):vec(b-a),pt(a){}
    	bool operator < (LINE b)const{return atan2(vec)==atan2(b.vec)?b.vec%(pt-b.pt)>0:vec<b.vec;}
    	NODE operator * (LINE b)const{
    		//no exist para
    		NODE A=vec,B=b.vec,C=b.pt-pt;
    		//if(B%A==0) return {1e9,1e9};
    		double t=(B%C)/(B%A);
    		//assert(t==t);
    		return pt+vec*t;
    	}
    };
    
    typedef vector<NODE> mat;
    typedef vector<LINE> poly;
    poly data;
    const double bound=1000;
    double sum(poly data){
    	if(data.size()<3) return 0;
    	double ret=0;
    	sort(data.begin(),data.end());
    	NODE x={0,0};
    	for(int t=0,ed=data.size();t<ed;++t)
    		ret+=(data[t]*data[(t-1+ed)%ed]-x)%(data[t]*data[(t+1)%ed]-x);	
    	assert(ret==ret);
    	return ret/2;
    }
    
    poly Surface(poly _data){
    	sort(_data.begin(),_data.end());
    	poly data;
    	for(int t=0,r=0,ed=_data.size();r<ed;t=++r){
    		while(r+1<ed&&atan2(_data[t].vec)==atan2(_data[r+1].vec)) ++r;
    		data.push_back(_data[t]);
    	}
    	deque<LINE> q(data.begin(),data.begin()+2);
    	for(int t=2,ed=data.size();t<ed;++t){
    		while(q.size()>1){
    			NODE m=q[q.size()-1]*q[q.size()-2];
    			assert(m.x<=1e7);
    			if(data[t].vec%(m-data[t].pt)<0) q.pop_back();
    			else break;
    		}
    		while(q.size()>1){
    			NODE m=q[0]*q[1];
    			assert(m.x<=1e7);
    			if(data[t].vec%(m-data[t].pt)<0) q.pop_front();
    			else break;
    		}
    		q.push_back(data[t]);
    	}
    	while(q.size()>1){
    		NODE m=q[q.size()-1]*q[q.size()-2];
    		assert(m.x<=1e7);
    		if(q.front().vec%(m-q.front().pt)<0) q.pop_back();
    		else break;
    	}
    	while(q.size()>1){
    		NODE m=q[0]*q[1];
    		assert(m.x<=1e7);
    		if(q.back().vec%(m-q.back().pt)<0) q.pop_front();
    		else break;
    	}
    	return poly(q.begin(),q.end());
    }
    
    int main(){
    	int n=qr();
    	for(int t0=1;t0<=n;++t0){
    		mat sav(qr());
    		for(auto&t:sav) t.x=qr(),t.y=qr();
    		for(int i=0,ed=sav.size();i<ed;++i)
    			data.push_back(LINE(sav[i],sav[(i+1)%ed]));
    		sort(data.begin(),data.end());
    	}
    	double k=sum(Surface(data));
    	printf("%.5lf
    ",k);
    	return 0;
    }
    
    
    
  • 相关阅读:
    UWP取出图片主色调
    UWP上可用的GB2312编码
    嵌入的资源 和 Resource
    WPF 斜角border
    .net core初试 --- 控制台程序
    Python初学手记----在window系统中安装环境
    我的第一个网络爬虫 C#版 福利 程序员专车
    使用FFMpeg命令行录屏推rtmp流
    WPF制作表示透明区域的马赛克画刷
    WPF之坑——surface触控失灵之谜
  • 原文地址:https://www.cnblogs.com/winlere/p/12142688.html
Copyright © 2020-2023  润新知