Hermite Curves
May 17, 2020
If we have 2 endpoints , and , we can interpolate the line in a parametric manner for every by using the equation:
For each coordinate at a , we can solve for the interpolated coordinate by:
This parametric line equation is very powerful, and the concept can be extended towards higher-order polynomials where we must interpolate points in order to obtain the graphical curve.
It is rather straightforward to graph a straight line through the parametric line equation presented above, but what if we want to graph a cubic polynomial?
Cubic polynomials have a degree , and so can cross the x-axis 3 times by Bezout's Theorem. So it is no longer as straightforward as connecting the dots. The main problem is that we do not know when the curve changes direction.
Fortunately, a mathematician in the past has helped us with that. Charles Hermite invented Hermite Curves to help us interpolate cubic polynomials.
Given positions , and , and the directional vectors for the corresponding points , and , we can find a function such that:
Extending it to a third-dimension is easy here. We just introduce a in this case, and parametrically solve. So not a big deal here.
We can also interpolate an Hermite curve, by turning the polynomial into a matrix multiplication expression.
If we simplify and represent each coefficient of as some variant of , we get:
If we let be the vector , be the matrix of coefficients for each term , and be the vector consisting of known points, , we can express a value of the Hermite curve with:
Let's work out an example. Suppose we have the following defined:
We can write our matrix multiplication expression of our Hermite curve at as:
We then solve for the , and components independently.
Using the points I have given, if we interpolate through using various fixed , we can see we can obtain different versions of the plotted curve.
Finer increments will allow for a better approximated curve. Here are graphical examples of using , , , , and .
As you can see, we best approximate the curve when . Although this generates a nice looking curve, there are more data points to interpolate, and as a result, more computationally expensive.
Choosing an appropriate step for interpolation should be kept in mind if performance is a concern.
Implementation
We use glMatrix
library to compute the matrices to interpolate a point given a in the Hermite curve.
for(let t = 0; t <= 1.0; t += 0.01) {
const coord = hermite(p0, p1, pp0, pp1, t);
console.log(coord);
}
function hermite(p0, p1, pp0, pp1, t) {
const g_x = glMatrix.mat4.fromValues(
p0.x, 0, 0, 0,
p1.x, 0, 0, 0,
pp0.x, 0, 0, 0,
pp1.x, 0, 0, 0
);
const g_y = glMatrix.mat4.fromValues(
p0.y, 0, 0, 0,
p1.y, 0, 0, 0,
pp0.y, 0, 0, 0,
pp1.y, 0, 0, 0
);
const M = glMatrix.mat4.fromValues(
1, 0, 0, 0,
0, 0, 1, 0,
-3, 3, -2, -1,
2, -2, 1, 1
);
const T = glMatrix.mat4.fromValues(
1, t, Math.pow(t, 2), Math.pow(t, 3),
0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0
);
const r_x = glMatrix.mat4.create();
glMatrix.mat4.multiply(r_x, g_x, M);
glMatrix.mat4.multiply(r_x, r_x, T);
const r_y = glMatrix.mat4.create();
glMatrix.mat4.multiply(r_y, g_y, M);
glMatrix.mat4.multiply(r_y, r_y, T);
return {
x: r_x[0] / 10,
y: r_y[0] / 10
};
}
Demo