• 【计算几何】点在多边形内部


    问题描述:已知点P(x,y)和多边形Poly,判断点P(x,y)是否在多边形内部。

    基本方法:射线法

    以点P为端点,向左方作射线L,由于多边形是有界的,所以射线L的左端一定在多边形外部,考虑沿着L从无究远处开始自左向右移动。

    遇到和多边形的第一个交点的时候,进入到了多边形的内部,遇到第二个交点的时候,离开了多边形...

    因而当L和多边形的交点数目C是奇数的时候,P在多边形内,是偶数,则P在多边形外。

    特殊情况分析,如图下图(a),(b),(c),(d)所示。

    图(a)中,L和多边形的顶点相交,交点只能计算一个。

    图(b)中,L和多边形顶点的交点不应被计算。

    图(c)和(d)中,L和多边形的一条边重合,这条边应该被忽略不计。

    代码实现如下:

    复制代码

     1 typedef struct Point
     2 {
     3     int x;
     4     int y;
     5 }Point;
     6 //  The function will return YES if the point x,y is inside the polygon, or
     7 //  NO if it is not.  If the point is exactly on the edge of the polygon,
     8 //  then the function may return YES or NO.
     9 bool IsPointInPolygon(std::vector<Point> poly,Point pt)
    10 {
    11     int i,j;
    12     bool c = false;
    13     for (i = 0,j = poly.size() - 1;i < poly.size();j = i++)
    14     {
    15         if ((((poly[i].y <= pt.y) && (pt.y < poly[j].y)) ||
    16             ((poly[j].y <= pt.y) && (pt.y < poly[i].y)))
    17             && (pt.x < (poly[j].x - poly[i].x) * (pt.y - poly[i].y)/(poly[j].y - poly[i].y) + poly[i].x))
    18         {
    19             c = !c;
    20         }
    21     }
    22     return c;
    23 }

    复制代码

    代码分析:

    条件1:((ploy[i].y <= pt.y) && (pt.y < poly[j].y)) || ((ploy[j].y <= pt.y) && (pt.y < poly[i].y))

    由于判断过程主要是判断,射线L与多边形每条边是否存在交点,而射线L平行于X轴,因此条件1相当于判断点P在Pi和Pj在垂直距离之间。

    条件2: (pt.x < (poly[j].x - poly[i].x) * (pt.y - poly[i].y)/(poly[j].y - poly[i].y) + poly[i].x)

    条件2可转换成:(pt.x - poly[i].x) * (poly[j].y - poly[i].y) - (poly[j].x - poly[i].x) * (pt.y - poly[i].y) < 0,相当于向量PiP和向量PiPj的叉积。

    当向量PiP和向量PiPj的叉积小于0时,向量PiP在向量PiPj的逆时针方向,相当于向量PiP在向量PiPj的右侧,而射线L由左侧射出,而且点P在Pi和Pj在垂直距离之间,因此,射线L和PiPj的跨立条件成立,相交。

    参考资料:

    http://alienryderflex.com/polygon/

  • 相关阅读:
    给任意多个链表然后要合并成一个
    hdu5967数学找规律+逆元
    poj2125最小点权覆盖+找一个割集
    poj3308 最小点权覆盖
    poj2987 最大闭合权子图基础题
    poj2699 转化为可行性判定问题+二分枚举+最大流
    判断割是否唯一zoj2587
    快排优化
    jvm垃圾收集器
    三次握手与四次挥手
  • 原文地址:https://www.cnblogs.com/xmphoenix/p/4508457.html
Copyright © 2020-2023  润新知