3
votes

I have an array of points in 3d Cartesian space:

P = np.random.random((10,3))

Now I'd like to find their distances to a given axis and on that given axis

Ax_support = array([3,2,1])
Ax_direction = array([1,2,3])

I've found a solution that first finds the vector from each point that is perpendicular to the direction vector... I feel however, that it is really complicated and that for such a standard problem there would be a numpy or scipy routine already out there (as there is to find the distance between points in scipy.spatial.distance)

1

1 Answers

1
votes

I would be surprised to see such an operation among the standard operations of numpy/scipy. What you are looking for is the projection distance onto your line. Start by subtracting Ax_support:

P_centered = P - Ax_support

The points on the line through 0 with direction Ax_direction with the shortest distance in the L2 sense to each element of P_centered is given by

P_projected = P_centered.dot(np.linalg.pinv(
             Ax_direction[np.newaxis, :])).dot(Ax_direction[np.newaxis, :])

Thus the formula you are looking for is

distances = np.sqrt(((P_centered - P_projected) ** 2).sum(axis=1))

Yes, this is exactly what you propose, in a vectorized way of doing things, so it should be pretty fast for reasonably many data points.

Note: If anybody knows a built-in function for this, I'd be very interested!