# What is the mathematical basis for F-Curves?

The Blender user's manual says:

Although F-curves are very similar to Bézier Curves, there are some important differences.

One of these differences is the fact that an F-curve doesn't allow a property to have more than one value at any given time. Blender's F-curves might take the keyframes and handles in the following image and produce the curve shown in the image:

However, a normal cubic Bézier curve with the same endpoints and handles would actually produce the following curve:

This curve contains a loop and is unsuitable as an F-curve.

So what is the mathematical basis for F-curves? More importantly, can you direct me to any scholarly articles that describe this type of modified Bézier curve? (or at least some good search terms for me to research)

• If blender didnt use the F-curve method, to draw "f-curves" like Justin mentioned, then how it is draws the curve in the graph editor correctly (if it is correct) with the given handles in the first place? Its possible that the f-curve method is correctly implemented in the graph editor ui, but not in blender? Feb 14 '17 at 12:58

After some digging through the Blender source code, I found the answer.

Short answer: They're just Bézier curves.

Long answer: They're normal Bézier curves with certain restrictions placed on the positions of the handles (the red circles). If the first handle is to the left of the second handle, as in the following image, then the curve is evaluated as a normal Bézier curve:

This guarantees that the curve will not turn back on itself.

However, if the handles cross (the first handle is to the right of the second handle), their positions need to be adjusted to avoid loops. The file fcurve.c (blender-2.77a\source\blender\blenkernel\intern\fcurve.c) gives the answer on line 2199:

/* adjust handles so that they don't overlap (forming a loop) */
correct_bezpart(v1, v2, v3, v4);


On line 1830, the correct_bezpart() function begins. The function finds the width of each handle and the width between the two keyframes. If the combined width of the two handles is greater than the width between the two keyframes, then the two handles are scaled down so that they don't cross each other, but their relative lengths are preserved. The original handles are used for drawing to the graph editor, but the scaled down versions are used for generating the curve, a plain-old cubic Bézier curve.

Here's an example F-Curve before correction. These handles are not used to create the actual curve; they're just drawn to the screen in Blender's graph editor:

Here's the same curve, but with corrected handles. These handles are not seen in the graph editor, but are the ones actually used to create the curve. If you want to pull out your ruler, you'll see that neither the lengths of each handle relative to each other, nor the angle of the handles were changed.

If you're not convinced, I invite you to look at fcurve.c and see for yourself. Overlapping handles are detected on lines 2188-2190. The actual handle correction takes place on lines 1830-1866.

As far as why they're called "F-Curves", your guess is as good as mine. My guess is that the 'F' stands for 'function', meaning that, like a math function, each x-value maps to exactly one y-value (A Bézier curve is indeed a function, except that an (x, y) pair is a function of t).

Whether this method is the brainchild of Blender developers or was the result of some third party is still a mystery to me. The answer to that question, in my opinion, is more valuable than the method itself.

It's right under your nose ;-) They are a member of the "Bezier Spline" family called an "F-curve," shortened from "Ferguson's Parametric Cubic Curves."

The F-curve is actually a direct derivative of the Catmull-Rom Spline (names you should recognize from other CGI algorithms). As stated in the introductory research an f-curve:

"attempts to fix the tangents at certain control points to be the average of the slopes of the two line segments of the control polygon adjacent to each control point. The matrix equation is then just a simple result of matrix algebra."

So, an f-curve is specifically designed to be simple, an average, and to have only one solution for any given point.

The Blender Manual says:

Although F-curves are very similar to Bezier Curves, there are some important differences.

This paper describes them in the context of CAD and CGI: http://www2.mat.dtu.dk/people/J.Gravesen/cagd/cagd.pdf

...but it surprises me that I can't find anywhere that 'Ferguson Curves' are called 'f-curves,' though that seems the most likely case.

• Maybe I'm missing something, but where in that paper does it say that the curve will only have one solution for any given point? May 11 '16 at 22:46
• @Justin It maps the control points to a cubic polynomial function en.wikipedia.org/wiki/Function_%28mathematics%29 May 12 '16 at 8:29
• It's quite possible for Catmull-Rom splines to have loops (see figure 2(b) in this paper for instance). In any case, animation curves allow the user to edit the tangents, so they aren't Catmull-Rom splines in general. May 12 '16 at 8:50
• @NathanReed I thought that was the difference between Catmull-Rom Splines and F-Curves?
– Matt
May 12 '16 at 13:00
• Well, the bit you quoted explicitly says the tangents are not editable, since they're fixed based on the locations of adjoining control points. That's exactly the definition of a Catmull-Rom spline. I'm unable to tell from the page you linked if there is any difference between "Ferguson splines" and Catmull-Rom splines; the text seems to use the names interchangeably. In any case I doubt if the term "F-curve" has anything at all to do with "Ferguson splines", unless you have a source that says so? IMO it's more likely F stands for frame, as in keyframing. May 12 '16 at 18:33

In 3D animation tools I've used, the key difference is that animation curves as shown in the graph editor are not actually 2D Bézier splines. They're 1D splines, parameterized by time (plotted along the X axis in the graph editor).

When you use splines to create curves in 2D or 3D, the spline has a parameter t that runs from 0 to 1 along its length, and the curve's XY or XYZ position is a function of t. This allows the spline to be oriented in any direction, and it can form loops because there is nothing preventing the curve from turning around and going "backward" in XY space as t increases.

With animation curves, t is (proportional to) time, and whatever channel is being keyed is a function of t. When you see the curves in the graph editor, they are not being rendered as 2D splines with XY being functions of t; instead, the value of t is based on the X axis position (corresponding to time), and the Y position is the output of the spline at that parameter value. So, animation channels are effectively 1D splines, graphed in the standard high-school algebra way, with Y as a function of X.

That explains why you can't make them loop "back in time": it's because time is an input to the spline and not an output. Compare this to 2D splines, where XY are both outputs, and the input parameter isn't being explicitly graphed.

Also note that you can easily animate an object to move along a looping spline such as the one you showed in your example, but when you view its curves in the graph editor, you'll see no loops there!

• What do you mean when you say "t is (proportional to) time"? May 13 '16 at 16:59
• @Justin I mean animation is done by increasing the value of t from 0 to 1 over a period of time. May 13 '16 at 17:46
• Sorry to be so nit-picky, but t (the input to the Bézier function) is not exactly proportional to time. Depending on the shape of the curve's control polygon, the parameterization of t could be squashed to one side of the curve or the other. You actually have to do some root finding to find the t value that corresponds to the desired time value. May 13 '16 at 18:25
• @Justin Hmm. If you've looked at the source, I believe you, but that seems very strange to me. AFAIK, in 3D animation tools splines are usually directly parameterized by time, so adjusting the parameterization allows you to control the speed the object moves. I'm not sure what is gained by having time be decoupled from the parameterization. May 13 '16 at 18:39