Tween bezier curves

Hey guys,

I’m wondering if there’s a way to tween between start and end state of a bezier curve? I may import these curves from say Illustrator. Looking for a any place to read up or examples.

Thanks a lot!

I’ve done quite a bit of work with bezier curves, and after a bit of research I found them to be easier to work with, understand, and manipulate than you might expect.

This is a code snippet that I pulled from one of my apps to find a point on a bezier curve:

float x = powf(1 - t, 3) * origin.x + 3.0f * powf(1 - t, 2) * t * control1.x + 3.0f * (1 - t) * t * t * control2.x + t * t * t * destination.x;
float y = powf(1 - t, 3) * origin.y + 3.0f * powf(1 - t, 2) * t * control1.y + 3.0f * (1 - t) * t * t * control2.y + t * t * t * destination.y;

Origin is the start point of the curve, control1 is the handle that extends from origin.
Destination is the end point of the curve, control2 is the handle that extends from destination.
t is the amount of interpolation between the start and end points, between 0 and 1

You could use your update function to update a elapsed time counter, and divide this by the the duration to find t. So for example:

float duration = 3;
elapsedTime += dt;
t = elapsedTime / duration;

When working with curves mathematically rather than in a graphic vector editing program, the main thing to get your head round is adjusting your thinking. When working graphically you tend to conceptualise a path as a set of points, and each point has two handles. When working mathematically, you need to think of each segment of the path as having a start point with a handle, and an end point with a handle. So those ‘two’ handles on each point on the curve actually belong to different bezier curves.

2 Likes

@SteveB - so awesome! I wonder if there is a lerp function along a bezier curve?

The problem I’m trying to solve is that I have a curve that’s a frown and another instance of same curve that’s a smile. Now, I want to animate from frown to smile. Any ideas where to start on this one?

Thanks a lot!

If you want to interpolate along a bezier curve, to move an object along a bezier curve path, that’s not too tricky. You just need to increase the value of t over time in the example above.

Regarding morphing from one curve shape to another, that can be easy or tricky, depending on how complex your curve is. If it’s a very basic curve for your smile/frown, you should be able to simply animate the control points (or handles, whatever you call them) over time a redraw the curve.

So starting from a smile:

p1++++++                              ++++++p2
 .      ++++++                  ++++++     .
  .           ++++++      ++++++          .
   .                ++++++               .
   cp1                                cp2

Animate the control points to make a frown:

   cp1                                cp2
   .                ++++++               .
  .           ++++++      ++++++          .
 .      ++++++                  ++++++     .
p1++++++                              ++++++p2

If it’s a more complex path made from several bezier curves, then the only way I’ve really managed to do it in the past is to split the path into many points, and then animate the points to their corresponding positions in the new shape. The points are then drawn with straight lines, but if they are close enough together they will still form a smooth curve.

I actually have a project that does exactly that if you want to take a look:

It’s for iOS and written in Objective C, but it shouldn’t be too much trouble to port to C++. The code for the actual bezier morphing is fairly tidy, but the supporting demo code is a horrible mess which I never got round to cleaning up, so don’t judge too harshly!

I’m sure there should be a more performant way of animating the control points and splitting the paths to be able animate complex shapes. I did have some success in trying to implement that in a separate branch, but could never get it robust enough. I think I’d reached the limit of my math ability there!