zoukankan      html  css  js  c++  java
  • 求多边形(覆盖)面积(模板)

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

    给定每个点的坐标。

    #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;
    }
  • 相关阅读:
    Windows Store App 主题动画
    Windows Store App 过渡动画
    Windows Store App 控件动画
    Windows Store App 近期访问列表
    Windows Store App 文件选取器
    Windows Store App 访问应用内部文件
    Windows Store App 用户库文件分组
    Windows Store App 获取文件及文件夹列表
    Windows Store App 用户库文件夹操作
    Windows Store App 用户库文件操作
  • 原文地址:https://www.cnblogs.com/nublity/p/9582906.html
Copyright © 2011-2022 走看看