多边形相交poj3082

Language:
'Roid Rage
Time Limit: 1000MS Memory Limit: 65536K
Total Submissions: 922 Accepted: 284

Description

When writing game programs, it is often useful to determine when two polygons intersect one another. This is especially useful in arcade games like   Asteroids  where one polygon could represent a spaceship while another represents a huge, unyielding chunk of space rock.  

Write a program that can determine which polygons of a given set intersect one another.

Input

Input to this problem will begin with a line containing a single integer n indicating the number of datasets. Each data set consists of the following components:
  1. A line containing a single positive integer m (1 <= m <= 10) indicating the number of polygons to analyze.
  2. m lines, each representing a single polygon, with the first line describing polygon 1, the second line describing polygon 2, and so on. Each line begins with a single positive integer v (3 <= v <= 20) indicating the number of vertices describing this polygon. This is followed by v (x,y) coordinate pairs (0 <= x, y <= 100), each of which is a vertex of this polygon. The vertices are connected by edges in the order listed with the last vertex connected back to the first by a final edge. All polygons are "simple"; they do not self-intersect.

Output

For each dataset in the input, output the heading "Data Set #z", where z is 1 for the first dataset, 2 for the second, etc. If this data set contained no intersecting polygons, output the message "no collisions" on its own line. Otherwise, output the list of all pairs of intersecting polygons, one pair per line, each pair formatted with the lowest-numbered polygon first. Output the polygon pairs in ascending order, sorting first by the lowest-numbered polygon in the set and then the second.  

Note: The definition of "intersecting" for the purpose of this problem means that two polygons either share an interior region (i.e., they overlap), or they share boundary points (i.e., they touch at a point or along an edge).

Sample Input

2
2
4 0,0 1,0 1,1 0,1
4 2,2 3,2 3,3 2,3
4
3 2,1 1,2 2,3
3 2,1 3,2 2,3
5 2,0 4,2 2,4 5,4 5,0
4 3,3 1,3 1,5 3,5

Sample Output

Data Set #1
no collisions
Data Set #2
1 2
1 4
2 4
3 4

计算几何真是恶心

#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<vector>
#include<cmath>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<algorithm>
using namespace std;
const int maxn=50;
const double eps=1e-10;
int N;
bool vis[maxn][maxn];
struct Point
{
    double x,y;
    Point(double x=0,double y=0):x(x),y(y){}
};
pair<int,int> ans[maxn];
struct node
{
    int num;
    Point p[maxn];
}polygon[maxn];
int dcmp(double x)
{
    if(fabs(x)<eps)return 0;
    return x<0?-1:1;
}
Point operator - (Point A,Point B)
{
    return Point(A.x-B.x,A.y-B.y);
}
bool operator == (const Point &a,const Point &b)
{
    return dcmp(a.x-b.x)==0&&dcmp(a.y-b.y)==0;
}
double Cross(Point A,Point B)
{
    return A.x*B.y-A.y*B.x;
}
double Dot(Point A,Point B){return A.x*B.x+A.y*B.y;}
bool isPointOnSegment(Point p,Point a1,Point a2)
{
    return dcmp(Cross(a1-p,a2-p))==0&&dcmp(Dot(a1-p,a2-p))<0;
}
int isPointInPolygon(Point p,node poly,int a,int b)
{
    int wn=0;
    int n=poly.num;
    for(int i=0;i<n;i++)
    {
        if(p==poly.p[i])return 1;
        if(isPointOnSegment(p,poly.p[i],poly.p[(i+1)%n]))
        {
            return 1;
        }
        int k=dcmp(Cross(poly.p[(i+1)%n]-poly.p[i],p-poly.p[i]));
        int d1=dcmp(poly.p[i].y-p.y);
        int d2=dcmp(poly.p[(i+1)%n].y-p.y);
        if(k>0&&d1<=0&&d2>0)wn++;
        if(k<0&&d2<=0&&d1>0)wn--;
    }
    if(wn!=0)return 1;
    return 0;
}
int main()
{
    int T,cas=1;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d",&N);
        for(int i=0;i<N;i++)
        {
            int num;
            scanf("%d",&polygon[i].num);
            for(int j=0;j<polygon[i].num;j++)
            {
                scanf("%lf,%lf",&polygon[i].p[j].x,&polygon[i].p[j].y);
            }
        }
        printf("Data Set #%d\n",cas++);
        memset(vis,0,sizeof(vis));
        bool flag=false;
        int cnt=0;
        for(int i=0;i<N;i++)
        {
            for(int j=0;j<polygon[i].num;j++)
            {
                bool flag1=false;
                for(int k=0;k<N;k++)
                {
                    if(k==i||vis[i][k]||vis[k][i])continue;
                    if(isPointInPolygon(polygon[i].p[j],polygon[k],i,k))
                     {
                         vis[i][k]=vis[k][i]=1;
                         ans[cnt++]=make_pair(min(i,k),max(i,k));
                         flag=true;
                         flag1=true;
                     }
                }
            }
        }
        if(!flag)printf("no collisions\n");
        else
        {
            sort(ans,ans+cnt);
            for(int i=0;i<cnt;i++)
                printf("%d %d\n",ans[i].first+1,1+ans[i].second);
        }
    }
    return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值