题目大意:RT
分析:构造一条射线,如果穿越偶数条边,那么就在多边形外面,如果穿越奇数条边,那么就在多边形里面。
代码如下:
===========================================================================================================================
#include<stdio.h> #include<algorithm> #include<string.h> #include<math.h> using namespace std; const int MAXN = 1e4+7; const double EPS = 1e-10; const double FarX = 1e5+7; int Sign(double x) { if(x > EPS)return 1; if(fabs(x) <= EPS)return 0; return -1; } struct point { double x, y; point(double x=0, double y=0):x(x),y(y){} point operator - (const point &t)const{ return point(x-t.x, y-t.y); } double operator ^(const point &t)const{ return x*t.y - y*t.x; } }; struct segment { point s, e; segment(point s=0, point e=0):s(s), e(e){} bool OnSeg(const point &p) {///判断点是否在线段上 if(Sign((s-e)^(p-e)) == 0)///共线 if(Sign((p.x-s.x)*(p.x-e.x)) <= 0)///位于线段的中间或者两端 if(Sign((p.y-s.y)*(p.y-e.y)) <= 0) return true; return false; } bool Inter(const segment &t) {///完全相交情况 return Sign((s-e)^(t.s-e))*Sign((s-e)^(t.e-e)) == -1; } }; int Find(segment sg[], int N, point &p) {///判断点与多边形的关系,在多边形上返回0,内返回1,外返回-1 ///使用射线法判断,判断穿越的边是奇数还是偶数,奇数说明在里面,偶数说明在外面 segment ray(p, point(FarX, p.y));///构造射线 int cnt = 0; for(int i=0; i<N; i++) { if(sg[i].OnSeg(p)) return 0;///如果点在边界上 if(ray.OnSeg(sg[i].s))///如果穿越点,记录y值小的 {///如果穿过s点 if(sg[i].e.y - sg[i].s.y > EPS) cnt += 1; } else if(ray.OnSeg(sg[i].e)) { if(sg[i].s.y - sg[i].e.y > EPS) cnt += 1; } else if(ray.Inter(sg[i]) && sg[i].Inter(ray)) cnt += 1; } if(cnt % 2) return 1; return -1; } int main() { segment sg[MAXN]; point A, B, p; int i, N; scanf("%d", &N); for(i=0; i<N; i++) { scanf("%lf%lf%lf%lf", &A.x, &A.y, &B.x, &B.y); sg[i] = segment(A, B); } scanf("%lf%lf", &p.x, &p.y); int ans = Find(sg, N, p); if(ans == 0) printf("BORDER "); else if(ans == 1) printf("INSIDE "); else printf("OUTSIDE "); return 0; }