Curves(曲线)

If moving everything along a straight line between two points is all we wanted to do, then this would be enough. However, in the real world, objects move in smooth curves and accelerate and decelerate smoothly. A curve can be represented by three or more control points. For most curves, there are more than three control points, two of which form the endpoints; the others define the shape of the curve. Consider the simple curve shown in Figure 4.14

The curve shown in Figure 4.14 has three control points, A, B, and C. A and C are theendpoints of the curve and B defines the shape of the curve. If we join points A and B with one line and points B and C together with another line, then we can interpolate along the two lines using a simple linear interpolation to find a new pair of points, D and E. Now, given these two points, we can join them with yet another line and interpolate along it to find a new point, P. As we vary our interpolation parameter, t, point P will move in a smooth curved path from A to D. Expressed mathematically, this is

Substituting for D and E and doing a little crunching, we come up with the following:(同样的对于D、E之间的插值，我们有如下式子:)

You should recognize this as a quadratic equation in t. The curve that it describes is known as a quadratic Bézier curve(你会发现，这个插值实际上就是二阶的贝塞尔曲线). We can actually implement this very easily in GLSL using the mix function, as all we’re doing is linearly interpolating (mixing) the results of two previous interpolations(我们在GLSL里面很容易去实现这一插值)

vec4 quadratic_bezier(vec4 A, vec4 B, vec4 C, float t)
{
vec4 D = mix(A, B, t); // D = A + t(B - A)
vec4 E = mix(B, C, t); // E = B + t(C - B)
vec4 P = mix(D, E, t); // P = D + t(E - D)
return P;
}
By adding a fourth control point as shown in Figure 4.15, we can increase the order by 1 and produce a cubic Bézier curve.

We now have four control points, A, B, C, and D. The process for constructing the curve is similar to that for the quadratic Bézier curve. We form a first line from A to B, a second line from B to C, and a third line from C to D. Interpolating along each of the three lines gives rise to three new points, E, F, and G. Using these three points, we form two more lines, one from E to F and another from F to G, interpolating along which gives rise to points H and I, between which we can interpolate to find our final point, P. Therefore, we have

If you think these equations look familiar, you’re right: Our points E, F, and G form a quadratic Bézier curve that we use to interpolate to our final point P. If we were to substitute the equations for E, F, and G into the equations for H and I, then substitute those into the equation for P, and crunch through the expansions, we would be left with a cubic equation with terms in t—hence the name cubic Bézier curve. Again, we can implement this simply and efficiently in terms of linear interpolations in GLSL using the mix function:

vec4 cubic_bezier(vec4 A, vec4 B, vec4 C, vec4 D, float t)
{
vec4 E = mix(A, B, t); // E = A + t(B - A)
vec4 F = mix(B, C, t); // F = B + t(C - B)
vec4 G = mix(C, D, t); // G = C + t(D – C)
vec4 H = mix(E, F, t); // H = E + t(F - E)
vec4 I = mix(F, G, t); // I = F + t(G - F)
vec4 P = mix(H, I, t); // P = H + t(I - H)
return P;
}
Just as the structure of the equations for a cubic Bézier curve “includes” the equations for a quadratic curve, so, too, does the code to implement them. In fact, we can layer these curves on top of each other, using the code for one to build the next

vec4 cubic_bezier(vec4 A, vec4 B, vec4 C, vec4 D, float t)
{
vec4 E = mix(A, B, t); // E = A + t(B - A)
vec4 F = mix(B, C, t); // F = B + t(C - B)
vec4 G = mix(C, D, t); // G = C + t(D - C)
}
Now that we see this pattern, we can take it further and produce even higher-order curves. For example, a quintic Bézier curve (one with five control points) can be implemented as

vec4 quintic_bezier(vec4 A, vec4 B, vec4 C, vec4 D, vec4 E, float t)
{
vec4 F = mix(A, B, t); // F = A + t(B - A)
vec4 G = mix(B, C, t); // G = B + t(C - B)
vec4 H = mix(C, D, t); // H = C + t(D - C)
vec4 I = mix(D, E, t); // I = D + t(E - D)
return cubic_bezier(F, G, H, I, t);
}
This layering could theoretically be applied over and over for any number of control points. However, in practice, curves with more than four control points are not commonly used. Rather, we use splines.