# 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

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

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

(a^2·(q^2 - 2·q·r + r^2) + 2·a·(r - q)·(b·(p - r) + c·(q - p)) + (b·(p - r) + c·(q - p))^2)·LN((√(a^2 - 2·a·b + b^2 + p^2 - 2·p·q + q^2)·√(a^2 + 2·a·(c - 2·b) + 4·b^2 - 4·b·c + c^2 + (p - 2·q + r)^2) + a^2 + a·(c - 3·b) + 2·b^2 - b·c + (p - q)·(p - 2·q + r))/(√(a^2 + 2·a·(c - 2·b) + 4·b^2 - 4·b·c + c^2 + (p - 2·q + r)^2)·√(b^2 - 2·b·c + c^2 + q^2 - 2·q·r + r^2) + a·(b - c) - 2·b^2 + 3·b·c - c^2 + (p - 2·q + r)·(q - r)))/(a^2 + 2·a·(c - 2·b) + 4·b^2 - 4·b·c + c^2 + (p - 2·q + r)^2)^(3/2) + (√(a^2 - 2·a·b + b^2 + p^2 - 2·p·q + q^2)·(a^2 + a·(c - 3·b) + 2·b^2 - b·c + (p - q)·(p - 2·q + r)) - √(b^2 - 2·b·c + c^2 + q^2 - 2·q·r + r^2)·(a·(b - c) - 2·b^2 + 3·b·c - c^2 + (p - 2·q + r)·(q - r)))/(a^2 + 2·a·(c - 2·b) + 4·b^2 - 4·b·c + c^2 + (p - 2·q + r)^2)

Where LN is the natural logarithm, and ^ denotes power and √ the square root.

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.

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)));