判断点与多边形的关系(4):射线法

发布时间 2023-07-21 13:24:56作者: porter_代码工作者
https://blog.csdn.net/ezhchai/article/details/78867367

终极大招来了,射线法是解决这一问题的最优方法,其他方法仅具有理论意义,如果工程应用的话,知道这个方法就够了。
射线法的思想是:以目标点为端点引一条射线,计算这条射线和多边形所有边的交点数目。如果交点个数为奇数,则点在多边形部,反之则在多边形外部。
图例说明,如下图所示:

 

 

所谓射线法,关键在于单向发射,为简化问题,以水平线为例,程序实现中也是这么处理的。O点向右发出射线,与多边形的交点是B、C、D,向左发出射线,交点是A,均为奇数个。P点在多边形外,无论想哪方向发出摄像,都有2个交点。

 

 

对于带内岛的形状,射线法同样适用,如上图所示。在实际应用中,射线法会有很多特殊情况需要讨论,全部都讨论会比较复杂,但结论是一样的。这里不做过多讨论了,不过可以给大家结论:射线法适用于所有类型的多边形进行点与多边形关系的判断,且实现相对简单,速度较快,是工程应用的不二之选。要注意的是,计算中所有数值都要选择浮点数类型,以保证计算精度。
参考代码如下:

int InPolygon_Ray(const CZPolygon& polygon, CZPoint_t pt) {
    int itNumPt = polygon.size();
    CZPoint_t pt_1, pt_2;
    int itJunctionCount = 0;
    for (int i = 0; i < (itNumPt - 1); i++) {
        pt_1 = polygon[i];
        pt_2 = polygon[i + 1];
        if (((pt.y >= pt_1.y) && (pt.y <= pt_2.y)) || ((pt.y >= pt_2.y) && (pt.y <= pt_1.y))) {
            double duT = (pt.y - pt_1.y) / (pt_2.y - pt_1.y);
            double duXT = pt_1.x + duT * (pt_2.x - pt_1.x);
            if (pt.x == duXT)
                return ONSIDE;
            if (pt.x > duXT)
                itJunctionCount++;
        }
    }
    return itJunctionCount % 2 ? INSIDE : OUTSIDE;
}

https://www.cnblogs.com/luxiaoxun/p/3722358.html
https://blog.csdn.net/MQLCSDN/article/details/90106406 ---unity 应用