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

Jér*_*ôme 5 python geometry numpy euclidean-distance

我正在寻找一个函数来计算具有两个坐标 (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))
Run Code Online (Sandbox Code Playgroud)

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

感谢您的帮助。

meo*_*dog 8

设置 – 测试点P、端点AB

在此处输入图片说明

  • 取的点积P - Anormalize(A - B)以获得签名平行距离分量sA。同样有Bt

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

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

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

以上是无分支的,因此很容易矢量化numpy

def lineseg_dists(p, a, b):
    
    # 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)
Run Code Online (Sandbox Code Playgroud)

  • 非常感谢您快速而详细的解决方案!这似乎按预期工作,10k 点大约需要 1 毫秒。 (3认同)