在没有for循环的情况下计算Python中点数组到线段之间的欧氏距离

Calculate the euclidian distance between an array of points to a line segment in Python without for loop

我正在寻找一个函数来计算具有两个坐标 (x, y) 的 numpy 点数组和一条线段之间的欧几里得距离。我的目标是在 0.01 秒内获得线段和 10k 点的结果。

我已经找到了单点的功能。但是 运行 for 循环非常低效。

我还发现了这个计算无限直线距离的函数:

def line_dists(points, start, end):
    if np.all(start == end):
        return np.linalg.norm(points - start, axis=1)

    vec = end - start
    cross = np.cross(vec, start - points)
    return np.divide(abs(cross), np.linalg.norm(vec))

它非常有效,我想对有界线采用类似的方法。

感谢您的帮助。

设置 – 测试点 P、端点 AB:

  • P - Anormalize(A - B) 进行点积,得到 signed 平行距离分量 s A。同样 Bt.

  • 取这两个数的最大值和零,得到夹紧的平行距离分量。如果该点位于线段的“边界”(Voronoi 区域?)之外,则此值为非零。

  • 像以前一样使用叉积计算垂直距离分量。

  • 使用毕达哥拉斯计算所需的最近距离(从PA的灰线)。

上面是无分支的,因此很容易用 numpy:

向量化
def lineseg_dists(p, a, b):
    # Handle case where p is a single point, i.e. 1d array.
    p = np.atleast_2d(p)

    # TODO for you: consider implementing @Eskapp's suggestions
    if np.all(a == b):
        return np.linalg.norm(p - a, axis=1)

    # normalized tangent vector
    d = np.divide(b - a, np.linalg.norm(b - a))

    # signed parallel distance components
    s = np.dot(a - p, d)
    t = np.dot(p - b, d)

    # clamped parallel distance
    h = np.maximum.reduce([s, t, np.zeros(len(p))])

    # perpendicular distance component, as before
    # note that for the 3D case these will be vectors
    c = np.cross(p - a, d)

    # use hypot for Pythagoras to improve accuracy
    return np.hypot(h, c)