参考 : http://cubic.org/docs/hermite.htm
Introduction
Hermite curves are very easy to calculate but also very powerful. They are used to smoothly interpolate between key-points (like object movement in keyframe animation or camera control). Understanding the mathematical background of hermite curves will help you to understand the entire family of splines. Maybe you have some experience with 3D programming and have already used them without knowing that (the so called kb-splines, curves with control over tension, continuity and bias are just a special form of the hermite curves).
The Math
To keep it simple we first start with some simple stuff. We also only talk about 2-dimensional curves here. If you need a 3D curve just do with the z-coordinate what you do with y or x. Hermite curves work in in any number of dimensions.
To calculate a hermite curve you need the following vectors:
- P1: the startpoint of the curve
- T1: the tangent (e.g. direction and speed) to how the curve leaves the startpoint
- P2: he endpoint of the curve
- T2: the tangent (e.g. direction and speed) to how the curves meets the endpoint
These 4 vectors are simply multiplied with 4 hermite basis functions and added together.
h1(s) = 2s^3 - 3s^2 + 1 h2(s) = -2s^3 + 3s^2 h3(s) = s^3 - 2s^2 + s h4(s) = s^3 - s^2
Below are the 4 graphs of the 4 functions (from left to right: h1, h2, h3, h4).
(all graphs except the 4th have been plotted from 0,0 to 1,1)
Take a closer look at functions h1 and h2:
- h1 starts at 1 and goes slowly to 0.
- h2 starts at 0 and goes slowly to 1.
Now multiply the startpoint with h1 and the endpoint with h2. Let s go from 0 to 1 to interpolate between start and endpoint. h3 and h4 are applied to the tangents in the same manner. They make sure that the curve bends in the desired direction at the start and endpoint.
The Math in Matrix Form
All this stuff can be expessed with some vector and matrix algebra. I think the matrix-form is much easier to understand.
Vector S: The interpolation-point and it's powers up to 3: Vector C: The parameters of our hermite curve: Matrix h: The matrix form of the 4 hermite polynomials: | s^3 | | P1 | | 2 -2 1 1 | S = | s^2 | C = | P2 | h = | -3 3 -2 -1 | | s^1 | | T1 | | 0 0 1 0 | | 1 | | T2 | | 1 0 0 0 |
To calculate a point on the curve you build the Vector S, multiply it with the matrix h and then multiply with C.
P = S * h * C
A little side-note: Bezier-Curves
This matrix-form is valid for all cubic polynomial curves. The only thing that changes is the polynomial matrix. For example, if you want to draw a Bezier curve instead of hermites you might use this matrix:
| -1 3 -3 1 | b = | 3 -6 3 0 | | -3 3 0 0 | | 1 0 0 0 |
I wrote a separate page about bezier curves.
Some Pseudocode
Sure, this C-style pseudo-code won't compile. C doesn't come with a power function, and unless you wrote yourself a vector-class any compiler would generate hundreds of errors and make you feel like an idiot. I think it's better to present this code in a more abstract form.
moveto (P1); // move pen to startpoint for (int t=0; t < steps; t++) { float s = (float)t / (float)steps; // scale s to go from 0 to 1 float h1 = 2s^3 - 3s^2 + 1; // calculate basis function 1 float h2 = -2s^3 + 3s^2; // calculate basis function 2 float h3 = s^3 - 2*s^2 + s; // calculate basis function 3 float h4 = s^3 - s^2; // calculate basis function 4 vector p = h1*P1 + // multiply and sum all funtions h2*P2 + // together to build the interpolated h3*T1 + // point along the curve. h4*T2; lineto (p) // draw to calculated point on the curve }