📌  相关文章
📜  检查给定点是否位于凸多边形的给定 N 个点内(1)

📅  最后修改于: 2023-12-03 15:40:36.110000             🧑  作者: Mango

检查点是否位于凸多边形内

在计算机图形学中,对于一个凸多边形和一个点,判断这个点是否位于多边形内是一个常见的问题。下面介绍几种判断方法。

射线法

射线法是最常见的方法之一。假设我们有一个多边形以及一个点P,我们从点P引一条任意方向的射线。如果这条射线和多边形的边有奇数个交点,那么点P在多边形内部,否则点P在多边形外部。

射线法示意图

代码实现:

def point_in_polygon(point, polygon):
    num_vertices = len(polygon)
    intersections = 0
    
    for i in range(num_vertices):
        p1 = polygon[i]
        p2 = polygon[(i+1)%num_vertices]
        
        if (p1[1] <= point[1] < p2[1]) or (p2[1] <= point[1] < p1[1]):
            if p1[0] == p2[0]:
                if p1[0] <= point[0]:
                    intersections += 1
            else:
                x_intersect = (point[1] - p1[1]) * (p2[0] - p1[0]) / (p2[1] - p1[1]) + p1[0]
                if x_intersect == point[0]:
                    return True
                if x_intersect > point[0]:
                    intersections += 1
    
    return intersections % 2 == 1
利用向量叉积

我们可以将多边形的每一条边与点P连成向量,然后计算向量叉积,如果向量叉积的正负性一致,说明点P在多边形内部,否则在外部。

向量叉积法示意图

代码实现:

def point_in_polygon(point, polygon):
    num_vertices = len(polygon)
    intersections = 0
    
    for i in range(num_vertices):
        p1 = polygon[i]
        p2 = polygon[(i+1)%num_vertices]
        vector1 = [p2[0]-p1[0], p2[1]-p1[1]]
        vector2 = [point[0]-p1[0], point[1]-p1[1]]
        
        cross_product = vector1[0]*vector2[1] - vector1[1]*vector2[0]
        if cross_product == 0:
            return True
        if cross_product > 0:
            intersections += 1

    return intersections == num_vertices or intersections == 0
利用凸包

我们可以先计算出多边形的凸包,然后判断点是否在凸包内部。凸包可以用 Graham 算法或者快速凸包算法求解。

凸包法示意图

代码实现:

from scipy.spatial import ConvexHull

def point_in_polygon(point, polygon):
    hull = ConvexHull(polygon)
    hull_vertices = [(polygon[v][0], polygon[v][1]) for v in hull.vertices]
    return point_in_polygon(point, hull_vertices)

以上是几种常用的判断方法,根据不同的场景和数据,选择不同的方法可以减小时间复杂度和消耗的计算资源。