现在的位置: 首页 > 综合 > 正文

zju1081 判断点是否在简单多边型内(包括凹的情况)

2013年12月02日 ⁄ 综合 ⁄ 共 1765字 ⁄ 字号 评论关闭

题目:顺序输入一系列n个点,输入m个测试点,如果点在形内,那么输出Within,否则输出Outside;

算法:采用环顾法(汝亮书上的P381),用差积(测试点p和 多边形同向相邻两个顶点的差积 m),如果m> 0,就对求出来的夹角+,否则-(m==0,考虑p在线段上就跳出返回Within , 否则不在线段上,那么就忽略,继续) 最后 ,夹角和取绝对值 跟3.0比较,大于3.0,那么在里面,否则在外面。

//---以下是我的AC源码,之前wa了好久,原来就是忘了考虑输入的顺时针或逆时针,只要加上fabs()!
//就可以了,呵呵

#include<iostream.h>
#include
<math.h>
struct Point
{
double x;
double y;
}
pt[1000];//依顺时针或逆时针存储简单多边形的点
int n;
Point p;
double MIN(double a,double b)
{
return a<b?a:b;
}

double MAX(double a,double b)
{
return a>b?a:b;
}

double mulpti(Point ps , Point pe , Point p)
{
double m;

m
=(pe.x-ps.x)*(p.y-ps.y)-(p.x-ps.x)*(pe.y-ps.y);

return m;
}

void p_in_ploygon(Point p)//要判断的点
{
int i;
double xa,ya,xb,yb;
double cos0;
double flag=0;//用于累加角度
bool tag=false;
double m;
for(i=n-1;i>=1;i--)
{
   
//差积判断点是否在线段
   m=mulpti(pt[i+1] , pt[i] , p);
   
if( m==0 )
   
{
    
if(p.x>=MIN(pt[i+1].x,pt[i].x) && p.x<=MAX(pt[i+1].x,pt[i].x) && p.y>=MIN(pt[i+1].y,pt[i].y) && p.y<=MAX(pt[i+1].y,pt[i].y) )
    
{
     tag
=true;
     
break;
    }

    
continue;
   }

   xa
=pt[i+1].x-p.x;
   ya
=pt[i+1].y-p.y;
   xb
=pt[i].x-p.x;
   yb
=pt[i].y-p.y;
   cos0
=(xa*xb + ya*yb)/(sqrt(xa*xa+ya*ya)* sqrt(xb*xb+yb*yb));
   
if( m > 0 )
   
{
    flag
+=acos(cos0);
   }

   
else
   
{
    flag
-=acos(cos0);
   }

}

if( fabs(flag)<3.0 && !tag) //注意求绝对值
{
   cout
<<"Outside"<<endl; 
}

else
{
   cout
<<"Within"<<endl;
}

}


void s(Point p)//当输入的多边形只有一个点
{
if(p.x == pt[1].x && p.y == pt[1].y )
   cout
<<"Within"<<endl;
else
   cout
<<"Outside"<<endl;
}

int main()
{
int i,m;
int c=0;
while(cin>>n&&n!=0)
{
   cin
>>m;
   
for(i=1;i<=n;i++)
   
{
    cin
>>pt[i].x>>pt[i].y;
   }

   n
++;
   pt[n]
=pt[1];
   
if(c!=0)cout<<endl;
   cout
<<"Problem "<<++c<<":"<<endl;
   
for(i=1;i<=m;i++)
   
{
    cin
>>p.x>>p.y;
    
if(n==2)
    
{
     s(p);
    }

    
else
    
{
     p_in_ploygon(p);
    }

   }

}

return 0;

 

 

抱歉!评论已关闭.