POJ 3449 Geometric Shapes

題目

分析:就是給一些多邊形,多邊形的邊不會自交(簡單多邊形),求它們的相交情況(當某個多邊形完全包含於某個多邊形,不算相交)。

代碼

#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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章