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

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


Setup – test point P, endpoints A and B:

enter image description here

  • Take the dot-product of P - A with normalize(A - B) to obtain the signed parallel distance component s from A. Likewise with B and t.

  • Take the maximum of these two numbers and zero to get the clamped parallel distance component. This will only be non-zero if the point is outside the "boundary" (Voronoi region?) of the segment.

  • Calculate the perpendicular distance component as before, using the cross-product.

  • Use Pythagoras to compute the required closest distance (gray line from P to A).

The above is branchless and thus easy to vectorize with 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)