射线相交法判断。
这个点向右发出一条射线,如果和多边形相交交点为奇数,则这个点在多边形内,反之不在。证明神马的自己证吧。
开始用int错得一塌糊涂,因为我的射线x坐标开得不够大,如果大的话,叉积判断后可能超int了,后改成doubleA掉了,注意输出块中间有换行,不是每块都有换行。
开始木有加精度判断,现在加下精度判断,就可以当我的模板了~~
#include <queue> #include <stack> #include <math.h> #include <stdio.h> #include <stdlib.h> #include <iostream> #include <limits.h> #include <string.h> #include <algorithm> using namespace std; const int MAX = 110; const double eps = 1e-6; struct point{ double x,y; }; struct beeline{ point a,b; }; point p[MAX]; int n; bool dy(double x,double y) // x > y { return x > y + eps; } bool xy(double x,double y) // x < y { return x < y - eps; } bool dyd(double x,double y) // x >= y { return x > y - eps; } bool xyd(double x,double y) // x <= y { return x < y + eps; } bool dd(double x,double y) // x == y { return fabs( x - y ) < eps; } double crossProduct(point a,point b,point c)//向量 ac 在 ab 的方向 { return (c.x - a.x)*(b.y - a.y) - (b.x - a.x)*(c.y - a.y); } bool onSegment(point a, point b, point c) { double maxx = max(a.x,b.x); double maxy = max(a.y,b.y); double minx = min(a.x,b.x); double miny = min(a.y,b.y); if( dd(crossProduct(a,b,c),0.0) && dyd(c.x,minx) && xyd(c.x,maxx) && dyd(c.y,miny) && xyd(c.y,maxy) ) return true; return false; } bool segIntersect(point p1,point p2, point p3, point p4) { double d1 = crossProduct(p3,p4,p1); double d2 = crossProduct(p3,p4,p2); double d3 = crossProduct(p1,p2,p3); double d4 = crossProduct(p1,p2,p4); if( xy(d1 * d2,0.0) && xy( d3*d4,0.0 ) ) return true; if( dd(d1,0.0) && onSegment(p3,p4,p1) ) return true; if( dd(d2,0.0) && onSegment(p3,p4,p2) ) return true; if( dd(d3,0.0) && onSegment(p1,p2,p3) ) return true; if( dd(d4,0.0) && onSegment(p1,p2,p4) ) return true; return false; } bool inPolygon(point pot) { int count = 0; beeline l; l.a = pot; l.b.x = 1e10; l.b.y = pot.y; p[n] = p[0]; for(int i=0; i<n; i++) { if( onSegment(p[i],p[i+1],pot) ) return true; if( !dd(p[i].y,p[i+1].y) ) { int tmp = -1; if( onSegment(l.a,l.b,p[i]) ) tmp = i; else if( onSegment(l.a,l.b,p[i+1]) ) tmp = i+1; if( tmp != -1 && dd(p[tmp].y,max(p[i].y,p[i+1].y)) ) count++; else if( tmp == -1 && segIntersect(p[i],p[i+1],l.a,l.b) ) count++; } } if( count % 2 == 1 ) return true; return false; } int main() { int m; int ind = 1; point pot; while( ~scanf("%d",&n) && n ) { if( ind != 1 ) printf("/n"); scanf("%d",&m); for(int i=0; i<n; i++) scanf("%lf %lf",&p[i].x,&p[i].y); printf("Problem %d:/n",ind++); while( m-- ) { scanf("%lf %lf",&pot.x,&pot.y); if( inPolygon(pot) ) printf("Within/n"); else printf("Outside/n"); } } return 0; }