0

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 figureenter image description here

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?

hrokr
  • 3,276
  • 3
  • 21
  • 39
yihao ren
  • 369
  • 1
  • 4
  • 15

1 Answers1

1

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

UPDATE

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: enter image description here
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')

enter image description here

Verification:

end = np.searchsorted(curve[:,0], point[0])
curve = np.insert(curve, end, point, axis=0)
print(curve_length(curve[:end+1]))
#1.0
Stef
  • 28,728
  • 2
  • 24
  • 52
  • thank you a lot for your great help @Stef. Just one more question, if the length of the curve is in meters, and I want to find the coordinates of a point that is 1 meters away from point [0,0,0]. Could you please kindly suggest a method to do this? Thanks again for your great help. – yihao ren Sep 21 '20 at 16:19