1

I created a 4-point bezier curve. I knew the total bezier curve length using this link. And I knew the length from start point.

I want to know how to get a time value from bezier curve and a point. I found a similar question and divided the bezier curve into 1000 pieces; but it isn't a good solution.

How can I get t value?

Community
  • 1
  • 1
  • 2
    What exactly do you mean by "time value"? – Spencer Wieczorek Nov 21 '14 at 04:06
  • if you get the total Bezier curve length using the link you provided, it is also an estimate as it will break the curve into 'STEPS' straight-line segments and compute the total length from these straight-line segments. So, using similar way to find the 't' value corresponding to a certain length from start point is not too bad of a solution for you. – fang Nov 21 '14 at 17:05
  • @SpencerWieczorek informal interpretation of the control variable for Bezier curves, since it's always `t` in literature. – Mike 'Pomax' Kamermans Nov 21 '14 at 21:53
  • possible duplicate of [Get x on Bezier curve given y](http://stackoverflow.com/questions/26373607/get-x-on-bezier-curve-given-y) – Mike 'Pomax' Kamermans Nov 21 '14 at 21:54
  • 1
    "Get x on Bezier curve given y" is about finding the 't' value from given y value. This post is about finding the 't' value from given length value. The former does not involve integration of squared first derivative and the latter does. – fang Nov 22 '14 at 02:03

1 Answers1

2

Note that for a cubic Bezier curve, there is no "one t value for each coordinate". Cubic Bezier can self-intersect, so you can find multiple t values for a single coordinate. There's two ways to do this: approximately or symbolically.

If you want an approximate answer (like what you're already doing for the length computation), simply construct a lookup table of coordinates-for-t:

buildLUT(a,b,c,d) {
  for(t=0; t<=1; t+=0.01) {
    LUTx[t*100] = getCoordinate(t, a.x,b.x,c.x,d.x);
    LUTy[t*100] = getCoordinate(t, a.y,b.y,c.y,d.y);
  }
}

And write an extra function for reverse lookups, or to build the reverse LUTs:

findTforCoordinate(x, y) {
  found = []
  for(i=0, len=LUTx.length; i<len; i++) {
    _x = LUTx[i], _y = LUTy[i]
    if(x==_x && y==_y) { found.push(i/len); }
  }
  return found
}

where a,b,c,d are your curve's control points. Since this is approximate, you're not looking for "t value for coordinate" but "closest t value to coordinate". It won't be perfect.

What WILL be perfect is finding all possible t values for the x and y coordinate components, then finding the one or two t values out of the set of possible six that approach generates that are the same between the x and y solutions. You can do this by using Cardano's approach, which is explain in another stackoverflow question here: Cubic Bezier reverse GetPoint equation: float for Vector <=> Vector for float

Community
  • 1
  • 1
Mike 'Pomax' Kamermans
  • 49,297
  • 16
  • 112
  • 153