# A problem about recursion formula of de Casteljau algorithm

I use Mathematica to implement the de Casteljau algorithm

$$\vec{P}_{k,i}(u_0)=(1-u_0)\vec{P}_{k-1,i}(u_0)+u_0\vec{P}_{k-1,i+1}(u_0)$$

The graphics that de Casteljau algorithm generated as follows:

### My trial

(*The recursion formula*)
P[k_, i_, u0_] :=
(1 - u0) P[k - 1, i, u0] + u0 P[k - 1, i + 1, u0]
(*Initial values*)
P[0, 0, 2/5] = {0, 0};
P[0, 1, 2/5] = {2, 4};
P[0, 2, 2/5] = {4, 5};
P[0, 3, 2/5] = {6, 0};

ptsData = Table[P[k, i, 2/5], {k, 0, 3}, {i, 0, 3 - k}];
pts = {{0, 0}, {2, 4}, {4, 5}, {6, 0}};
Graphics[
Join[Point /@ ptsData, Line /@ ptsData, {Red, BezierCurve[pts]}]]


It works well.

So I packed these codes to a function deCasteljau[]

deCasteljau[pts_, u_] :=
Module[{p, ptsdata, n},
n = Length@pts - 1;
Table[p[0, j, u], {j, 0, n}] = pts;
p[k_, i_, u0_] :=(1 - u0) p[k - 1, i, u0] + u0 p[k - 1, i + 1, u0];
ptsdata = Table[p[k, i, u], {k, 0, n}, {i, 0, n - k}];

Graphics[
Join[Point /@ ptsdata, Line /@ ptsdata, {Red, BezierCurve[pts]}]]
]


However, it failed.

deCasteljau[{{0, 0}, {2, 4}, {4, 5}, {6, 0}}, 2/5]


I felt that the main question is the recursion formula p[k_, i_, u0_] :=(1 - u0) p[k - 1, i, u0] + u0 p[k - 1, i + 1, u0]; But I cannot deal with it by myself smoothly.

### Question:

How to revise it?(Or how to avoid using the recursion formula. Namely, using Mathematica construction to replace it)

### Edit

Thanks for kale help

When I input

 ?j

 Globalj


In general, the variable j in construction Table[p[0, j, u], {j, 0, n}] should be local.

Set has attributes HoldFirst. So when we evaluate a=2 (aka Set[a,2]), a is held until the rhs is evaluated.

In your example, the issue is setting your initial points with Table[p[0, j, u], {j, 0, n}] = pts;. We can add Evaluate and get along with our business. This forces the Table command to evaluate first before proceeding with Set.

deCasteljau[pts_, u_] := Module[{p, ptsdata, n}, n = Length@pts - 1;
Evaluate[Table[p[0, j, u], {j, 0, n}]] = pts;
p[k_, i_, u0_] := (1 - u0) p[k - 1, i, u0] + u0 p[k - 1, i + 1, u0];
ptsdata = Table[p[k, i, u], {k, 0, n}, {i, 0, n - k}];
Graphics[
Join[Point /@ ptsdata, Line /@ ptsdata, {Red, BezierCurve[pts]}]]
]

deCasteljau[{{0, 0}, {2, 4}, {4, 5}, {6, 0}}, 2/5]


• +1, Could you tell me why j in Evaluate[Table[p[0, j, u], {j, 0, n}]] = pts; is Global, not local
– xyz
Oct 1, 2014 at 3:04
• @Tangshutao It's not Global. It's localized inside of the Table function. I'm definitely not an expert in this but it appears the presence of j is made known, but no values are assigned. Table effectively uses Block so even if j had a global value assigned, the Table construct would still work as desired.
– kale
Oct 1, 2014 at 14:17
• The syntax colorof j is black when j has a value outsize
– xyz
Oct 1, 2014 at 14:38
• @Tangshutao But the Table construct still works, meaning (IMO) it's a bug with the syntax coloring engine.
– kale
Oct 1, 2014 at 15:07
• So @kale I use the P[0, #, u] & /@ Range[0, n] to replace it.
– xyz
Oct 1, 2014 at 15:09

Although I cannot understand why j in Evaluate[Table[p[0, j, u], {j, 0, n}]] = pts is Local, I use P[0, #, u] & /@ Range[0, n] to avoid using Table[p[0, j, u], {j, 0, n}]

With the help of kale, I improve my function deCasteljauPlot[] as below:

deCasteljauPlot[pts : {{_, _} ..}, u_?NumericQ, opts : OptionsPattern[Plot]] :=
Module[{P, ptsCoordi, n},
n = Length@pts - 1;
Evaluate[P[0, #, u] & /@ Range[0, n]] = pts;
(*recursion formula*)
P[k_, i_, u0_] := (1 - u0) P[k - 1, i, u0] + u0 P[k - 1, i + 1, u0];
(*generate the coordinates of points*)
ptsCoords = Table[P[k, i, u], {k, 0, n}, {i, 0, n - k}];
Graphics[
Join[
{PointSize[.012], Red}, Point /@ ptsCoords, {Black},
Line /@ ptsCoords, {Red, BezierCurve[pts]}],
(*generate the names of points*)
Epilog ->
Text @@@
Join[
{Table[Style[Subscript["P", i], 12, Blue], {i, 0, n}],
# + {.2, .2} & /@pts},
{Flatten@
Table[Style[Subscript["P", k, i], 12, Purple],
{k, 1, n}, {i,0, n - k}],
# + {.2, .2} & /@ Flatten[Rest@ptsCoordi, 1]}], opts]
]


Test

 deCasteljauPlot[{{0, 0}, {2, 4}, {4, 5}, {6, 0}}, 2/5,
PlotRange -> {{-1, 9}, {-1, 6}}, ImageSize -> 500]


Or we can Manipulate to look the process

Manipulate[
deCasteljauPlot[
{{0, 0}, {2, 4}, {4, 5}, {6, 0}}, u,
PlotRange -> {{-1, 7}, {-1, 6}}, ImageSize -> 400],
{{u, .2}, 0, 1}
]
`