今天还是在看计算几何,原来计算几何一直有点差,不过今天这道题一交就过,我都惊讶了。题目是中文题很容易理解,就是判断一点是否在多边形内。判断点在多边形内有好几种方法,我这里用的是 射线法+微移,我原来以为真的要移动,看了学长借给我的 刘汝佳《算法艺术》,之后对这种方法有了比较深刻的认识。
http://blog.csdn.net/aacm1992/article/details/7747483
这道题没什么陷阱,硬要算的话就是:点在多边形的边上也算是中了靶的。
代码:
#include<iostream>
#include<cmath>
using namespace std;
#define exp 1e-8
struct Point
{
double x,y;
} pt[105],p;
int n;
int Cross(Point a,Point b,Point c)
{
double t=(b.x-a.x)*(c.y-a.y)-(c.x-a.x)*(b.y-a.y);
//printf("%.3lf\n",t);
if( fabs(t)<exp)
return 0;
return ( t>0? 1:-1 );
}
bool Judge(Point a,Point b,Point c)
{
if( a.y>=min(b.y,c.y)&&a.y<=max(b.y,c.y))
return true;
return false;
}
int cmp(double a,double b)
{
double t=a-b;
if( fabs(t)<exp)
return 0;
return ( t>0? 1:-1);
}
bool Inpolygon()
{
int i,cnt;
Point a,b;
cnt=0;
for( i=0; i<n; i++){
a=pt[i];
b=pt[(i+1)%n];
if( a.y<b.y){ //a存储线段高点 b存储线段低点
Point temp=a;
a=b;
b=temp;
}
int flag=Cross(p,b,a);
if( !flag&&Judge(p,a,b))
return true;
if( flag>0 && cmp(a.y,p.y)==1 && cmp(b.y,p.y)<=0)//判断P是否在高点下方 或者在地点上或低点上方。
cnt++;
}
if( cnt%2)
return true;
return false;
}
int main()
{
int m,i;
double x,y;
while( scanf("%d",&n)!=EOF){
for( i=0; i<n; i++)
scanf("%lf%lf",&pt[i].x,&pt[i].y);
scanf("%d",&m);
while( m--){
scanf("%lf%lf",&p.x,&p.y);
if( Inpolygon())
printf("Yes\n");
else
printf("No\n");
}
}
return 0;
}