射线法检查一个点在不在多边形内-python 实现

参考文档:
https://www.cnblogs.com/gxcdream/p/7597865.html
https://www.cnblogs.com/muyefeiwu/p/11260366.html
https://blog.csdn.net/liangzhaoyang1/article/details/51088475

代码:

点击查看代码
# encoding=utf8
import numpy as np
from collections import namedtuple


Point = namedtuple("Point", ["x", "y"])


def isin_poly(p, poly, point_num):
    isin = False
    for i in range(point_num):
        p1 = poly[i]
        p2 = poly[(i + 1) % point_num]
        min_x, max_x = (p1.x, p2.x) if p1.x <= p2.x else (p2.x, p1.x)
        min_y, max_y = (p1.y, p2.y) if p1.y <= p2.y else (p2.y, p1.y)

        # 点积计算
        dot_a = (p.x - p1.x) * (p2.y - p1.y)
        dot_b = (p.y - p1.y) * (p2.x - p1.x)

        # 检查点是否在线段上
        if (
            # (p.x - p1.x) * (p2.y - p1.y) == (p2.x - p1.x) * (p.y - p1.y)  # 点积计算
            dot_a == dot_b  # 点积计算
            and min_x <= p.x <= max_x
            and min_y <= p.y <= max_y
        ):
            return True

        # # 线段与Y轴平行且检测点在线段上
        # if p1.y == p2.y and p.y == p1.y and min_x < p.x < max_x:
        #     return True
        #
        # # 线段与X轴平行且检查点在线段上
        # if p1.x == p2.x and p.x == p1.x and min_y < p.y < max_y:
        #     return True

        if p.y < min_y or p.y >= max_y:
            continue

        # x = (p.y - p1.y) * (p2.x - p1.x) / (p2.y - p1.y) + p1.x
        x = dot_b / (p2.y - p1.y) + p1.x
        if x > p.x:
            isin = not isin

    return isin


def test_isin(p, poly):
    return isin_poly(p, [Point(x, y) for x, y in poly[0]], len(poly[0]))


if __name__ == "__main__":
    # polys = [[
    #     [1,2],[2,3],[4,3],[5,0],[6,2],[7,0],[7,2],[9,3],[7,4],[9,5],[7,7],[6,5], [4,5],[3,7],[1,5]
    # ]]

    # polys = [[
    #     [0,2],[1,0],[3,2],[2,4],[4,4],[4,0],[6,0],[5,2],[6,4],[8,3],[6,2],[7,0],[9,1],[8,4],[9,5],[7,5],[7,6],[9,7],[8,9],[7,7],[6,9],[5,9],[5,7],[3,7],[4,9],[2,9],[3,6],[5,6],[6,5],[2,5],[2,7],[1,9],[0,8],[1,7],[0,6],[1,4],[0,3],[2,2]
    # ]]

    # polys = [[
    #     [9,9],[5,5],[2,9],[7,8],[7,10],[0,10],[0,6],[3,6],[1,4],[3,2],[5,2],[7,0],[9,0],[8,4],[7,1],[6,4],[9,5]
    # ]]

    polys = [[
            [5, 5],[5, 3],[10, 4],[6, 0],[8, 3],[4, 1],[2, 3],[0, 2],[2, 4],[0, 6],[3, 9],[4, 5],[4, 9],[5, 6],[5, 9],[8, 6],[10, 8],[10, 5],
    ]]

    n = 12
    matrix = np.empty((n, n), dtype=np.bool_)
    for x in range(n):
        for y in range(n):
            p = Point(x,y)
            matrix[x, y] = test_isin(p, polys)

    print(matrix)


测试结果:
多边形坐标:
polys = [[
[1,2],[2,3],[4,3],[5,0],[6,2],[7,0],[7,2],[9,3],[7,4],[9,5],[7,7],[6,5], [4,5],[3,7],[1,5]
]]

image

多边形坐标:
polys = [[
[0,2],[1,0],[3,2],[2,4],[4,4],[4,0],[6,0],[5,2],[6,4],[8,3],[6,2],[7,0],[9,1],[8,4],[9,5],[7,5],[7,6],[9,7],[8,9],[7,7],[6,9],[5,9],[5,7],[3,7],[4,9],[2,9],[3,6],[5,6],[6,5],[2,5],[2,7],[1,9],[0,8],[1,7],[0,6],[1,4],[0,3],[2,2]
]]

image

多边形坐标
polys = [[ [5,5],[5,3],[10,4],[6,0],[8,3],[4,1],[2,3],[0,2],[2,4],[0,6],[3,9],[4,5],[4,9],[5,6],[5,9],[8,6],[10,8],[10,5] ]]

image

posted @ 2024-07-10 10:55  一枚码农  阅读(1)  评论(0编辑  收藏  举报