A plurality of convex polygons intersecting area

#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) { / / relationship between point and line segment, the segment 0 is a point, a line segment point for the 
    return SGN (Cross (pv.p1, v.p2-v.p1)) == 0 && SGN (dOT (pv.p1, PV .p2)) <= 0 ; 
} 
Point Cross_Point (Point a, Point B, Point C, Point D) { // two line focus of 
    Double S1 = Cross (BA, the C- a);
     Double S2 = Cross (BA , D- A);
     return Point (CX DX-S2 * S1 *, Dy * CY * S1-S2) / (S1-S2); // must first determined whether the two parallel or coincident 
}
BOOLcross_segment (Point A, Point B, Point C, Point D) {
     Double C1 = Cross (BA, CA), C2 = Cross (BA, D- A);
     Double D1 = Cross (DC, AC), D2 = Cross ( DC, B- C);
     return SGN (C1) * SGN (C2) < 0 && SGN (D1) * SGN (D2) < 0 ; // . 1 intersects disjoint 0 
}
 BOOL Point_in_polygon (Point Pt, Point P *, int n-) { // . 1 inside the polygon represents 0 or outside the boundary 
    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\n");
                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\n",0.5*ans);
    return 0;
}
View Code

 

Guess you like

Origin www.cnblogs.com/xiaolaji/p/11600347.html