zoukankan      html  css  js  c++  java
  • HDU 3060 多边形面积并

    Area2

    Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 1197    Accepted Submission(s): 278


    Problem Description
    小白近期又被空军特招为飞行员,參与一项实战演习。演习的内容还是轰炸某个岛屿(这次的岛屿非常大,非常大非常大非常大,大到炸弹怎么扔都能全然在岛屿上引爆),看来小白确实是飞行员的命。。。
    这一次,小白扔的炸弹比較奇怪,爆炸的覆盖区域不是圆形,而是一个不规则的简单多边形,请你再次帮助小白,计算出炸到了多少面积。
    须要注意的是,这次小白一共扔了两枚炸弹,可是两枚炸弹炸到的公共部分的面积仅仅能计算一次。
     

    Input
    首先输入两个数n,m,分别代表两枚炸弹爆炸覆盖到的图形的顶点数;
    接着输入n行,每行输入一个(x,y)坐标,代表第一枚炸弹爆炸范围图形的顶点(按顺势针或者逆时针给出)。
    最后输入m行,每行输入一个(x',y')坐标,代表第二枚炸弹爆炸范围图形的顶点(按顺势针或者逆时针给出)。
    (3<= n,m <= 500)
     

    Output
    输出一个两位小数,表示实际轰炸到的岛屿的面积。
     

    Sample Input
    4 4 0 0 0 1 1 1 1 0 0.5 0.5 0.5 1.5 1.5 1.5 1.5 0.5
     

    Sample Output
    1.75


    给定两个多边形,求面积并

    把多边形分解成三角形,然后计算三角形的有向面积交。

    代码:

    /* ***********************************************
    Author :_rabbit
    Created Time :2014/5/4 15:03:55
    File Name :20.cpp
    ************************************************ */
    #pragma comment(linker, "/STACK:102400000,102400000")
    #include <stdio.h>
    #include <iostream>
    #include <algorithm>
    #include <sstream>
    #include <stdlib.h>
    #include <string.h>
    #include <limits.h>
    #include <string>
    #include <time.h>
    #include <math.h>
    #include <queue>
    #include <stack>
    #include <set>
    #include <map>
    using namespace std;
    #define INF 10000000
    #define eps 1e-8
    #define pi acos(-1.0)
    typedef long long ll;
    int dcmp(double x){  
        if(fabs(x)<eps)return 0;  
        return x>0?1:-1;  
    }  
    struct Point{  
        double x,y;  
        Point(double _x=0,double _y=0){  
            x=_x;y=_y;  
        }  
    };  
    Point operator + (const Point &a,const Point &b){  
        return Point(a.x+b.x,a.y+b.y);  
    }  
    Point operator - (const Point &a,const Point &b){  
        return Point(a.x-b.x,a.y-b.y);  
    }  
    Point operator * (const Point &a,const double &p){  
        return Point(a.x*p,a.y*p);  
    }  
    Point operator / (const Point &a,const double &p){  
        return Point(a.x/p,a.y/p);  
    }  
    bool operator < (const Point &a,const Point &b){  
        return a.x<b.x||(a.x==b.x&&a.y<b.y);  
    }  
    bool operator == (const Point &a,const Point &b){  
        return dcmp(a.x-b.x)==0&&dcmp(a.y-b.y)==0;  
    }  
    double Dot(Point  a,Point b){  
        return a.x*b.x+a.y*b.y;  
    }  
    double Length(Point a){  
        return sqrt(Dot(a,a));  
    }  
    double Angle(Point a,Point b){  
        return acos(Dot(a,b)/Length(a)/Length(b));  
    }  
    double angle(Point a){  
        return atan2(a.y,a.x);  
    }  
    double Cross(Point a,Point b){  
        return a.x*b.y-a.y*b.x;  
    }  
    Point vecunit(Point a){  
        return a/Length(a);  
    }  
    Point Normal(Point a){  
        return Point(-a.y,a.x)/Length(a);  
    }  
    Point Rotate(Point a,double rad){  
        return Point(a.x*cos(rad)-a.y*sin(rad),a.x*sin(rad)+a.y*cos(rad));  
    }  
    double Area2(Point a,Point b,Point c){  
        return Length(Cross(b-a,c-a));  
    }  
    struct Line{  
        Point p,v;  
        double ang;  
        Line(){};  
        Line(Point p,Point v):p(p),v(v){  
            ang=atan2(v.y,v.x);  
        }  
        bool operator < (const Line &L) const {  
            return ang<L.ang;  
        }  
    };  
    bool OnLeft(const Line &L,const Point &p){  
        return dcmp(Cross(L.v,p-L.p))>=0;  
    }  
    Point GetLineIntersection(Point p,Point v,Point q,Point w){  
        Point u=p-q;  
        double t=Cross(w,u)/Cross(v,w);  
        return p+v*t;  
    }  
    Point GetLineIntersection(Line a,Line b){  
        return GetLineIntersection(a.p,a.v,b.p,b.v);  
    }  
    vector<Point> HPI(vector<Line> L){  
        int n=L.size();  
        sort(L.begin(),L.end());//将全部半平面依照极角排序。  
        int first,last;  
        vector<Point> p(n);  
        vector<Line> q(n);  
        vector<Point> ans;  
        q[first=last=0]=L[0];  
        for(int i=1;i<n;i++){  
            while(first<last&&!OnLeft(L[i],p[last-1]))last--;//删除顶部的半平面  
            while(first<last&&!OnLeft(L[i],p[first]))first++;//删除底部的半平面  
            q[++last]=L[i];//将当前的半平面假如双端队列顶部。  
            if(fabs(Cross(q[last].v,q[last-1].v))<eps){//对于极角同样的,选择性保留一个。  
                last--;  
                if(OnLeft(q[last],L[i].p))q[last]=L[i];  
            }  
            if(first<last)p[last-1]=GetLineIntersection(q[last-1],q[last]);//计算队列顶部半平面交点。  
        }  
        while(first<last&&!OnLeft(q[first],p[last-1]))last--;//删除队列顶部的无用半平面。  
        //cout<<first<<" "<<last<<endl;
        if(last-first<=1)return ans;//半平面退化  
        p[last]=GetLineIntersection(q[last],q[first]);//计算队列顶部与首部的交点。  
        for(int i=first;i<=last;i++)ans.push_back(p[i]);//将队列中的点复制。  
        return ans;  
    }  
    double PolyArea(vector<Point> p){  
        int n=p.size();  
        double ans=0;  
        for(int i=1;i<n-1;i++)  
            ans+=Cross(p[i]-p[0],p[i+1]-p[0]);  
        return ans/2;  
    }  
    vector<Point> p1,p2;
    int main()
    {
         //freopen("data.in","r",stdin);
         //freopen("data.out","w",stdout);
         int n,m;
         while(~scanf("%d%d",&n,&m)){
             Point pp;
    		 p1.clear();p2.clear();
             for(int i=0;i<n;i++)scanf("%lf%lf",&pp.x,&pp.y),p1.push_back(pp);
             for(int i=0;i<m;i++)scanf("%lf%lf",&pp.x,&pp.y),p2.push_back(pp);
             double ret1,ret2,ret=0;
             ret1=PolyArea(p1);if(dcmp(ret1)<0)reverse(p1.begin(),p1.end());ret+=fabs(ret1);
             ret2=PolyArea(p2);if(dcmp(ret2)<0)reverse(p2.begin(),p2.end());ret+=fabs(ret2);
             for(int i=1;i<n-1;i++)
                 for(int j=1;j<m-1;j++){
                     vector<Point> s1,s2;
                     s1.push_back(p1[0]);
                     s1.push_back(p1[i]);
                     s1.push_back(p1[i+1]);
                     s2.push_back(p2[0]);
                     s2.push_back(p2[j]);
                     s2.push_back(p2[j+1]);
                     double r1,r2;
                     int flag1,flag2;
                     r1=PolyArea(s1);
                     if(dcmp(r1)>=0)flag1=1;else flag1=0;
                     if(dcmp(r1)<0)reverse(s1.begin(),s1.end());
                     r2=PolyArea(s2);
                     if(dcmp(r2)>=0)flag2=1;else flag2=0;
                     if(dcmp(r2)<0)reverse(s2.begin(),s2.end());
                     vector<Line> L;
                     for(int k=0;k<3;k++)
                         L.push_back(Line(s1[k],s1[(k+1)%3]-s1[k]));
                     for(int k=0;k<3;k++)
                         L.push_back(Line(s2[k],s2[(k+1)%3]-s2[k]));
                     vector<Point> tt=HPI(L);
                     if(flag1==flag2)ret-=PolyArea(tt);
                     else ret+=PolyArea(tt);
                 }
             printf("%.2lf
    ",ret);
         }
         return 0;
    }
    
    



  • 相关阅读:
    项目的搭建步骤:
    MySQL复习笔记记录
    记录搭建SSM框架中常用到的功能:(监听器)、过滤器和拦截器 以及相关的拓展内容的学习记录
    为什么要配置spring**.xml或者applicationContext.xml --学习笔记
    java8 Lambda表达式学习笔记
    java多线程高并发学习从零开始——初识volatile关键字
    java多线程高并发学习从零开始——新建线程
    JVM工作机制以及异常处理之内存溢出OOM(OutOfMemoryError)/SOF(StackOverflowError)--Java学习记录2——更新中
    记录使用idea构建出现错误:failed to execute goal org.apache.maven.plugins:maven-javadoc-plugin:2.9.1:jar——Java学习记录3
    Oracle创建用户和表空间的步骤 和 导入dmp文件的方法 —— 数据库学习
  • 原文地址:https://www.cnblogs.com/hrhguanli/p/3911173.html
Copyright © 2011-2022 走看看