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


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

    给定每个点的坐标。

    #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;
    }
  • 相关阅读:
    MySQL数据库----数据类型
    MySQL数据库----安装
    I2c串行总线组成及其工作原理
    感慨
    液晶操作
    串口通信
    9.19AD和DA操作
    9.19键盘的应用
    9.17键盘的操作
    9.15学习笔记
  • 原文地址:https://www.cnblogs.com/nublity/p/9582906.html
Copyright © 2020-2023  润新知