Broken line - SGU 124(判断点与多边形的关系)

题目大意: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\n");
     else if(ans == 1)
        printf("INSIDE\n");
     else
        printf("OUTSIDE\n");

     return 0;
 }

 

posted @ 2015-09-24 15:04  无忧望月  阅读(207)  评论(0编辑  收藏  举报
levels of contents