• 多个凸多边形相交面积


    #include <bits/stdc++.h>
    using namespace std;
    const long double eps=1e-8;
    const double pi=acos(-1.0);
    int sgn(double x) {
        if(fabs(x)<eps)
            return 0;
        return x<0?-1:1;
    }
    int dcmp(double x,double y) {
        if(fabs(x-y)<eps)
            return 0;
        return x<y?-1:1;
    }
    struct Point {
        double x,y;
        Point() {};
        Point(double x,double y):x(x),y(y) {}
        Point operator + (Point b) {
            return Point(x+b.x,y+b.y);
        }
        Point operator -(Point b) {
            return Point(x-b.x,y-b.y);
        }
        Point operator *(double k) {
            return Point(x*k,y*k);
        }
        Point operator /(double k) {
            return Point(x/k,y/k);
        }
        bool operator ==(Point b) {
            return sgn(x-b.x)==0&&sgn(y-b.y)==0;
        }
        bool operator <(Point b) {
            return sgn(x-b.x)<0||(sgn(x-b.x)==0&&sgn(y-b.y)<0);
        }
    } now[1000],nex[1000],over[1000],res[1000];
    typedef Point Vector;
    double dot(Vector A,Vector B) { //点积
        return A.x*B.x+A.y*B.y;
    }
    double Cross(Vector a,Vector b) { //叉积
        return a.x*b.y-a.y*b.x;
    }
    bool cmp(Point r,Point t) { //极角排序
        Point tt=t-res[0];
        Point rr=r-res[0];
        if(sgn(Cross(rr,tt))==0)
            return (rr.x*rr.x+rr.y*rr.y)<(tt.x*tt.x+tt.y*tt.y);
        return sgn(Cross(rr,tt))>0;
    }
    struct Line {
        Point p1,p2;
        Line() {};
        Line(Point p1,Point p2):p1(p1),p2(p2) {}
    };
    typedef Line segment;
    bool Point_on_seg(Point p,Line v) { //点和线段的关系,0为点在线段上,1为点在线段上
        return sgn(Cross(p-v.p1,v.p2-v.p1))==0&&sgn(dot(p-v.p1,p-v.p2))<=0;
    }
    Point Cross_Point(Point a,Point b,Point c,Point d) { //两条直线的焦点
        double s1=Cross(b-a,c-a);
        double s2=Cross(b-a,d-a);
        return Point(c.x*s2-d.x*s1,c.y*s2-d.y*s1)/(s2-s1);//先要判断两条是否平行或者重合
    }
    bool cross_segment(Point a,Point b,Point c,Point d) {
        double c1=Cross(b-a,c-a),c2=Cross(b-a,d-a);
        double d1=Cross(d-c,a-c),d2=Cross(d-c,b-c);
        return sgn(c1)*sgn(c2)<0&&sgn(d1)*sgn(d2)<0;//1相交,0不相交
    }
    bool Point_in_polygon(Point pt,Point *p,int n) {//1在多边形内部或者边界 0表示在外面
        for(int i=0; i<n; i++) {
            if(p[i]==pt)
                return 1;
        }
        for(int i=0; i<n; i++) {
            Line v=Line(p[i],p[(i+1)%n]);
            if(Point_on_seg(pt,v))
                return 1;
        }
        int num=0;
        for(int i=0; i<n; i++) {
            int j=(i+1)%n;
            int c=sgn(Cross(pt-p[j],p[i]-p[j]));
            int u=sgn(p[i].y-pt.y);
            int v=sgn(p[j].y-pt.y);
            if(c>0&&u<0&&v>=0)
                num++;
            if(c<0&&u>=0&&v<0)
                num--;
        }
        return num!=0;
    }
    int main() {
       // freopen("in.txt","r",stdin);
        int t;
        scanf("%d",&t);
        int lenow;
        for(int i=1; i<=t; i++) {
            int n;
            scanf("%d",&n);
            for(int j=0; j<n; j++) {
                scanf("%lf%lf",&nex[j].x,&nex[j].y);
            }
           // res[0]=nex[0];
            //sort(nex,nex+n,cmp);
            if(i==1) {
                for(int j=0; j<n; j++) {
                    now[j]=nex[j];
                }
                lenow=n;
            } else {
                int cnt=0;
                for(int j=0; j<lenow; j++) {
                    for(int w=0; w<n; w++) {
                        if(cross_segment(now[j],now[(j+1)%lenow],nex[w],nex[(w+1)%n])) {
                            over[cnt++]=Cross_Point(now[j],now[(j+1)%lenow],nex[w],nex[(w+1)%n]);
                            //cout<<now[j].x<<" "<<now[j].y<<" "<<now[(j+1)%lenow].x<<" "<<now[(j+1)%lenow].y<<" ";
                           // cout<<nex[w].x<<" "<<nex[w].y<<" "<<nex[(w+1)%n].x<<" "<<nex[(w+1)%n].y<<" "<<over[cnt-1].x<<" "<<over[cnt-1].y<<" "<<endl;
                        }
                    }
                }
                int tot=0;
                for(int j=0; j<lenow; j++) {
                    if(Point_in_polygon(now[j],nex,n)&&Point_in_polygon(now[j],now,lenow)) {
                        //cout<<"*"<<now[j].x<<" "<<now[j].y<<endl;
                        res[tot++]=now[j];
                    }
                }
                for(int j=0; j<n; j++) {
                    if(Point_in_polygon(nex[j],nex,n)&&Point_in_polygon(nex[j],now,lenow)) {
                        // cout<<"**"<<nex[j].x<<" "<<nex[j].y<<endl;
                        res[tot++]=nex[j];
                    }
                }
                for(int j=0; j<cnt; j++) {
                    if(Point_in_polygon(over[j],nex,n)&&Point_in_polygon(over[j],now,lenow)) {
                        // cout<<"***"<<over[j].x<<" "<<over[j].y<<endl;
                        res[tot++]=over[j];
                    }
                }
                if(tot<=2) {
                    printf("0.000
    ");
                    return 0;  
                } else {
                    sort(res+1,res+tot,cmp);
                    for(int j=0; j<tot; j++) {
                        now[j]=res[j];
                        //cout<<now[j].x<<" "<<now[j].y<<endl;
                    }
                    lenow=tot;
                }
            }
    
            // scanf("%d",)
        }
        double ans=0;
        for(int i=0; i<lenow; i++) {
            //cout<<now[i].x<<" "<<now[i].y<<" "<<ans<<endl;
            ans+=Cross(now[i],now[(i+1)%lenow]);
        }
        printf("%.3f
    ",0.5*ans);
        return 0;
    }
    View Code
  • 相关阅读:
    ZOJ 3609 Modular Inverse (水题)
    ZOJ 3607 Lazier Salesgirl (贪心)
    POJ 1730 Perfect Pth Powers (枚举||分解质因子)
    POJ 2262 Goldbach's Conjecture (素数判断)
    LA 3135 Argus (优先队列)
    uva 11991 (map vector 嵌套)
    hdu 1022 Train Problem I(stack)
    poj 1837 blance (01背包)
    hdu 1242 rescue (优先队列 bfs)
    hdu 3033 I love sneakers!(分组背包)
  • 原文地址:https://www.cnblogs.com/xiaolaji/p/11600347.html
Copyright © 2020-2023  润新知