求多边形(覆盖)面积(模板)

求多个多边形的总面积以及多边形的相互覆盖以后的面积 

给定每个点的坐标。

#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
",-t1,-t2);
    return 0;
}
原文地址:https://www.cnblogs.com/nublity/p/9582906.html