POJ 3449 Geometric Shapes

判断两个多边形是否相交,只需判断边是否有相交。

编码量有点大,不过思路挺简单的。

#include<cstdio>
#include<cstring>
#include<vector>
#include<cmath>
#include<string>
#include<queue>
#include<list>
#include<algorithm>
#include<iostream>
using namespace std;

string s;
struct point
{
    double x;
    double y;
    point (double a,double b){x=a;y=b;}
};

struct Sharp
{
    string name;
    vector<point>v;
    vector<string> ans;
}sharp[100];
int tot;

bool cmp(const Sharp&a,const Sharp&b)
{
    return a.name<b.name;
}

void work()
{
    int a,b,c,d,e,f;
    if(s=="square")
    {
        scanf(" (%d,%d)",&a,&b);
        scanf(" (%d,%d)",&c,&d);
        point p1(1.0*a,1.0*b);
        point p2(1.0*(a+b+c-d)/2.0,1.0*(-a+b+c+d)/2.0);
        point p3(1.0*c,1.0*d);
        point p4(1.0*(a-b+c+d)/2.0,1.0*(a+b-c+d)/2.0);
        sharp[tot].v.push_back(p1);
        sharp[tot].v.push_back(p2);
        sharp[tot].v.push_back(p3);
        sharp[tot].v.push_back(p4);
    }
    if(s=="rectangle")
    {
        scanf(" (%d,%d)",&a,&b);
        scanf(" (%d,%d)",&c,&d);
        scanf(" (%d,%d)",&e,&f);
        point p1(1.0*a,1.0*b);
        point p2(1.0*c,1.0*d);
        point p3(1.0*e,1.0*f);
        point p4(p1.x+p3.x-p2.x,p1.y+p3.y-p2.y);
        sharp[tot].v.push_back(p1);
        sharp[tot].v.push_back(p2);
        sharp[tot].v.push_back(p3);
        sharp[tot].v.push_back(p4);
    }
    if(s=="line")
    {
        for(int i=1;i<=2;i++)
        {
            scanf(" (%d,%d)",&a,&b);
            point p(1.0*a,1.0*b);
            sharp[tot].v.push_back(p);
        }
    }
    if(s=="triangle")
    {
        for(int i=1;i<=3;i++)
        {
            scanf(" (%d,%d)",&a,&b);
            point p(1.0*a,1.0*b);
            sharp[tot].v.push_back(p);
        }
    }
    if(s=="polygon")
    {
        int x;
        scanf("%d",&x);
        for(int i=1;i<=x;i++)
        {
            scanf(" (%d,%d)",&a,&b);
            point p(1.0*a,1.0*b);
            sharp[tot].v.push_back(p);
        }
    }
    tot++;
}

const double eps=1e-8;
#define zero(x)(((x)>0?(x):(-x))<eps)

double xmult(point p1,point p2,point p0)
{
    return (p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y);
}

int dots_inline(point p1,point p2,point p3)
{
    return zero(xmult(p1,p2,p3));
}

int same_side(point p1,point p2,point l1,point l2)
{
    return xmult(l1,p1,l2)*xmult(l1,p2,l2)>eps;
}

int dot_online_in(point p,point l1,point l2)
{
    return zero(xmult(p,l1,l2))&&(l1.x-p.x)*(l2.x-p.x)<eps&&(l1.y-p.y)*(l2.y-p.y)<eps;
}

int intersect_in(point u1,point u2,point v1,point v2)
{
    if(!dots_inline(u1,u2,v1)||!dots_inline(u1,u2,v2)) return !same_side(u1,u2,v1,v2)&&!same_side(v1,v2,u1,u2);
    return dot_online_in(u1,v1,v2)||dot_online_in(u2,v1,v2)||dot_online_in(v1,u1,u2)||dot_online_in(v2,u1,u2);
}

bool judge(int a,int b)
{
    for(int i=0;i<sharp[a].v.size();i++)
    {
        for(int j=0;j<sharp[b].v.size();j++)
        {
            point p1=sharp[a].v[i];
            point p2=sharp[a].v[(i+1)%sharp[a].v.size()];
            point p3=sharp[b].v[j];
            point p4=sharp[b].v[(j+1)%sharp[b].v.size()];

            if(intersect_in(p1,p2,p3,p4)) return 1;
        }
    }
    return 0;
}

void init()
{
    tot=0;
    for(int i=0;i<100;i++)
    {
        sharp[i].ans.clear();
        sharp[i].v.clear();
    }
}
int main()
{
    while(1)
    {
        cin>>s;
        if(s==".") break;

        init();

        sharp[tot].name=s;
        cin>>s; work();

        while(1)
        {
            cin>>s;
            if(s=="-") break;

            sharp[tot].name=s;
            cin>>s; work();
        }

        sort(sharp,sharp+tot,cmp);

        for(int i=0;i<tot;i++)
        {
            for(int j=i+1;j<tot;j++)
            {
                if(judge(i,j))
                {
                    sharp[i].ans.push_back(sharp[j].name);
                    sharp[j].ans.push_back(sharp[i].name);
                }
            }
        }

        for(int i=0;i<tot;i++)
        {
            cout<<sharp[i].name<<" ";
            if(sharp[i].ans.size()==0) printf("has no intersections\n");
            else if(sharp[i].ans.size()==1) cout<<"intersects with "<<sharp[i].ans[0]<<endl;
            else if(sharp[i].ans.size()==2) cout<<"intersects with "<<sharp[i].ans[0]<<" and "<<sharp[i].ans[1]<<endl;
            else
            {
                printf("intersects with");
                for(int k=0;k<sharp[i].ans.size();k++)
                {
                    if(k<sharp[i].ans.size()-1) cout<<" "<<sharp[i].ans[k]<<",";
                    else cout<<" and "<<sharp[i].ans[k]<<endl;
                }
            }
        }
        printf("\n");
    }
    return 0;
}

 

posted @ 2016-01-24 14:08  Fighting_Heart  阅读(152)  评论(0编辑  收藏  举报