Jon Maiga, 2020-06-29
After finishing a larger project I wanted to focus on something smaller and randomly picked up an old project where I used a b-spline setup to generate pretty smooth noise. For my own understanding, this post will go through the basics of b-splines and how to calculate certain coefficients.
B-splines use piecewise cubic polynomials that each interpolate between two consecutive points. To do this it requires additionally two neighboring points. We are only going to consider points with a constant space between them, or in the bigger picture, uniform b-splines.
I will denote the piecewise cubic curve that interpolates from to by where . Note that I am using the term “interpolate” wrong since the curve is not necessarily passing through the control points.
What makes b-splines smooth is that we can get any wanted continuity, for C2 we have:
To interpolate between the points and in C2 we additionally require the point to the left of and right of , so we have to consider the four points .
By using more control points and higher degree of the polynomials we can achieve any smoothness. For example, for C3 continuity requires fourth degree polynomials and five control points. This investigation will only consider C2.
The form of the cubic curve is where are weight functions for each control point those weight functions are called basis functions, which explains the name b(asis)-splines.
Each basis function takes a and outputs the weight of the corresponding point. The general form of our cubic basis function is
Here we will focus on one piecewise function, . Since we have four control points, we get four corresponding basis functions
Each basis function will output the weight between and , multiplying this with the corresponding point and summing all those gives us our cubic curve between the points and .
Now we need to figure out what the 16 coefficients are (). We have 16 unknown coefficients, so we will try to setup and solve a system of 16 equations in this step.
We already stated three constraints for the C2 guarantee,
Expanding the first of the three constraints we get
We can write this as
Now we cancel the points and expands each basis function:
We end up with 5 equations, so 11 to go! We repeat the exact same procedure for the first and second derivatives and we get 10 additional equations. First we take the derivatives, e.g. for we get:
Then take the same steps as for before and from the first derivatives we end up with
And from the second derivatives
Now we have 15 equations, but 16 unknowns so we need to add another. For the last one, we will add a new constraints that will keep our cubic in check, namely the sum of the weights of the of the basis functions should always equal to one, . To achieve this we can consider the case when , then we are only left with so clearly this has to add up to .
After adding this last equation we can finally solve the equation system and retrive the coefficients. I was lazy and put it into Mathematica and got the following back
So we end up with the following set of cubics
and finally plugging this into gives us
Plotting the individual basis functions in mathematica, you can see how the individual basis functions seamlessly goes from one another, , , and . One can also guess that the sum of all four functions at any is , just like our constraint wanted.
Here I am plotting three piecewise curves, to verify that it behaves as expected.
The idea is to use b-splines to smoothen noise and see how it holds up against more common methods such as Perlin and Simplex noise. I decided to split each part into different posts and bring it all together in the last.
I used Uniform Cubic B-Spline Curves as a reference, it’s gives a really friendly walk-through!
Written with StackEdit.