This is Words and Buttons Online — a collection of interactive #tutorials, #demos, and #quizzes about #mathematics, #algorithms and #programming.

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 cubics are the simplest functions you can link together and expect continuity and smoothness at the joints. But can you get it even simpler than that?

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 of how to build an interpolating function in the Programmer's guide to polynomials and splines. Long story short, if you run a polynomial through some 4 points, it could minimally be of 3rd degree. Which is a cubic.

Here is an interactive example. You can drag the points across the canvas. The curve is rather predictable, especially in between the second and the third points. That's the piece we prefer 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's effect. To avoid this, 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 to the derivatives of its successor.

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 as the oscillations start 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. And 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 y(x), we can expect it to be smooth only if the first derivative of the function is continuous. That's true for y(x). But for x(t), y(t), the tangent is not the same as the derivative. It's the proportion of its derivatives. It doesn't have to be like that:

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

We only need this:

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

When your curve becomes uncontrollable, you can safely calm it down. Cut down its derivatives in every point to make it more like a piece-wise linear interpolation.

Here is the example, increment the derivative divisor to cut down the derivatives:

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 is 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? 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. That calms it down.

Conclusion

Spline function is a broad concept, and you get to choose what you want. Sometimes you want 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. Quadratic splines demonstrate all that rather well.