Cubic Splines
The word "spline" had its origin in ship building. To create smooth hull shapes, ancient ship builders would drive pegs into the ground, and then lay down a very large thin flexible strip of wood (the "spline") that would be forced into a curve by the position of the pegs. They would then use the resulting smooth curve as a guide for cutting the lumber that they would use to create the hulls of their ships.
PARAMETRIC CUBIC CURVES The underlying math for creating smooth splines is generally to create a set of parametric cubic curves that fit together seamlessly, so that they appear to form a single smooth curve. The general recipe is as follows:
After defining the above functions x(t) and y(t), it's easy to draw the resulting spline segment. For example:
function drawSpline(x, y, dt) { let a = [x(0), y(0)]; for (let t = dt ; t <= 1 ; t += dt) { let b = [x(t), y(t)]; drawLine(a, b); // we assume this function is already defined. ** a = b; } } ** To be clear (because some students have asked), you don't need to create a drawLine function. I'm just using it here as an example. TRANSLATING FROM THE HUMAN DESIGNER TO THE COMPUTER For most human beings, it would be extremely difficult to design such curves by directly typing the coefficients of cubic polynomials. For this reason, we create other ways of defining those coefficients, which are more human-friendly. All such methods work by transforming some easier to understand set of values into the underlying cubic coefficients (a,b,c,d). In class we went over two of the more important such methods, Hermite splines and Bezier splines. HERMITE SPLINES If our human user wants to define things in terms of the position and orientation at the beginning and end of each cubic spline segment, then we use the Hermite spline. We do all the math independently for each coordinate (eg: x and y, or x,y and z).
P0 = value at start of the segment (where t = 0). We create four "basis functions", each of which varies only one thing:
So to get from (P0,P1,R0,R1) to the coefficients (a,b,c,d) that define cubic polynomial a * t^3 + b * t^2 + c * t + d, we apply the Hermite Matrix, which is just a way of describing these four basis functions. Each of the four functions is described in a single column of the Hermite Matrix:
BEZIER SPLINES If our human user wants to define things by moving points around on a screen, then the Bezier spline is a good choice. Again, we do the math independently for each coordinate.
A = value at start of the segment (where t = 0).
In other words:
(1-t) * ( (1-t) * ((1-t)*A + t*B) + t * ((1-t)*B + t*C) ) + t * ( (1-t) * ((1-t)*B + t*C) + t * ((1-t)*C + t*D) ) When you multiply everything out, this turns into:
(1-t) * (1-t) * (1-t) * A + 3 * (1-t) * (1-t) * t * B + 3 * (1-t) * t * t * C + t * t * t * D This gives us what we need to go from key values (A,B,C,D) to cubic coefficients (a,b,c,d). Each line of the above equation can be turned into a column of the characteristic Bezier Matrix:
Homework (due before class on Tuesday April 10): Implement either Hermite or Bezier splines. For extra credit, implement both. Apply your spline to either creating shapes. For example, you can use a spline to vary both the radius and the height of a parametric shape, as a function of v, like the vase shape I showed in class. Or try creating animated movement, using splines to vary rotation and/or translation over time. For extra credit, do both.
|