在凸多边形外寻找与其边垂直的点

2024-09-24 02:20:33 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在处理2D凸面多边形,周围有两组点,让我们将最靠近多边形的邻域称为A,再向外的邻域称为B。这些点集是原始多边形的偏移,偏移本身是使用Python中的Shapely完成的(无可否认,这项工作做得并不好,如果有人知道任何替代方案,请发表评论)

我现在想做的是,对于A中的每个点,找到B中在多边形边的法线方向上离它最近的点。我在下面附上了一些图片,这些图片解释了我做得比文字更好的地方

到目前为止,我自己尝试过这样做,但结果很差。我的方法是对A中的每个点,使用最近邻搜索找到其最近的两个顶点,这两个点可以用来计算斜率。我找到垂直于该斜率的线,固定在我当前迭代通过的点A上。然后我构建一组poi沿着这条线,找到B中离它最近的点。为了确保我在正确的方向上找到点,我实际上在B中找到了两个最近的点,并选择了一个,这样它到我在A中迭代通过的点的距离就最小化了。这对A中的所有点都是这样做的

这种方法有几个缺点:

  1. 如果一个点正好在一个顶点上,它就会失败并产生垃圾
  2. 如果有一条长边,且该点靠近该边的起点或终点,则可能会选择错误的两个顶点来计算坡度

这让我相信一定有更好的方法。这里有一张图片解释我想做什么:

红色虚线是我正在使用的凸多边形的一个示例。黑色点表示较小的偏移量A,白色点表示较大的偏移量B。绿色点是B中的点,我的代码当前将其标识为正常点,尽管它们显然是错误的。我画了蓝色箭头以显示我所做的根据每条边的法线方向确定一个顶点。作为代码缺点的一个示例,您可以看到,在最右边的点上,两个点正好位于一个顶点上,代码没有选择我们期望的点

以下是代码本身的副本:

def Nearest_Points(inner, outer, vertices):
    step = 0.1
    near_points = []
    tree = KDTree(vertices)
    line_tree = KDTree(outer_points)

    for point in inner_points:

        #Finding closest vertices to point
        dist, index = tree.query(point, k = 2)
        nearest_vertex1 = vertices[index[0]]
        nearest_vertex2 = vertices[index[1]]

        #Constructing line perpendicular to edge and anchored at point
        dy = nearest_vertex2[1]-nearest_vertex1[1]
        dx = nearest_vertex2[0]-nearest_vertex1[0]
        line_points = []
        if dy != 0:
            for i in range(-50, 51):
                    x = point[0]+i*step
                    y = -dx/dy*(x-point[0])+point[1]
                    line_points.append([x, y])
        else:
            for i in range(-50, 51):
                    line_points.append([point[0], point[1]+step*i])

        #Finding the two points in outer neighborhood closest to line 
        dist2, index_2 = line_tree.query(line_points, k = 2)
        dist2_arr = np.asarray(dist2)
        min_1 = np.min(dist2_arr[:,0])
        min_2 = np.min(dist2_arr[:,1])

        for i in range(len(dist2)):
            if dist2[i][0] == min_1:
                index_2_1 = i
            if dist2[i][1] == min_2:
                index_2_2 = i
        near1 = outer_points[index_2[index_2_1][0]]
        near2 = outer_points[index_2[index_2_2][1]]

        #Of these two points, finding the one closest to the point currently being iterated through
        near1_dist = (near1[0]-point[0])**2 + (near1[1]-point[1])**2
        near2_dist = (near2[0]-point[0])**2 + (near2[1]-point[1])**2
        if near1_dist < near2_dist:
            near_points.append(near1)
        else: 
            near_points.append(near2)
    return near_points

多谢各位


Tags: inindexdistlinemin多边形pointspoint