多边形是否重叠

    题目:多边形是否重叠(有可能是凹多边形,有点重叠了就算。pku acm 3082题目)。 可以分为几种情况: 点点是否重叠  点是否在线上  点是否在在多边形内部,最后一个是关键。        

判断点P是否在多边形中是计算几何中一个非常基本但是十分重要的算法。以点P为端点,向左方作射线L,由于多边形是有界的,所以射线L的左端一定在多边形外,考虑沿着L从无穷远处开始自左向右移动,遇到和多边形的第一个交点的时候,进入到了多边形的内部,遇到第二个交点的时候,离开了多边形,……所以很容易看出当L和多边形的交点数目C是奇数的时候,P在多边形内,是偶数的话P在多边形外。
为了统一起见,在计算射线L和多边形的交点的时候,1。对于多边形的水平边不作考虑;2。对于多边形的顶点和L相交的情况,如果该顶点是其所属的边上纵坐标较大的顶点,则计数,否则忽略;3。对于P在多边形边上的情形,直接可判断P属于多边行。

题目:

'Roid Rage
Time Limit:1000MS  Memory Limit:65536K
Total Submit:177 Accepted:52

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:

 

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

 

Sample Output

 

Source
2006 South Central USA Regional Programming Contest

Source

Problem Id:3082  User Id:bmexue
Memory:72K  Time:0MS
Language:C++  Result:Accepted

  • Source

     

     

    #include <iostream>
    using namespace std;
    int m;
    struct Point
    {
    	int x,y;
    };
    Point d[10][21];
    bool one_two(int a, int b , int t) //ok
    {
    	if(t>=a && t<=b)
    		return true;
    	if(t<=a && t>=b)
    		return true;
    	return false;
    }
    bool one_two(double a, double b , double t)  //ok
    {
    	if(t>=a && t<=b)
    		return true;
    	if(t<=a && t>=b)
    		return true;
    	return false;
    }
    bool p_line(Point a, Point b, Point t)
    {
    	if(b.x == a.x){   //水平线
    		if( t.x == a.x && one_two(a.y,b.y,t.y))
    			return true;
    		return false;
    	}
    	else if(b.y == a.y){   //垂直边
    		if( t.y == a.y && one_two(a.x,b.x,t.x))
    			return true;
    		return false;
    	}
    	else{    //斜边
    		if( (b.x-t.x == 0) || (a.x-t.x ==0) )
    			return false;
    		if(  (double)(b.y-t.y)/(double)(b.x-t.x) ==  (double)(a.y-t.y)/(double)(a.x-t.x) && one_two(a.y,b.y,t.y))
    			return true;
    	}
    	return false;
    }
    bool p_p(Point a, Point b)  //点点
    {
    	if(a.x==b.x && a.y==b.y)
    		return true;
    	return false;
    }
    int min(int a, int b)
    {
    	if(a<b) return a;
    	return b;
    }
    int max(int a, int b)
    {
    	if(a>b)
    		return a;
    	return b;
    }
    bool dline_line(int y0, int x0, Point a, Point b)
    {   
    	if(a.y == b.y)   //水平边  不考虑
    		return false;
    	if(y0 <= min(a.y,b.y)) // 相交在纵坐标低的不算
    		return false;
    	if( y0 > max(a.y,b.y))  //不在带状区域
    		return false;
    	if(x0>=max(a.x,b.x)) //射线源在边的右边,可以不考虑
    		return false;
    	if(a.x == b.x){  // 垂直边
            if( one_two(a.y,b.y,y0) && a.x > x0){  //向右边发射现可以相交 
    			return true;
    		}
    	    return false;
    	}
        //斜边:
    	double tmp_x = (double)(y0-a.y)*(double)(b.x-a.x)/(double)(b.y-a.y) + (double)a.x;
    	if(tmp_x < (double)x0) //相交在x0的左边了
    		return false;
    	if(one_two( (double)a.x,(double)b.x,tmp_x))
    		return true;
    	return false;
    }
    bool polygon_polygon(int i, int j)
    {
    	int v1 = d[i][0].x;
    	int v2 = d[j][0].x;
    	int a,b;
        for(a=1; a<=v1;a++){   //p_p
    		for(b=1;b<=v2;b++){
    			if(p_p( d[i][a], d[j][b]))
    				return true;
    		}
    	}
        for(a=1; a<=v1;a++){  //p_line
    		for(b=1;b<v2;b++){
    			if(p_line(d[j][b],d[j][b+1], d[i][a]) )
    				return true;
    		}
    		if( p_line(d[j][1],d[j][v2], d[i][a]) )
    			return true;
    	}
    	for(b=1; b<=v2;b++){   // p_line   b=1 a=2
    		for(a=1;a<v1;a++){
    			if(p_line(d[i][a],d[i][a+1], d[j][b]) )
    				return true;
    		}
    	    if( p_line(d[i][1],d[i][v1], d[j][b]) )//b==3 a==3  xxxxxxxxxx
    			return true;
    	}
        //i 的点在j内?
        int num;
    	for(a=1;a<=v1;a++){
    		num=0;
    		for(b=1;b<v2;b++){
    		   if(dline_line(d[i][a].y,d[i][a].x ,   d[j][b],d[j][b+1]) )
    			   num++;
    		}
            if(dline_line(  d[i][a].y,d[i][a].x ,   d[j][1],d[j][v2]))
    			   num++;
    		if(num%2 !=0)   //奇数个交点就在内部
    			return true;
    	}
    	//j的点在i内
        for(b=1;b<=v2;b++){
    		num=0;
    		for(a=1;a<v1;a++){
    		   if(dline_line(d[j][b].y, d[j][b].x,    d[i][a],d[i][a+1]) )
    			   num++;
    		}
      	    if(dline_line(d[j][b].y,d[j][b].x,d[i][1],d[i][v1]) )
    			   num++;
    		if(num%2 !=0)
    			return true;
    	}
    
    	return false;
    	
    }
    void work(int ii)
    {
    	printf("Data Set #%d/n",ii);
    	int fir =0;
    	for(int i=0; i<m;i++){
    		for(int j=i+1; j<m;j++){
    		     if	(polygon_polygon(i,j) ){
    				 printf("%d %d/n",i+1,j+1);fir++;
    			 }
    		}
    	}
    	if(fir==0)
    		printf("no collisions/n");
    }
    int main()
    {
    	int n,p,v,i;
    	char c='d';
    	scanf("%d",&n);
    	int ii=1;
    	while(ii<=n){
    		scanf("%d",&m);   //num
    		i=0;  
    		while(i<m){   //m line
    			scanf("%d",&v);  d[i][0].x =v; p=1;
    		    while(p<=v){
    			   scanf("%d%c%d",&d[i][p].x,&c,&d[i][p].y); 
    			   p++;
    			} 
    			i++;
    		}
    		work(ii);
            ii++;
    	}
    	return 0;
    }
    

 

 

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

 

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

 

  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.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值