# How to calculate the control points of a Bézier curve?

To plot a BezierCurve in Mathematica, I need control points. But, I do not know the control points; I only know the points through which the Bézier curve passes. Take a simple example:

A Bézier curve goes through the 4 points (0,0), (2,1), (4,3) and (6,1). Find the two control points.

How would I go about finding the two control points in this example? The solution of this simple example will give me a clue on how to solve the general case.

• Why do you insist on BezierCurve instead of Interpolation? Sep 5, 2016 at 10:53
• What is your code? Because BezierCurve[pts] doesn't go through these four points. Sep 5, 2016 at 11:06
• Because what I really want to do is to draw a Bezier curve containing hundred of points. I know the points that the curve passes through but in order to plot it I need the control points instead. If I can do it for a simple case of 4 points I will figure out how to do it for hundred of points. Sep 5, 2016 at 11:06

Here is my approach:

pts = {{0, 0}, {2, 1}, {4, 3}, {6, 1}};
paras = FoldList[Plus, 0, Normalize[(Norm /@ Differences[pts]), Total]] // N
mat = Outer[BernsteinBasis[3, #1, #2] &, Range[0, 3], paras] // Transpose;
ctrlpts = LinearSolve[mat, pts]
(* {{0., 0.}, {2.71043, -0.262717}, {3.94236, 6.32778}, {6., 1.}} *)

Graphics[{BezierCurve[ctrlpts], PointSize[Medium], Red, Point[pts]}]


### Comparison with Interpolation[]

To show that the results of the Bézier curve interpolant and the built-in Interpolation[] are vastly different, I will use the following data:

pts1 = {{-1, 0}, {2, 1}, {4, 4}, {6, -3}};
mat1 = Outer[BernsteinBasis[3, #1, #2] &, Range[0, 3],
FoldList[Plus, 0.0,
Normalize[(Norm /@ Differences[pts1]), Total]]] // Transpose;

f = Interpolation[pts1];
Show[Plot[f[x], {x, -1, 6}],
Graphics[{BezierCurve[LinearSolve[mat1, pts1]],
PointSize[Medium], Red, Point[pts1]}],
PlotRange -> {Automatic, {-3, 6}}]


• Is the slight difference with Interpolation[] expected? Sep 5, 2016 at 11:13
• @Feyre Of course, they use the different algorithms(basis function). I think the Interpolation[] uses the classical Largrange interpolation strategy, while for the Bezier curve, it uses the Bernstein basis.
– xyz
Sep 5, 2016 at 11:20
• I'm sure you could find an example where the Interpolation result is vastly different. It might be worthwhile to show the comparison in the answer. Sep 5, 2016 at 12:25
• The difference is only because you used chord length instead of the abscissas in setting up the linear system for the control points. Sep 3, 2017 at 5:40
• @J.M. is right : the visual difference between the 2 curves disappears when one replace FoldList[balh blah blah ...] by Rescale[First /@ pts1] in the code above. Nevertheless it is possible that the curves are mathematically different, for example because the default method used by Interpolation is "Hermite" instead of "Spline". Apr 1, 2018 at 22:18

There's no need to resort to chord length parametrization as was done in the other answer for this simple interpolation problem.

pts = {{0, 0}, {2, 1}, {4, 3}, {6, 1}};
{xt, yt} = Transpose[pts];
cp = LinearSolve[Outer[BernsteinBasis[3, #2, #1] &, Rescale[xt], Range[0, 3]], yt]
{0, -7/6, 20/3, 1}

Graphics[{{Directive[AbsoluteThickness[2], ColorData[97, 1]],
BezierCurve[Transpose[{xt, cp}]]},
{Directive[AbsolutePointSize[6], ColorData[97, 2]], Point[pts]}}]


An explanation for the following two results is left as an exercise for the interested reader:

if = Interpolation[pts];
Plot[if[x], {x, 0, 6},
Epilog -> {Directive[AbsoluteThickness[2], ColorData[97, 2]],
BezierCurve[Transpose[{xt, cp}]]},
PlotStyle -> AbsoluteThickness[6]]


Plot[if[x] - cp.BernsteinBasis[3, Range[0, 3], Rescale[x, MinMax[xt]]],
{x, 0, 6}, Evaluated -> True, PlotRange -> All]