求多边形(覆盖)面积(模板)
求多个多边形的总面积以及多边形的相互覆盖以后的面积
给定每个点的坐标。
#include <bits/stdc++.h>//求多个多边形的总面积以及多边形的相互覆盖以后的面积 #define ll long long #define met(a,x) memset(a,x,sizeof(a)) #define ull unsigned long long #define mp make_pair using namespace std; const double pi=4*atan(1.0); const int mod=1e9+7; const double inf=1e200; const double eps=1e-12; int dcmp(double x) { return fabs(x)<eps?0:(x<0?-1:1); } struct node { double x,y; node(double a=0,double b=0):x(a),y(b) {} }; vector<node>pp[110]; pair<double,int>s[110*60]; node operator +(node A,node B) { return node(A.x+B.x,A.y+B.y); } node operator -(node A,node B) { return node(A.x-B.x,A.y-B.y); } node operator *(node A,double p) { return node(A.x*p,A.y*p); } node operator /(node A,double p) { return node(A.x/p,A.y/p); } bool operator ==(const node& a,const node& b) { return fabs(a.x-b.x)<eps&&fabs(a.y-b.y)<eps; } double seg(node O,node A,node B) { if(dcmp(B.x-A.x)==0) return (O.y-A.y)/(B.y-A.y); return (O.x-A.x)/(B.x-A.x); } double det(node A,node B) { return A.x*B.y-A.y*B.x; } double det(node O,node A,node B) { return det(A-O,B-O); } double area(vector<node>p) { double ans=0; int sz=p.size(); for(int i=1; i<sz-1; i++) ans+=det(p[i]-p[0],p[i+1]-p[0]); return ans/2.0; } double dot(node A,node B) { return A.x*B.x+A.y*B.y; } double length(node A) { return sqrt(dot(A,A)); } double polyunion(vector<node>*p,int n) { int i,j,k,ii; double ans=0; for(int i=0; i<n; i++) { int sz=p[i].size(); for(j=0; j<sz; j++) { int m=0; s[m++]=mp(0,0); s[m++]=mp(1,0); node a=p[i][j],b=p[i][(j+1)%sz]; for(k=0; k<n; k++) { if(i!=k) { int cnt=p[k].size(); for(ii=0; ii<cnt; ii++) { node c=p[k][ii],d=p[k][(ii+1)%cnt]; int c1=dcmp(det(b-a,c-a)); int c2=dcmp(det(b-a,d-a)); if(c1==0&&c2==0) { if(dcmp(dot(b-a,d-c))) { s[m++]=mp(seg(c,a,b),1); s[m++]=mp(seg(c,a,b),-1); } } else { double s1=det(d-c,a-c); double s2=det(d-c,b-c); if(c1>=0&&c2<0) s[m++]=mp(s1/(s1-s2),1); else if(c1<0&&c2>=0) s[m++]=mp(s1/(s1-s2),-1); } } } } sort(s,s+m); double pre=min(max(s[0].first,0.0),1.0),now,sum=0; int cover=s[0].second; for(int j=1; j<m; j++) { now=min(max(s[j].first,0.0),1.0); if(!cover) sum+=now-pre; cover+=s[j].second; pre=now; } ans+=det(a,b)*sum; } } return ans/2; } int main() { ios::sync_with_stdio(false); cin.tie(0); int i,j,k,m,n; node tp; cin>>n; //共有n个多边形 for(i=0; i<n; i++) { //每个多边形有m个点 cin>>m; for(j=0; j<m; j++) { //每个点的坐标 cin>>tp.x>>tp.y; pp[i].push_back(tp); } } double t1=0,t2=polyunion(pp,n); for(i=0; i<n; i++) t1+=area(pp[i]); //第一个是总面积,第二个是覆盖以后的面积 cout<<fixed<<setprecision(7)<<(-t1)<<' '<<fixed<<setprecision(7)<<(-t2)<<endl; //printf("%.7lf %.7lf\n",-t1,-t2); return 0; }