Tuesday, July 25, 2006

Animation and layout on paths

I finished the code to correctly map transformations along arbitrary paths (that includes bezier curves). It's extremely nice. The list of features that can be implemented on top of it is quite extensive. A two very obvious examples are animations along a path (as defined in SVG) and text layouting on arbitrary curves.

For example take a look at the following screencast (of course it's really smooth in reality but our screencasting software still has a long way to go, although I've been pretty nicely surprised this time). In this demo you can see a South Park character head (in this case it's mine) animated along a bezier curve with me manipulating the curve in real time.

So now to the math because it's rather neat. Moving along a path would be trivial if not that we have bezier curves in our paths. So the only tricky part is figuring out the transformation necessary to transform coordinate system suitably for arbitrary points on a bezier curve (that plus we need to find the length of the curve itself for which algorithm I could describe in a separate blog).

The parametric form of cubic bezier curve has the following form:
. In this case we need two algorithms to solve all our problems:

  • Nearest point on a curve - to correctly compute t on arbitrary positions within the curve

  • Tangent (or normal) vector to a point on the bezier curve - to compute our transformation given that the curve will be our attachment surface

The first one is described in detail in Graphics Gems 1. For the second all you have to do is take the derivative of the parametric equation. After simplification you should end up with:

Now we can compute the change in t by substituting the variables with the components of our control points. The vector that we get can be used to compute the slope of a line tangent to the curve at a given point. The last thing we need to do is compute the transformation matrix needed to transform our object. We do that by first translating the object to the point at the given t (we already have t and we get the point by substituting in the original equation) and then rotating the object by atan(slope of a tangent line) (this is assuming that we're transforming with regards to the horizontal axis). Extra points for doing all that with absolute minimal number of operations ;)

Or.. you could use Qt and we'll do all that for you.

No comments: