Quadratic splines are useful too

Usually, when people talk about splines, like at a party or in a pub, they talk about polynomial cubic splines. This makes sense as it is the simplest piece of function you can link together with any other two functions and expect continuity and smoothness at the joints. But can you get it even simpler than that?

Consider this. A parametric curve is a curve that has its every point defined as a function of some parameter. Let's build a polynomial curve that runs through 4 points.

x(t) = axt3 + bxt2 + cxt + dx
y(t) = ayt3 + byt2 + cyt + dy

There is an explanation how to build an interpolating function in the Programmer's guide to polynomials and splines. TL&DR, if you run a polynomial through some 4 points, it should be of 3rd degree minimum. Which is a cubic. Yes, we basically got ourselves a single cubic spline not conjoined with anything, but only constrained by the points.

You can drag the points across the canvas to see how it reacts. It is rather predictable, especially in between the second and the third points. That's the piece we usually use to build aggregate spline functions.

Just like with the simple non-parametric interpolation, you can't just add more points to the interpolating polynomial and expect it to behave nicely. It will eventually oscillate due to the Runge effect. That's why you need splines in the first place.

Now let's say we don't know how many points we want. Let's say points keep coming even while we're building our spline. We want to add points and retain the pieces of the curve that we've built.

We can still use cubic splines. It's just now we don't have to conjoint each of them from both sides, we only have to attach it from one. This can be done, for instance, by solving these systems:

axit3 + bxit2 + cxit + dxi = xi
axi(t+1)3 + bxi(t+1)2 + cxi(t+1) + dxi = xi+1
3axit2 + 2bxit + cxi = 3axi-1t2 + 2bxi-1t + cxi-1
6axit + 2bxi = 6axi-1t + 2bxi-1

ayit3 + byit2 + cyit + dyi = yi
ayi(t+1)3 + byi(t+1)2 + cyi(t+1) + dyi = yi+1
3ayit2 + 2byit + cyi = 3ayi-1t2 + 2byi-1t + cyi-1
6ayit + 2byi = 6ayi-1t + 2byi-1

The first and the second equations here are just the interpolation conditions. The third and the fourth are the ones that connect the derivatives of the i-th piece and of its successor's.

Here is an example of a 3-piece curve made of such one-sided cubic splines. Feel free to drag the points.

As you can see, it is smooth and continuous, so it's kind of a win. But it is nearly impossible to make it go where you want it to. It's even worse than with the Runge effect, it starts almost immediately.

You probably noticed that the first segment is straight. That's because both the initial derivatives, the first one and the second one, are zeros. The second segment is then quadratic, since its own second derivative on the left is still zero, and only the third one is fully cubic. But this is the least controllable one.

Still, since we keep the second derivative continuous, we know that our first derivative is smooth. You can see it in the next plot. The “hair” is the depiction of the derivative vector's length in multiple points. And yes, since the curve is parametric, and it's formed by two functions, it has two derivatives in every point: dx/dt and dy/dt, and you can make a vector out of them.

Now here is a trick that may help us tame the curve we got. With a function's plot, we can expect it to be smooth only if the first derivative of a function is continuous. That's true for plots. But for parametric curves, the tangent is not the same as the derivative. It's the proportion of its derivatives. It doesn't have to be like this:

dpxi(t) / dt = dpxi+1(t) / dt
dpyi(t) / dt = dpyi+1(t) / dt

We only need that:

dpxi(t) / dt = dpxi+1(t) / dt
dpyi(t) / dt dpyi+1(t) / dt

Simply put, this means that when your curve becomes uncontrollable, you can safely slow it down. Cut down its derivatives in every grip point to make it more like a piece-wise linear interpolation.

Here is the example when in every grid point the derivative gets divided by some divisor.

Derivative divisor:

Look at its hair! It's no longer continuous, it gets cut off after every grid point.

We also have another way to calm down our curve and it's to drop its second derivative in every grid point effectively turning it... into a quadratic spline!

Quadratic splines are even simpler than the cubic ones. We keep the idea of stealing the first derivative from the successor, but we don't touch the second one.

ait2 + bit + ci = xi
ai(t+1)2 + bi(t+1) + ci = xi+1
2ait + bi = 2ai-1t + bi-1

The first derivative is then continuous but it isn't smooth anymore. You can see it on the plot's hair. It gets a little bent at the grid points.

Now, this has all been fun, but is it really a problem to solve? I mean, why would we want to have a curve that grows as we plot it? Well, we might not want exactly that. But there is a niche for building splines on the go, and it is the animation.

Here is an arrow. Just click somewhere on the canvas, and it will go there. Setup several way-points, it will run through them all. Note that it also accumulates derivatives, which is its speed, and becomes thin and uncontrollable. Let it rest and get fat again. It calms it down.

Conclusion

Splines are more than just NURBS. Sometimes you need simple quadratic splines, sometimes you want 5-th degree ones with all the extra knots and weights. There are even non-polynomial splines, they have their applications too.

There is, however, some common body of knowledge that works for all splines, plots, and curves in general. I think, even if you wouldn't have to ever implement any kind of splines, you can benefit from learning about derivatives, parameterization, continuity, and smoothness. Simple quadratic splines are just the easy thing to study. It's a useful mental model in its own right.