Hermite Curves

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.

Charles Hermite

 

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 .

dt = 1.0

dt = 0.5

dt = 0.25

dt = 0.1

dt = 0.01

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