# How to discretize a BezierCurve?

Bug introduced in version 10.0 and fixed in version 12.0
DiscretizeGraphics is new in 10.0.

I need to create a discretized region from a BezierCurve.

This is one of my curves:

pt = {{93.2759, 277.0452}, {90.6249,
273.3252}, {79.7499, 255.70020000000002}, {76.9999,
250.70020000000002}, {74.2499,
245.70020000000002}, {70.2499,
237.70020000000002}, {69.9999, 235.32520000000002}};
g = Graphics[{BezierCurve[pt]}];


DiscretizeGraphics creates points which are close to the curve, but clearly not on it.

Show[g, DiscretizeGraphics[g]]


This is a magnified portion of the result:

There is a small but consistent difference between the discretized version and the original graphics.

What is going on?

Which one is wrong? The BezierCurve rendering or the discretization? If it's the discretization, then:

What workarounds are there for the problem? Could I sample the points on the curve using BezierFunction? If yes, how exactly? BezierFunction[points] and BezierCurve[points] don't seem to represent the same curve.

My ultimate aim is to discretize some objects imported from a PDF. One of them is a closed JoinedCurve (or FilledCurve) and I need to use it to filter certain points which are inside the region. The other one (shown above) is a non-closed JoinedCurve, consisting of BezierCurve[..., SplineDegree -> 3] and Line[...] segments. DiscretizeGraphics does not work on JoinedCurve/FilledCurve.

BezierFunction and BezierCurve do not give the same result in the following test:

ParametricPlot[BezierFunction[pt][x], {x, 0, 1}, Epilog -> {BezierCurve[pt]}]


Again there is a small but consistent difference. Why?

Here's a different point set where BezierCurve and BezierFunction give very different results. How can I use BezierFunction to reproduce the same thing I see with BezierCurve?

pt = {{85.6699, 270.639}, {81.4849, 265.53}, {72.1939, 247.082}, {69.5059,
244.27}, {66.8189, 241.46}, {65.3979, 237.927}, {64.1759,
236.649}, {62.9539, 235.372}, {75.0969, 229.142}, {76.6069,
228.676}, {78.1179, 228.21}, {75.1319, 234.644}, {75.2469,
237.147}, {75.3609, 239.65}, {80.5859, 252.02}, {82.9949,
256.076}, {85.4049, 260.131}, {92.1679, 270.779}, {93.5919,
274.19}, {95.0159, 277.6}, {92.9719, 279.555}, {85.6699, 270.639}}


Posted a related question on Wolfram Community.

• You can export a bspline as pdf then import the pdf. See my answer here. Commented Oct 29, 2015 at 11:42
• The other possibility is to use ParametricPlot[] + BezierFunction[] to create a Line[] primitive that should now be easily discretized. Can you give an example where BezierCurve[] doesn't seem to give the same result as my proposal? Commented Oct 29, 2015 at 11:44
• With respect to JoinedCurve[]/FilledCurve[]: if memory serves Simon Woods has a post somewhere on how to split those into components. Commented Oct 29, 2015 at 11:45
• @J.M. The same example from this post doesn't. ParametricPlot[BezierFunction[pt][x], {x, 0, 1}, Epilog -> {BezierCurve[pt]}], where pt are the points from above. Commented Oct 29, 2015 at 11:46
• @Silvia If I export/import to/from PDF, I still get a JoinedCurve with a BezierCurve inside (after decoding using GeometricFunctionsDecodeJoinedCurve), so I'm back to the same problem. There's also an additional problem: the coordinates have all changed. I need to do measurements on these objects (imported form a single PDF), so they must all be in the same coordinate system. Commented Oct 29, 2015 at 11:50

This was solved with help from Shutao Tang, J.M., Sander Huisman and Eric Rimbey.

1. Why do BezierFunction[pt] and BezierCurve[pt] not agree?

Because BezierCurve uses SplineDegree -> 3 by default and BezierFunction always uses degree Length[pt] - 1 (not settable).

2. Why does DiscretizeGraphics give a bad result?

Because it appears to use (the equivalent of) BezierFunction[pt] internally. This is a bug. Witness:

pt = {{0, 0}, {0, 1}, {1, 1}, {1, 0}, {2, 0}};
g = Graphics[{BezierCurve[pt]}];
Show[g,
ParametricPlot[BezierFunction[pt][x], {x, 0, 1},
PlotStyle -> Directive[AbsoluteThickness[3], Yellow]],
DiscretizeGraphics[g]
]


3. How can we reproduce a BezierCurve using BezierFunction?

By stitching together several degree-3 (or less) BezierFunctions:

funs = BezierFunction /@ Partition[pt, 4, 3, {1, 1}, {}];
Show[Table[ParametricPlot[f[x], {x, 0, 1}], {f, funs}], PlotRange -> All]


DiscretizeGraphics can then be applied to this.

• do you get an error when you enter the line funs = BezierFunction /@ Partition[pt, 4, 3, {1, 1}, {}];? I find that the Partition command creates a list whose last element only has one point. I can only get it to work without error if I add [[;;-2]] after the Partition` Commented Dec 11, 2015 at 11:12