Bezier curve arc length

How can I find the arclength of a Bezier curve? For example, a linear Bezier curve has the length:

length = sqrt(pow(x[1] - x[0], 2) + pow(y[1] - y[0], 2));


(My goal was to estimate a sampling resolution beforehand, so I don't have to waste time checking if the next point is touching the previous point.)

• You should reword the question to refer to the length of the curve, that is a much more straightforward (and searchable) term. – Sparr Nov 28 '10 at 11:34
• i suggest posting this on math, i'm sure some clever face over there will give you the answer in one of them clever web fonts :p – Tor Valamo Nov 28 '10 at 17:27
• @Tor I did (yesterday), but I've been told it's very complicated, and hence unpractical. [ math.stackexchange.com/q/12186/2736 ] – Mateen Ulhaq Nov 28 '10 at 21:08
• Supposedly clothoid curves/splines are an alternative to beziers, and have closed-form arclength expressions, but I don't know much about this yet. (Trying to generate equal-distance points along a curve.) Catenaries also have closed-form arc length expressions? – endolith Feb 21 '14 at 16:43

A simple way for cubic Beziers is to split the curve into N segments and sum the segments' lengths.

However, as soon as you need the length of only part of the curve (e.g. up to a point 30% of the length along), arc-length parameterization will come into play. I posted a fairly long answer on one of my own questions about Béziers, with simple sample code.

• I'm doing this for the LEGO Mindstorms NXT, which has a really weak processor (48Mhz), so I need as much speed as possible. I'll take the dividing approach to conserve some speed, and get it accurate enough (for "non-realtime" rendering). I also have a option in which you can set the value of 1.0/t (called resolution), so that's for "realtime" (which is at best 10fps on the slow NXT). Every iteration, t += resolution, and a new point/line is drawn. Anyways, thanks for the idea. – Mateen Ulhaq Nov 29 '10 at 0:58

Arc lengths for Bezier curves are only closed form for linear and quadratic ones. For cubics, it is not guaranteed to have a closed solution. The reason is arc length is defined by a radical integral, for which has a closed for only 2nd degree polynomials.

Just for reference: The length of a quadratic Bezier for the points (a,p) (b,q) and (c,r) is

$$\frac{(a^2(q^2 - 2qr + r^2) + 2a(r - q)(b(p - r) + c(q - p)) + (b(p- r) + c(q - p))^2)\ln{\frac{\sqrt{a^2 - 2ab + b^2 + p^2 - 2pq + q^2} \sqrt{a^2 + 2a(c - 2b) + 4b^2 - 4bc + c^2 + (p - 2q + r)^2} + a^2 + a(c - 3b) + 2b^2 - bc + (p - q)(p - 2q + r) }{\sqrt{a^2 + 2a(c - 2b) + 4b^2 - 4bc + c^2 + (p - 2q + r)^2} \sqrt{b^2 - 2bc + c^2 + q^2 - 2qr + r^2} + a(b - c) - 2b^2 + 3bc - c^2 + (p - 2q + r)(q - r)}}}{a^2 + 2a(c - 2b) + 4b^2 - 4bc + c^2 + (p - 2q + r)^2}^\frac{3}{2} + \frac{\sqrt{(a^2 - 2ab + b^2 + p^2 - 2pq + q^2) (a^2 + a(c - 3b) + 2b^2 - bc + (p - q)(p - 2q + r)) - \sqrt{b^2 - 2bc + c^2 + q^2 - 2qr + r^2} (a(b - c) - 2b^2 + 3bc - c^2 + (p - 2q + r)(q - r))}}{a^2 + 2a(c - 2b) + 4b^2 - 4bc + c^2 + (p - 2q + r)^2}$$

Hence, it should be easier and cheaper approximate the arc by some other rule, like a polygon or an integration scheme like Simpson's rule, because square roots the LN are expensive operations.

• This looks like something you'd draw on a blackboard in a movie to show how much of a genius someone is. – Bemmu 2 days ago

While I am d'accord with the answers you got already, I want to add a simple but powerful approximation mechanism which you can use for any degree Bézier curves: You continually subdivide the curve using de Casteljau subdivision until the maximum distance of the control points of a sub-curve to the sub-curve's baseline is below some constant epsilon. In that case the sub-curve can be approximated by its baseline.

In fact, I believe this is the approach usually taken when a graphics subsystem has to draw a Bézier curve. But do not quote me on this, I do not have references at hand at the moment.

In practice it will look like this: (except the language is irrelevant)

public static Line[] toLineStrip(BezierCurve bezierCurve, double epsilon) {
ArrayList<Line> lines = new ArrayList<Line>();

Stack<BezierCurve> parts = new Stack<BezierCurve>();
parts.push(bezierCurve);

while (!parts.isEmpty()) {
BezierCurve curve = parts.pop();
if (distanceToBaseline(curve) < epsilon) {
} else {
}
}

return lines.toArray(new Line[0]);
}

• While this is a good approach, I've heard of numerical instability at high-order Bezier curves, which require another idea: splitting the the higher-order curves into smaller cubic curves. – Mateen Ulhaq Sep 21 '15 at 0:31
• Also, if the end goal is an accurate estimate, it might be a good idea to approximate with quadratics instead of lines to ensure that we don't understate our estimate at locations of high curvature. – Mateen Ulhaq Sep 21 '15 at 0:33

I worked out the closed form expression of length for a 3 point Bezier (below). I've not attempted to work out a closed form for 4+ points. This would most likely be difficult or complicated to represent and handle. However, a numerical approximation technique such as a Runge-Kutta integration algorithm would work quite well by integrating using the arc length formula. My Q&A on RK45 on MSE may help with RK45 implementation.

Here is some Java code for the arc length of a 3 point Bezier, with points a,b, and c.

    v.x = 2*(b.x - a.x);
v.y = 2*(b.y - a.y);
w.x = c.x - 2*b.x + a.x;
w.y = c.y - 2*b.y + a.y;

uu = 4*(w.x*w.x + w.y*w.y);

if(uu < 0.00001)
{
return (float) Math.sqrt((c.x - a.x)*(c.x - a.x) + (c.y - a.y)*(c.y - a.y));
}

vv = 4*(v.x*w.x + v.y*w.y);
ww = v.x*v.x + v.y*v.y;

t1 = (float) (2*Math.sqrt(uu*(uu + vv + ww)));
t2 = 2*uu+vv;
t3 = vv*vv - 4*uu*ww;
t4 = (float) (2*Math.sqrt(uu*ww));

return (float) ((t1*t2 - t3*Math.log(t2+t1) -(vv*t4 - t3*Math.log(vv+t4))) / (8*Math.pow(uu, 1.5)));

• Given the number of transcendental functions it is presumably much faster to calculate it using a non-closed form. – Timmmm Mar 28 at 18:17