To compute tangent and normal vectors at a point on a Bézier curve, we must compute the first and second derivatives at that point. Fortunately, computing the derivatives at a point on a Bézier curve is easy.
Recall that the Bézier curve defined by n + 1 control points P_{0}, P_{1}, ..., P_{n} has the following equation:
where B_{n,i}(u) is defined as follows:
Since the control points are constants and independent of the variable u, computing the derivative curve C'(u) reduces to the computation of the derivatives of B_{n,i}(u)'s. With some simple algebraic manipulations, we have the following result for B^{'}_{n,i}(u):
Then, computing the derivative of the curve C(u) yields:
Let Q_{0} = n(P_{1} - P_{0}), Q_{1} = n(P_{2} - P_{1}), Q_{2} = n(P_{3} - P_{2}), ..., Q_{n-1} = n(P_{n} - P_{n-1}). The above equation reduces to the following:
Therefore, the derivative of C(u) is a Bézier curve of degree n - 1 defined by n control points n(P_{1} - P_{0}), n(P_{2} - P_{1}), n(P_{3} - P_{2}), ..., n(P_{n} - P_{n-1}). This derivative curve is usually referred to as the hodograph of the original Bézier curve. Note that P_{i+1} - P_{i} is the direction vector from P_{i} to P_{i+1} and n (P_{i+1} - P_{i}) is n times longer than the direction vector. Once the control points are known, the control points of its derivative curve can be obtained immediately. The left figure below shows a Bézier curve of degree 7 and the right figure shows its derivative which is a degree 6 Bézier curve.
That a Bézier curve being tangent to its first and last legs provides us with a technique for joining two or more Bézier curves together for designing a desired shape. Let the first curve C(u) be defined by m + 1 control points P_{0}, P_{1}, P_{2}, ..., P_{m}. Let the second curve D(u) be defined by n + 1 control points Q_{0}, Q_{1}, Q_{2}, ..., Q_{n}. If we want to join these two Bézier curves together, then P_{m} must be equal to Q_{0}. This guarantees a C^{0} continuous join. Recall that the first curve is tangent to its last leg and the second curve is tangent to its first leg. Consequently, to achieve a smooth transition, P_{m-1}, P_{m} = Q_{0}, and Q_{1} must be on the same line such that the directions from P_{m-1} to P_{m} and the direction from Q_{0} to Q_{1} are the same. This is shown below.
While joining two Bézier curves in this way looks smooth, it is still a C^{0} join and is not yet C^{1}. However, it is G^{1}, because they have the same tangent vector directions. To achieve C^{1} continuity, we have to make sure that the tangent vector at u = 1 of the first curve, C'(1), and the tangent vector at u = 0 of the second curve, D'(0), are identical. That is, the following must hold:
This relation states that to achieve C^{1} continuity at the joining point the ratio of the length of the last leg of the first curve (i.e., |p_{m} - p_{m-1}|) and the length of the first leg of the second curve (i.e., |q_{1} - q_{0}|) must be n/m. Since the degrees m and n are fixed, we can adjust the positions of p_{m-1} or q_{1} on the same line so that the above relation is satisfied.
The left figure below has two Bézier curves. The light color polyline defines a Bézier curve of degree 4 while the dark color polyline defines a Bézier curve of degree 5. Since the last leg of the first curve and the first leg of the second are not on the same line, the two curves are not joint smoothly. The right figure shows two Bézier curves that are tangent to a line at the joining point. However, they are not C^{1} continuous. The left curve is of degree 4, while the right curve is of degree 7. But, the ratio of the last leg of the left curve and the first leg of the second curve seems near 1 rather than 7/4=1.75. To achieve C^{1} continuity, we should increase (resp., decrease) the length of the last (resp. first) leg of the left (resp., right). However, they are G^{1} continuous.
There is one more interesting application of this tangency property. If we let the first and last control points be identical (i.e., P_{0} = P_{n}) and P_{1}, P_{0} and P_{n-1} collinear, the generated Bézier curve will be a closed one and is G^{1} continuous at the joining point as shown below. To achieve C^{1} continuous at P_{0}, we must have P_{1} - P_{0} = P_{n} - P_{n-1} (i.e., the first and last legs have the same length and P_{1}, P_{0} = P_{n}, P_{n-1} are collinear)
Note that although the above curve looks like an ellipse, it is not because this curve is of degree 6 and Bézier curves are polynomials which cannot represent circles and ellipses.
Thus, the derivative of a Bézier curve is the difference of two Bézier curves of degree n-1. For simplicity, let these two curves be C_{1}(u) and C_{2}(u):
From these definitions, we know that the first curve C_{1}(u) is defined by control points P_{1}, P_{2}, ..., P_{n}, that the second curve C_{2}(u) is defined by control points P_{0}, P_{1}, ..., P_{n-1}, and that the derivative is:
Therefore, theoretically, to compute the derivative of C(u) at a particular u, we can use de Casteljau's algorithm to compute C_{1}(u) and C_{2}(u). Then, computing their difference followed by multiplying by n yields C'(u). Therefore, the point on curve C(u) and its tangent vector C^{'}(u) can be computed at the same time with de Casteljau's algorithm.
Now let us apply de Casteljau's algorithm to compute C_{1}(u) and C_{2}(u). See the figure below. The left-most column has all the given control points. The point n0 gives the point C(u) on the curve, and the segment joining (n-1)0 and (n-1)1 is the last control polyline of the de Casteljau net. In fact, n0 lies in the segment of (n-1)0 and (n-1)1 and divides it in a ratio of u:1-u.
Since curve C_{1}(u) is defined by control points 01, 02, ..., 0n, using the above diagram we know that (n-1)1 is the point on curve C_{1}(u). Similarly, since C_{2}(u) is defined by control points 00, 01, ..., 0(n-1), using the above diagram we know that (n-1)0 is the point on curve C_{2}(u). Therefore, vector C_{1}(u)-C_{2}(u) is the vector from point (n-1)0 to point (n-1)1, and the derivative of C(u) is n times C_{1}(u)-C_{2}(u).
What does this mean? Since the line segment from (n-1)0 to (n-1)1 of the de Casteljau net has the same direction as the tangent vector at C(u), it is tangent to the curve at C(u)! In summary, we have
The last polyline, actually a line segment, of a de Casteljau net is tangent to the Bézier curve at C(u). |
The following figure shows an example. The point shown corresponds to u = 0.5. It is clear that the last line segment of a de Casteljau net is tangent to C(0.5).
Applying the derivative formula to the above Bézier curve yields the following, which gives the second derivative of the original Bézier curve:
After obtaining C'(u) and C''(u), the moving triad and curvature at C(u) can be computed easily. Higher derivatives can be found by recursively applying the formula of derivative.
To express higher derivative concisely, we shall use finite difference. Let us define D_{i}^{0} to be control point P_{i} for 0 <= i <= n. Then, we define the first level difference D_{i}^{1} to be the difference of the previous level:
Note that the first level difference has only n points, one less than the number of given control points. More precisely, the first level of difference is the following:
The second level difference is defined to be the difference of the first level points:
This second level difference has n-1 points. Repeating this procedure, we can define the k-th level difference as follows. The k-th level difference has n-k+1 point.
With these notation in hand, higher derivatives can be expressed concisely. First of all, let us rewrite C'(u) as follows, using the D_{i}^{1}'s:
Applying the derivative to C'(u) to compute C''(u) gives us a formula of C''(u) in D_{i}^{2}'s:
Do the same to C''(u) and we have a formula of C'''(u) in D_{i}^{3}'s:
Continue this process and we can compute the k-th derivative C^{[k]}(u) in D_{i}^{k}'s:
Therefore, to compute the k-th derivative of C(u) at a particular u, we first compute the D_{i}^{k}'s and apply de Casteljau's algorithm to compute the point corresponding to u on the Bézier curve defined by D_{i}^{k}'s. More precisely, we can arrange all D_{i}^{0}'s on column 0, assign the south-east and north-east arrows -1 and 1, respectively, to compute column 1 of D_{i}^{1}'s. Repeat this until we reach column k as shown below:
Finally, applying de Casteljau's algorithm to the points on column k with u and multiply the result by n(n-1)(n-2)...(n-k+1) gives us the vector of C^{[k]}(u)!