December 17, 2008 I posted an article on how to draw the smooth curve through the set of 2D points with Bezier drawing primitives. Yesterday I got a question on how to draw a closed curve in the same manner. Indeed, there is a difference to open-ended curve.

# Equations

Note: to make a sequence of individual Bezier curves to be a spline we should calculate Bezier control points so that the spline curve has two continuous derivatives at the knot points.

Bezier curve at the single interval is expressed as

B(t)=(1-t)^{3}P_{0}+3(1-t)^{2}tP_{1}+3(1-t)t^{2}P_{2}+t^{3}P_{3}

where t is in [0,1] and

1. P_{0} – first knot point

2. P_{1} – first control point (at first knot)

3. P_{2} – second control point (at second knot)

4. P_{3} – second knot point

First derivative is:

B’(t) = -3 (1 – t)^{2 }P_{0 }+ 3 (3 t^{2 }– 4t + 1) P_{1 }+ 3 (2t – 3t^{2}) P_{2 }+ 3t^{2 }P_{3}

Second derivative is:

B’’(t) = 6 (1 – t) P_{0 }+ 3 (6t – 4) P_{1 }+ 3 (2 – 6t) P_{2}+ 6 t P_{3}

Let’s consider piece-wise Bezier curve on the interval with n (n > 2) points P_{i}_{ }(0,..,n-1) and n subintervals S_{i}_{ }(0,..,n-1).

S_{i }= (P_{i}, P_{i+1}) for (i=0,..,n-2)

S_{n-1 }= (P_{n-1}, P_{0}) for (i=n-1)

Bezier curve at S_{i} (i=0,..,n-2) will be

B_{i}(t) = (1 – t)^{3 }P_{i }+ 3 (1-t)^{2 }t P1_{i }+ 3 (1-t) t^{2 }P2_{i+1 }+ t^{3 }P_{i+1}; (i=0,..,n-2)

and the closing Bezier curve at S_{n}_{-1}

B_{i}(t) = (1 – t)^{3 }P_{n}_{-1 }+ 3 (1-t)^{2 }t P1_{n}_{-1 }+ 3 (1-t) t^{2 }P2_{0 }+ t^{3 }P_{0}

First derivative at S_{i} (i=0,..,n-2) will be

B’_{i}(t) = -3 (1-t)^{2 }P_{i }+ 3(3t^{2 }– 4t + 1) P1_{i }+ 3(2t – 3t^{2}) P2_{i+1}+3t^{2 }P_{i+1}

and at S_{n-1}

B’_{n-1}(t) = -3 (1-t)^{2 }P_{n-1 }+ 3(3t^{2 }– 4t + 1) P1_{n-1 }+ 3(2t – 3t^{2}) P2_{0}+3t^{2 }P_{0}

First derivative continuity condition gives:

P1_{i }+ P2_{i} = 2 P_{i} (i=0,..,n-1) (1)

Second derivative at S_{i} (i=0,..,n-2) will be

B’’_{i} (t) = 6 (1-t) P_{i }+6 (3t – 2) P1_{i }+ 6 (1 – 3t) P2_{i+1 }+ 6t P_{i+1}

and at S_{n-1}

B’’_{n-1} (t) = 6 (1-t) P_{n-1 }+6 (3t – 2) P1_{n-1 }+ 6 (1 – 3t) P2_{0 }+ 6t P_{0}

Second derivative continuity condition gives:

at P_{0}

2 P1_{0 }+ P1_{n-1} = 2 P2_{0 }+ P2_{1 (2.1)}

at P_{i} (i=1,..,n-2)

2 P1_{i }+ P1_{i-1 }= 2 P2_{i} + P2_{i+1 (2.2)}

and at P_{n-1}

2 P1_{n-1} + P1_{n-2 }= 2 P2_{n-1 }+ P2_{0 (2.3)}

Excluding P2 form (2.1-3) with (1) we get the set of equations for P1

4 P1_{0 }+ P1_{1 }+ P1_{n-1} = 4 P_{0 }+ 2 P_{1} for P_{0}

P1_{i-1 }+ 4 P1_{i }+ P1_{i+1 }= 4 P_{i }+ 2 P_{i+1} for P_{i} (i=1,..,n-2)

P1_{0} + P1_{n-2 }+ 4 P1_{n-1 }= 4 P_{n}_{-1 }+ 2 P_{0} for P_{n-1}

We got the system with the matrix which looks like

4 1 0 0 … 0 1

1 4 1 0 … 0 0

0 1 4 1 … 0 0

……………

1 0 0 0 … 1 4

It’s so-called "cyclic" system which can be solved as effectively as a tridiagonal system with the trick which you can find in the "Numerical Recipes", for example.

After P1’s found it’s easy to get P2’s from (1).

# Code and sample

You can download the code and sample application here:

http://cid-39d56f0c7a08d703.skydrive.live.com/embedrow.aspx/.Public/ClosedBezierSpline

It is Visual Studio 2008 solution targeted to .NET 3.5. It contains WPF Windows Application project designed to demonstrate sampled circle drawn with Bezier spline above.

Although I compiled this code in C# 3.0 I don’t see why it can’t be used without any modification in C# 2.0 and even in C# 1.0 if you remove keyword “static” from the class declarations.

Would you please check the message titled "A mistake in the last equation which causes a strange behavior (corrected)" at http://www.codeproject.com/KB/graphics/BezierSpline.aspx