0

I am trying to calculate the length of a quadratic Bezier curve. Found a solution and a formula to calculate the length of the entire curve in a "closed form" - without having to do numeric methods. The solution is covered at: quadratic Bezier curve length. The function is below:

function quadraticBezierLength(x1, y1, x2, y2, x3, y3) {
  let a, b, c, d, e, u, a1, e1, c1, d1, u1, v1x, v1y;

  v1x = x2 * 2;
  v1y = y2 * 2;
  d = x1 - v1x + x3;
  d1 = y1 - v1y + y3;
  e = v1x - 2 * x1;
  e1 = v1y - 2 * y1;
  c1 = a = 4 * (d * d + d1 * d1);
  c1 += b = 4 * (d * e + d1 * e1);
  c1 += c = e * e + e1 * e1;
  c1 = 2 * Math.sqrt(c1);
  a1 = 2 * a * (u = Math.sqrt(a));
  u1 = b / u;
  a = 4 * c * a - b * b;
  c = 2 * Math.sqrt(c);
  return (
    (a1 * c1 + u * b * (c1 - c) + a * Math.log((2 * u + u1 + c1) / (u1 + c))) /
    (4 * a1)
  );
}

It seems to be working correctly. I actually need L(t) rather than the length of the complete curve. It is another task. However, fortunately, someone solved it before me, and shared at length of a quadratic curve segment. I wrote a function based on this solution:

function quadraticBezierArcLength(t, x1, y1, x2, y2, x3, y3) {
  let a, b, c, d, e, e1, d1, v1x, v1y;

  v1x = x2 * 2;
  v1y = y2 * 2;
  d = x1 - v1x + x3;
  d1 = y1 - v1y + y3;
  e = v1x - 2 * x1;
  e1 = v1y - 2 * y1;
  a = 4 * (d * d + d1 * d1);
  b = 4 * (d * e + d1 * e1);
  c = e * e + e1 * e1;
  a = 4 * c * a - b * b;
  c = 2 * Math.sqrt(c);

  const bt = b / (2 * a),
    ct = c / a,
    ut = t + bt,
    k = ct - bt ** 2;

  return (
    (Math.sqrt(a) / 2) *
    (ut * Math.sqrt(ut ** 2 + k) -
      bt * Math.sqrt(bt ** 2 + k) +
      k *
        Math.log((ut + Math.sqrt(ut ** 2 + k)) / (bt + Math.sqrt(bt ** 2 + k))))
  );
}

If I am not mistaken, the implementation in code is correct. Yet, the length values are definitely wrong. The only time it returns what I expect is when t equals 0.

Is there an error in my quadraticBezierArcLength function, or the formula wrong? I want the length along the curve of a segment from the point with coordinates {x1, x2} to the point C(t). I would expect that when t === 1, the results of both functions are the same, at the very least.

Igor Shmukler
  • 1,742
  • 3
  • 15
  • 48
  • Not sure where that first function comes from: the post you link to shows you `L(t)` (giving the formula for the length of the curve from 0 to t), relying on a `u` substitution where `u = t + b`, so your function better include `t` as a function parameter, and it better calculate `u` by using `t`. Neither of those things happen in the first function. So: look at that post again, then take that convenient list of "which terms to compute, in which order", and then write the code that does that, followed by the code that then computes L =) – Mike 'Pomax' Kamermans Dec 01 '22 at 23:58
  • I linked two posts. The second post, actually also links the first - https://malczak.info/blog/quadratic-bezier-curve-length I did not understand the rest of your comment, sorry. There are two different functions, one calculates the length of the curve and needs no `t`, the second calculates the length of the segment from start to C(t) and requires the `t`. What is unclear? – Igor Shmukler Dec 02 '22 at 00:31
  • The part where neither link shows the code you're showing, they show "real" maths, so where did those functions come from? If you follow the recipe from the SO post you linked to, you should arrive at a function that looks rather different from what you're showing? – Mike 'Pomax' Kamermans Dec 02 '22 at 05:19
  • 1
    Does this answer your question? [Calculate the length of a segment of a quadratic bezier](https://stackoverflow.com/questions/11854907/calculate-the-length-of-a-segment-of-a-quadratic-bezier) – Spektre Dec 02 '22 at 08:57
  • @Mike'Pomax'Kamermans the way you phrase things, makes it rather difficult to understand for me. I found formulas at the links I mentioned. Please try to repackage your thoughts. Thank you for trying to help. It is probably my English, which is a second language. I understand separate words, yet complete sentences escape me. – Igor Shmukler Dec 02 '22 at 09:03

1 Answers1

1

You seem to have added two unnecessary lines to the calculation. Here's a fiddle where I have commented out those two lines, along with the function copied from the original answer.

  //a = 4 * c * a - b * b;
  //c = 2 * Math.sqrt(c);

The original answer also used the absolute function, which you have removed.

aptriangle
  • 1,395
  • 1
  • 9
  • 11