Friday, September 7, 2012

A cubic spline example

The example at left is taken from wikipedia and I'd like to talk about it. The original code for the graphics contain the curve as
<path d="M 70,420 C 150,70 700,145 650,420" style="fill: none; stroke-width: 2.5; stroke: black;"></path>
The details of the syntax are defined in the SVG Path specification.
Pointxy
P070420
P115070
P2700145
P3650420

We can evaluate this with the De Casteljau's algorithm:

Q0[t_] := P0 * (1 - t) + P1 *t
Q1[t_] := P1 * (1 - t) + P2 *t
Q2[t_] := P2 * (1 - t) + P3 *t

R0[t_] := Q0[t] * (1 - t) + Q1[t] * t
R1[t_] := Q1[t] * (1 - t) + Q2[t] * t

S0[t_] := R0[t] * (1 - t) + R1[t] * t

and plot S0[t] over the range {t,0,1}.  In the wikipedia graphics below S0 is shown as B.

Construction of a cubic Bézier curve
Animation of a cubic Bézier curve, t in [0,1]

The name of them though is cubic spline.  So let's get it into cubic form.  These control points are in fact the coefficients of Bernstein polynomial of degree 3. 

b_{0,3}[t] = (1 - t)^3
b_{1,3}[t] = 3t(1 - t)^2
b_{2,3}[t] = 3t^2(1 - t)
b_{3,3}[t] = t^3

and the spline segment is:

B[t] = b_{0,3}[t] * P0 +  b_{1,3}[t] * P1 + b_{2,3}[t] * P2 +  b_{3,3}[t] * P3

this can be expanded into separate x and y components:

x[t] = b_{0,3}[t] * P0_x + b_{1,3}[t] * P1_x + b_{2,3}[t] * P2_x + b_{3,3}[t] * P3_x
y[t] = b_{0,3}[t] * P0_y + b_{1,3}[t] * P1_y + b_{2,3}[t] * P2_y + b_{3,3}[t] * P3_y

When we expand into standard polynomial form we get:

x[t_]:= a_x + t * b_x + t^2 * c_x + t^3 *d_x
y[t_]:= a_y + t * b_y + t^2 * c_y + t^3 *d_y

where

a_x = P0_x
b_x = 3* P1_x - 3 P0_x
c_x = 3*P2_x - 6 *P1_x + 3*P0_x
d_x = P3_x - 3 * P2_x + 3*P1_x - P0_x


and similarly

a_y = P0_y
b_y = 3* P1_y - 3 P0_y
c_y = 3*P2_y - 6 *P1_y + 3*P0_y
d_y = P3_y - 3 * P2_y + 3*P1_y - P0_y

No comments:

Post a Comment