Search code examples
javascriptcss-transitionsbeziercubic

Get x on Bezier curve given y


I have a Bezier curve: (0,0), (.25,.1), (.25,1), and (1,1).

This is graphically seen here: http://cubic-bezier.com/#.25,.1,.25,1

We see on the x axis is time.

This is my unknown. This is a unit cell. So I was wondering how can I get x when y is 0.5?

Thanks

I saw this topic: y coordinate for a given x cubic bezier

But it loops, I need to avoid something loops So I found this topic: Cubic bezier curves - get Y for given X

But I can't figure out how to solve a cubic polynomial in js :(


Solution

  • This is mathematically impossible unless you can guarantee that there will only be one y value per x value, which even on a unit rectangle you can't (for instance, {0,0},{1,0.6},{0,0.4},{1,1} will be rather interesting at the mid point!).

    We can solve this symbolically, as explained over on https://pomax.github.io/bezierinfo/#yforx, using Cardanos algorithm to find the roots of our x(t) function, but if you're going to do a lot of curve work, it might be faster to simply build a relatively small LUT and then approximate the result instead. For instance:

    var LUT_x = [], LUT_y = [], t, a, b, c, d;
    for(let i=0; i<100; i++) {
      t = i/100;
      a = (1-t)*(1-t)*(1-t);
      b = (1-t)*(1-t)*t;
      c = (1-t)*t*t;
      d = t*t*t;
      LUT_x.push( a*x1 + 3*b*x2 + 3*c*x3 + d*x4 );
      LUT_y.push( a*y1 + 3*b*y2 + 3*c*y3 + d*y4 );
    }
    

    Now if you want to look up a x value for some y value, you can run through LUT_y until you find your y value, or more realistically until you find two values at index i and i+1 such that your y value lies somewhere in between them, and you will immediately know the corresponding x value because it'll be at the same index in LUT_x.

    For nonexact matches with 2 indices i and i+1 you simply do a linear interpolation (i.e. y is at distance ... between i and i+1, and this at the same distance between i and i+1 for the x coordinates)

    (But of course: if you want precision, implement Cardano's algorithm or just copy-paste it from the Primer on Bezier curves, and compute the exact value)