See also: same question on Math.SE

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

But what about quadratic, cubic, or n-degree Bezier curves?

(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.)

  • 1
    \$\begingroup\$ You should reword the question to refer to the length of the curve, that is a much more straightforward (and searchable) term. \$\endgroup\$
    – Sparr
    Nov 28 '10 at 11:34
  • \$\begingroup\$ 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 \$\endgroup\$
    – Tor Valamo
    Nov 28 '10 at 17:27
  • 2
    \$\begingroup\$ @Tor I did (yesterday), but I've been told it's very complicated, and hence unpractical. [ math.stackexchange.com/q/12186/2736 ] \$\endgroup\$ Nov 28 '10 at 21:08
  • \$\begingroup\$ 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? \$\endgroup\$
    – 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.

  • \$\begingroup\$ 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. \$\endgroup\$ 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.

  • 5
    \$\begingroup\$ This looks like something you'd draw on a blackboard in a movie to show how much of a genius someone is. \$\endgroup\$
    – Bemmu
    Aug 11 '20 at 16:17

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

    while (!parts.isEmpty()) {
        BezierCurve curve = parts.pop();
        if (distanceToBaseline(curve) < epsilon) {
            lines.add(new Line(curve.get(0), curve.get(1)));
        } else {

    return lines.toArray(new Line[0]);
  • \$\begingroup\$ 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. \$\endgroup\$ Sep 21 '15 at 0:31
  • \$\begingroup\$ 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. \$\endgroup\$ 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)));
  • \$\begingroup\$ Given the number of transcendental functions it is presumably much faster to calculate it using a non-closed form. \$\endgroup\$
    – Timmmm
    Mar 28 '20 at 18:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.