I have a NumPy array that can be used to create a curve the array looks like this.
curve=np.asarray([0,0,0], [0.5,0,0], [0.8,0.2,0], [1,0.5,0], [1.2,0.7,0])
If I connect them up it will look like the following figure
The points are the vertices on the curve.
Is there any way to find the arc length between any two given points on this curve for example the two blue points?
To get the curve length between any two points of the curve you need to define these points as vertices of this curve.
In the following example I insert the two blue points at the needed position and then sum up the Euclidean distances of all the vertices between these two points:
import numpy as np
curve = np.asarray([[0,0,0], [0.5,0,0], [0.8,0.2,0], [1,0.5,0], [1.2,0.7,0]])
points = np.array([[.65,.1,0],[.9,.35,0]])
#insert points in curve
start = np.searchsorted(curve[:,0], points[0,0])
curve = np.insert(curve, start, points[0], axis=0)
end = np.searchsorted(curve[:,0], points[1,0])
curve = np.insert(curve, end, points[1], axis=0)
print(curve)
#[[0. 0. 0. ]
# [0.5 0. 0. ]
# [0.65 0.1 0. ]
# [0.8 0.2 0. ]
# [0.9 0.35 0. ]
# [1. 0.5 0. ]
# [1.2 0.7 0. ]]
def curve_length(curve):
""" sum of Euclidean distances between points """
return np.sum(np.sqrt(np.sum((curve[:-1] - curve[1:])**2,axis=1)))
print(curve_length(curve[start:end+1]))
#0.3605551275463989
as per comment: in order to find the coordinates of the point point
on the curve that is len
units away from the origin (curve[0]
) we first cumulatively sum up the curve segments' lengths to find the segment on which our point lies. Let this segment be the line between curve[i]
and curve[i+1]
. We then find the portion lambda (l
) of this segment according to the following sketch:
With this lambda we can then calculate the searched for point:
import numpy as np
import matplotlib.pyplot as plt
curve = np.asarray([[0,0,0], [0.5,0,0], [0.8,0.2,0], [1,0.5,0], [1.2,0.7,0]])
len = 1
#len is reached between curve[i] and curve[i+1]
cs = np.cumsum(np.sqrt(np.sum((curve[:-1] - curve[1:])**2, axis=1)))
i = np.argmin(cs < len)
dist = len - cs[i-1]
l = dist / np.sqrt(np.sum((curve[i+1] - curve[i])**2))
point = l * (curve[i+1] - curve[i]) + curve[i]
print(point)
#[0.8773501 0.31602515 0. ]
Visualization:
plt.plot(curve[:,0], curve[:,1])
plt.plot(point[0], point[1], 'o')
Verification:
end = np.searchsorted(curve[:,0], point[0])
curve = np.insert(curve, end, point, axis=0)
print(curve_length(curve[:end+1]))
#1.0