今天还是在看计算几何,原来计算几何一直有点差,不过今天这道题一交就过,我都惊讶了。题目是中文题很容易理解,就是判断一点是否在多边形内。判断点在多边形内有好几种方法,我这里用的是 射线法+微移,我原来以为真的要移动,看了学长借给我的 刘汝佳《算法艺术》,之后对这种方法有了比较深刻的认识。
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; }