1

Background

  1. I want to generate a unit-length cubic spline (arc length of 1), with way- or control-points as the input.
  2. I then want to generate another unit-length cubic spline in the same way, having it smoothly connect from the previous spline.

I want to do this iteratively (over and over again) and using SciPy or another easy-to-use library in Python.

What I've tried

To demonstrate, let's consider that I initially have 10 waypoints, i.e.:

y0 = np.array([
    [-18., -20.],
    [-18.,  18.],
    [-14.,  18.],
    [-14., -18.],
    [-10., -18.],
    [-10.,  18.],
    [ -6.,  18.],
    [ -6., -18.],
    [ -2., -18.],
    [ -2.,  18.]
])
plt.plot(y0[:,0], y0[:,1], 'bx')

It's pretty straightforward to generate a unit-length spline using scipy.interpolate.CubicSpline like so:

x0 = np.linspace(0, 1, y0.shape[0])
f0 = CubicSpline(x0, y0, bc_type='natural')

Now, let's suppose I receive 10 new waypoints. In an attempt to continue the spline, I repeat the previous procedure, including the last waypoint and incrementing the independent variable interval:

y1 = np.array([
    [ -2.,  18.],
    [  2.,  18.],
    [  2., -18.],
    [  6., -18.],
    [  6.,  18.],
    [ 10.,  18.],
    [ 10., -18.],
    [ 14., -18.],
    [ 14.,  18.],
    [ 18.,  18.],
    [ 18., -20.]
])
plt.plot(y1[:,0], y1[:,1], 'gx')
x1 = np.linspace(1, 2, y1.shape[0])
f1 = CubicSpline(x1, y1, bc_type='natural')

Now, if we plot these interpolants, there will obviously be a lack of smoothness between the last waypoint of the first interpolant.

plt.plot(y0[:,0], y0[:,1], 'b-')
plt.plot(y1[:,0], y1[:,1], 'g-')
plt.show()

enter image description here

Going forward

  1. Is there a way to constrain the curvature at the beginning of the second spline?
  2. I suppose generating the splines with the control points as the inputs would give a straightforward way to enforce smoothness between splines.
  3. Is there a straightforward way to implement arc-length reparameterisation?
cisprague
  • 71
  • 8
  • Seems like you want spline 1 to have bc_type=((2,0),(1,x)) and spline 2 to have bc_type=((1,x), (2,0)) – AlexNe Jun 28 '20 at 16:12
  • But then you could just use one large spline instead – AlexNe Jun 28 '20 at 16:14
  • @AlexNe indeed, I could — but, that would assume that I have all the waypoints available at once. Recall that the second batch of waypoints is available only after the first spline is generated with the first batch of waypoints. Of course, I could just reinterpolate through all the points once the second batch becomes available, but then that would change the original first spline. Essentially, here I want to keep the first spline the way it was. – cisprague Jun 28 '20 at 16:59
  • Ah. Then adjusting the gradient at the end via bc_type is probably the way forward – AlexNe Jun 28 '20 at 17:01
  • @AlexNe, you mean optimising the `bc_type` value so that it satisfies some measure of smoothness at the splines' intersection? – cisprague Jun 28 '20 at 19:52
  • Probably not even optimize. Just choose a suitable tangent – AlexNe Jun 28 '20 at 20:15
  • @AlexNe aha, so maybe I could approximate the parametric derivative at the last waypoint of the first spline (perhaps through finite difference) — then place two infinitesimally separated points that correspond to that derivative. Since the spline returned from this method must pass through all supplied points, the resulting union should be approximately smooth. – cisprague Jun 28 '20 at 20:41

0 Answers0