POJ 3449 Geometric Shapes <几何(简单相交判断)>

来源:互联网 发布:mac开机密码 编辑:程序博客网 时间:2024/06/05 15:10

题目

分析:就是给一些多边形,多边形的边不会自交(简单多边形),求它们的相交情况(当某个多边形完全包含于某个多边形,不算相交)。

代码

#include <cstdio>#include <iostream>#include <cmath>#include <vector>#include <string>#include <algorithm>using namespace std;const double EPS=1e-8;struct Point;typedef Point Vector;int dblcmp(double x){    return fabs(x)<EPS?0:(x>0?1:-1);}struct Point{    double x,y;    Point(){}    Point(double xx,double yy):x(xx),y(yy){}    Vector operator -(Point p){        return Vector(x-p.x,y-p.y);    }    Point operator +(Point p){        return Point(x+p.x,y+p.y);    }    double operator ^(Vector v){        return x*v.y-y*v.x;    }};struct Segment{    Point p1,p2;    Segment(){}    Segment(Point pp1,Point pp2):p1(pp1),p2(pp2){}    bool isCross(Segment s){  //线段相交判断,允许端点相交,但不允许延长线相交        return max(p1.x,p2.x)>=min(s.p1.x,s.p2.x)&&                max(p1.y,p2.y)>=min(s.p1.y,s.p2.y)&&                max(s.p1.x,s.p2.x)>=min(p1.x,p2.x)&&                max(s.p1.y,s.p2.y)>=min(p1.y,p2.y)&&                dblcmp((p2-p1)^(s.p1-p1))*dblcmp((p2-p1)^(s.p2-p1))<=0&&                dblcmp((s.p2-s.p1)^(p1-s.p1))*dblcmp((s.p2-s.p1)^(p2-s.p1))<=0;    }};struct Polygon{    char identifier;    vector<Point> p;    vector<Segment> e;    vector<char> interP;    void buildEdge(){        int n=p.size();        for(int i=0;i<n;++i){            e.push_back(Segment(p[i],p[(i+1)%n]));        }    }    bool intersection(Polygon p){        int n1=e.size(),n2=p.e.size();        for(int i=0;i<n1;++i){            for(int j=0;j<n2;++j){                if(e[i].isCross(p.e[j])) return true;            }        }        return false;    }    bool input();    void clear();};vector<Polygon> p;bool compare(const Polygon& p1,const Polygon& p2){    return p1.identifier<p2.identifier;}bool Polygon::input(){    scanf("%c",&identifier);    if(identifier=='-'||identifier=='.'){        getchar();        return false;    }    char polyType[10];    scanf("%s",polyType);    double x0,y0,x1,y1,x2,y2;    if(polyType[0]=='s'){        scanf(" (%lf,%lf) (%lf,%lf)",&x0,&y0,&x2,&y2);        p.push_back(Point(x0,y0));        p.push_back(Point((x0+x2+y2-y0)/2.0,(y0+y2+x0-x2)/2.0));        p.push_back(Point(x2,y2));        p.push_back(Point((x0+x2+y0-y2)/2.0,(y0+y2-x0+x2)/2.0));    }    else if(polyType[0]=='l'){        scanf(" (%lf,%lf) (%lf,%lf)",&x0,&y0,&x1,&y1);        p.push_back(Point(x0,y0));        p.push_back(Point(x1,y1));    }    else if(polyType[0]=='t'){        scanf(" (%lf,%lf) (%lf,%lf) (%lf,%lf)",&x0,&y0,&x1,&y1,&x2,&y2);        p.push_back(Point(x0,y0));        p.push_back(Point(x1,y1));        p.push_back(Point(x2,y2));    }    else if(polyType[0]=='p'){        int n;        scanf(" %d",&n);        for(int i=0;i<n;++i){            scanf(" (%lf,%lf)",&x0,&y0);            p.push_back(Point(x0,y0));        }    }    else if(polyType[0]=='r'){        scanf(" (%lf,%lf) (%lf,%lf) (%lf,%lf)",&x0,&y0,&x1,&y1,&x2,&y2);        p.push_back(Point(x0,y0));        p.push_back(Point(x1,y1));        p.push_back(Point(x2,y2));        p.push_back(Point(x0,y0)+(Point(x2,y2)-Point(x1,y1)));    }    getchar();    buildEdge();    return true;}void Polygon::clear(){    p.clear();    e.clear();    interP.clear();}void output(){    int n=p.size();    for(int i=0;i<n;++i){        int m=p[i].interP.size();        char id=p[i].identifier;        if(!m){            printf("%c has no intersections\n",id);        }        else if(m==1){            printf("%c intersects with %c\n",id,p[i].interP[0]);        }        else if(m==2){            printf("%c intersects with %c and %c\n",id,p[i].interP[0],p[i].interP[1]);        }        else{            printf("%c intersects with ",id);            for(int j=0;j<m-1;++j){                printf("%c, ",p[i].interP[j]);            }            printf("and %c\n",p[i].interP[m-1]);        }    }    putchar('\n');}void solve(){    int n=p.size();    for(int i=0;i<n;++i){        for(int j=i+1;j<n;++j){            if(p[i].intersection(p[j])){                p[i].interP.push_back(p[j].identifier);                p[j].interP.push_back(p[i].identifier);            }        }        sort(p[i].interP.begin(),p[i].interP.end());    }    sort(p.begin(),p.end(),compare);    output();}int main(){    Polygon polygon;    while(polygon.input()){        p.clear();        p.push_back(polygon);        polygon.clear();        while(polygon.input()){            p.push_back(polygon);            polygon.clear();        }        solve();    }    return 0;}