您的位置:首页 > 其它

POJ 3449 Geometric Shapes(判断多边形相交情况)

2014-09-27 15:05 417 查看
POJ 3449 Geometric Shapes(判断多边形相交情况)
http://poj.org/problem?id=3449
题意:

给你n个多边形,这些多边形包括线段,三角形,矩形,正方形,和其他多边形. 然后要你输出他们之间相交的情况. 且多边形自己的边不会相交,且三角形不会退化成线段.

分析:


本题不难,但是需要注意程序实现的各种细节才行.


当给你矩形时,你得到的是(x1,y1) (x2,y2) 和(x3,y3)3个点.你需要求出(x4,y4). 分析可得(x4,y4)=(x3+x1-x2,y3+y1-y2).

当给你正方形时,你得到的是对角线的端点(x1,y1)和(x3,y3).你需要计算出(x2,y2)和(x4,y4).



接下来就两两判断是否相交即可.判断两个图形是否相交,只需要判断他们中的任意两条边是否有交点即可(线段相交判定).

AC代码:

</pre><pre name="code" class="cpp">#include<cstdio>
#include<algorithm>
#include<cstring>
#include<vector>
#include<cmath>
using namespace std;
const int maxn=30+5;
const double eps=1e-10;
int dcmp(double x)
{
    if(fabs(x)<eps) return 0;
    return x<0?-1:1;
}
struct Point
{
    double x,y;
    Point(){}
    Point(double x,double y):x(x),y(y){}
};
typedef Point Vector;
Vector operator-(Point A,Point B)
{
    return Vector(A.x-B.x,A.y-B.y);
}
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 InSegment(Point P,Point a1,Point a2)
{
    return dcmp(Cross(a1-P,a2-P))==0 && dcmp(Dot(a1-P,a2-P))<=0;
}
bool SegmentIntersection(Point a1,Point a2,Point b1,Point b2)
{
    double c1=Cross(a2-a1,b1-a1),c2=Cross(a2-a1,b2-a1);
    double c3=Cross(b2-b1,a1-b1),c4=Cross(b2-b1,a2-b1);
    if(dcmp(c1)*dcmp(c2)<0 && dcmp(c3)*dcmp(c4)<0) return true;
    if(dcmp(c1)==0 && InSegment(b1,a1,a2) ) return true;
    if(dcmp(c2)==0 && InSegment(b2,a1,a2) ) return true;
    if(dcmp(c3)==0 && InSegment(a1,b1,b2) ) return true;
    if(dcmp(c4)==0 && InSegment(a2,b1,b2) ) return true;
    return false;
}
/***以上为刘汝佳模板***/

struct Graph
{
    char type;    //该图形的字母标记
    int n;        //点数
    Point p[maxn];//图形的每个顶点
    bool operator<(const Graph &rhs)const
    {
        return type<rhs.type;
    }
}G[maxn];

int main()
{
    while(scanf(" %c",&G[0].type)==1 && G[0].type!='.')
    {
        int n=0;//图形个数
        while(G
.type!='-')
        {
            char str[100];
            scanf("%s",str);
            if(str[0]=='l')
            {
                for(int i=0;i<2;++i)
                    scanf(" (%lf,%lf)",&G
.p[i].x,&G
.p[i].y);
                G
.p[2]=G
.p[0];
                G
.n=2;
                ++n;
            }
            else if(str[0]=='t')
            {
                for(int i=0;i<3;++i)
                    scanf(" (%lf,%lf)",&G
.p[i].x,&G
.p[i].y);
                G
.p[3]=G
.p[0];
                G
.n=3;
                ++n;
            }
            else if(str[0]=='r')
            {
                for(int i=0;i<3;++i)
                    scanf(" (%lf,%lf)",&G
.p[i].x,&G
.p[i].y);
                G
.p[3].x= G
.p[0].x+G
.p[2].x-G
.p[1].x;
                G
.p[3].y= G
.p[0].y+G
.p[2].y-G
.p[1].y;
                G
.p[4]=G
.p[0];
                G
.n=4;
                ++n;
            }
            else if(str[0]=='s')
            {
                for(int i=0;i<3;i+=2)//注意i+=2
                    scanf(" (%lf,%lf)",&G
.p[i].x,&G
.p[i].y);
                G
.p[1].x = (G
.p[0].x+G
.p[2].x-G
.p[2].y+G
.p[0].y)/2  ;
                G
.p[1].y = (-G
.p[0].x+G
.p[2].x+G
.p[2].y+G
.p[0].y)/2 ;
                G
.p[3].x = (G
.p[0].x+G
.p[2].x+G
.p[2].y-G
.p[0].y)/2 ;
                G
.p[3].y = ( G
.p[0].x-G
.p[2].x+G
.p[2].y+G
.p[0].y)/2 ;
                G
.p[4]=G
.p[0];
                G
.n=4;
                ++n;
            }
            else if(str[0]=='p')
            {
                scanf("%d",&G
.n);
                for(int i=0;i<G
.n;++i)//错误1,这里i<n
                    scanf(" (%lf,%lf)",&G
.p[i].x,&G
.p[i].y);
                G
.p[G
.n]=G
.p[0];//错误2,漏写了这句且G
.p[G
.n]写成了G
.p

                ++n;
            }

            scanf(" %c",&G
.type);
        }
        sort(G,G+n);
        vector<int> vc[maxn];//vc[i]记录第i个多边形与哪几个多边形相交
        for(int i=0;i<n;++i)
        for(int j=i+1;j<n;++j)
        {
            for(int k=0;k<G[i].n;++k)
            {
                int h;
                for(h=0;h<G[j].n;++h)
                {
                    if(SegmentIntersection(G[i].p[k],G[i].p[k+1], G[j].p[h],G[j].p[h+1] ) )
                    {
                        vc[i].push_back(j),vc[j].push_back(i);
                        break;
                    }
                }
                if(h<G[j].n) break;
            }
        }

        //打印结果
        for(int i=0;i<n;++i)
        {
            if(vc[i].size()==0)
                printf("%c has no intersections\n",G[i].type);
            else if(vc[i].size()==1)
                printf("%c intersects with %c\n",G[i].type,G[vc[i][0]].type);
            else if(vc[i].size()==2)
                printf("%c intersects with %c and %c\n",G[i].type,G[vc[i][0]].type,G[vc[i][1]].type);
            else
            {
                printf("%c intersects with ",G[i].type);
                for(int j=0;j<vc[i].size()-1;++j)
                    printf("%c, ",G[vc[i][j]].type);
                printf("and %c\n",G[vc[i][vc[i].size()-1]].type );
            }
        }
        printf("\n");
    }
    return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: