Bézier Curves

The Bézier curve is a popular way to draw curves in graphic editors such as GIMP and Inkscape. A curve of degree n is defined using n+1 points, where the first and last are the start and end points of the curve, respectively, and the rest are control points.
For example:
fff
The curve in the image above is a cubic Bézier curve. It has start and end points (filled with blue) and two control points (with no fill).
Each control point is attached by a straight line to a start or an end point, for a reason:

  • The control points allows the user to control the curve intuitively.
  • The straight line between the start(or end) point and its control point is tangent to the curve at the start(or end) point.

The Definition

A Bézier curve is defined as the collection of points that are the result of the function
B(t) for every t in [0,1].
A linear Bézier is simply a straight line between to points P0 and P1. The function is:
(1 – t)BP0 + tBP1

For n>1, Be P0, P1 … Pn the list of the curve’s points. Then the curve’s function is defined as
BP0P1…Pn(t) = (t – 1)BP0P1…Pn-1(t) + tBP1P2…Pn(t)

Or, in its explicit form:

(Not a very precise definition because 00 is not a number, so use the value 1 instead.)

This equation can be proved easily using the Pascal triangle.
From the explicit definition, you can see that the translation is done by adding the same coordinates to which of the curves start, end and control points.
because:
Rotations and translations are done by a transform matrix. So, if T is a transform matrix:
TBP1,P2,…Pn = BTP1,TP2,…TPn

About Tangents

Now, in a Bézier curve, BP0P1…Pn(t), The line P0 – P1 is tangent to the curve at point P0, and Pn – Pn-1 is tangent to the curve at point Pn

To prove this we’ll have to show that the derivative of a Bézier curve of degree n at the start and end points is a non-zero scalar multiplied by the difference between P1 and P0, and between Pn and Pn-1.
That scalar is n.

For n=1;
BP0,P1 = (1 – t)P0 + tP1
Let’s derive:
B’P0,P1 = -P0 + P1

Good!

Let’s assume it’s correct for n, and prove for n+1
BP0,P1…,Pn+1(t) = (1 – t)BP0,P1…,Pn(t) + tBP1,P2…,Pn+1(t)
Let’s derive:
B’P0,P1…,Pn+1(t) = -BP0,P1…,Pn(t) + (1-t)B’P0,P1…,Pn(t) + BP1,P2…,Pn+1(t) + tB’P1,P2…,Pn+1(t)

Now, to get the tangent to the curve at p0, let;s assign t=0:
B’P0,P1…,Pn+1(0) = -BP0,P1…,Pn(0) + B’P0,P1…,Pn(0) + BP1,P2…,Pn+1(0) =
= – P0 + n(P1 – P0) + P1 = (n+1)(P1 – P0)

Good!
Now, to get the tangent to the curve at p0, let;s assign t=1:
B’P0,P1…,Pn+1(1) = -BP0,P1…,Pn(1) + BP1,P2…,Pn+1(1) + B’P1,P2…,Pn+1(1) =
= – Pn + Pn+1 + n(Pn+1 – Pn) + P1 = (n+1)(Pn+1 – Pn)

QED

SVG supports Bézier curves of up to the third degree. A path consisting of such curves are good approximations of shapes provided that you have enough points.

Advertisements

Tower Of Hanoi Without Recursion

If you’ve taken courses in computer sciences, you probably know the Tower Of Hanoi algorithm. The task is to move a tower of discs from the source rod the the destination using an auxiliary rod. Each disc should be placed on a bigger one all the time.
The solution is to move all discs on top of the biggest one to the auxiliary rod, then move the biggest disc to the destination rod and then move all the rest to the destination (according to the rules of course, and one disc at a time).

The Recursive (and Naive) Solution

The function that moves n discs from src to dst using aux looks like:

function moveDiscs(n, src, dst, aux){
  if (n > 1)
    moveDiscs(n-1, src, aux, dst);
  print("Move from " + src + " to " + dst);
  if (n>1)
    moveDiscs(n-1, aux, dst, src);
}

We’ll use that function later to prove that the non-recursive algorithm does the same.

The Iterative Solution

A naive iterative solution is to use a binary search and find for each move of a disc, the parameters passed to moveDiscs when n=1. This is crazy! We don’t want time complexity o(n) just to move the first disc.
Let’s look at a better solution:
Repeat the 3 steps in table 1 until all discs are moved, depending on the value of n:

Table 1:

If n is even If n is odd
perform a legal move between src and aux perform a legal move between src and dst
perform a legal move between src and dst perform a legal move between src and aux
perform a legal move between aux and dst perform a legal move between aux and dst

Note: perform no more step after all discs have been moved to the destination.

Proof

For n = 1, just move a disc from src to dst
For n = 2, take a look at the recursive function.
For n ≥ 3:
The total number of moves is 2n – 1
Let’s assume our algorithm works for any natural number n and prove for n+1:

Steps 1 thru 2n – 1

Let’s look at the first call to moveDiscs inside itself:

moveDiscs(n-1, src, aux, dst); // Remember that we prove for `n+1`, so `n-1` in the function actually means `n`

Let’s look how it is performed:
Per our assumption, the sequence for steps 1 thru 2n – 1 is

If n is even If n is odd
perform a legal move between src and dst perform a legal move between src and aux
perform a legal move between src and aux perform a legal move between src and dst
perform a legal move between aux and dst perform a legal move between aux and dst

Because if n is odd, n+1 is even and vice versa, we get that the first steps are performed correctly by the iterative algorithm

Step 2n

This is when we move a disc from src to dst
If n is even, 2n≡1 mod 3, thus it matches step 1 in Table 1 for odd n+1.
If n is odd, 2n≡2 mod 3, thus it matches step 2 in Table 1 for even n+1.
Thus, our iterative algorithm is still correct.

Steps 2n + 1 Thru 2n+1 – 1

Those steps are performed by the second call to moveDiscs inside itself:

moveDiscs(n-1, aux, dst, src); // Remember that we prove for `n+1`, so `n-1` in the function actually means `n`
If n is even If n is odd
perform a legal move between aux and src
(step 2 for odd n+1)
perform a legal move between aux and dst
(step 3 for even n+1)
perform a legal move between aux and dst
(step 3 for odd n+1)
perform a legal move between src and aux
(step 1 for even n+1)
perform a legal move between src and dst
(step 1 for odd n+1)
perform a legal move between src and dst step 2 for even n+1)

In this table we see the steps that follow step 2n.
Thus, the algorithm works correctly for the last part, and thus our whole algorithm is correct.

You can now watch a working Hanoi animation here.