# Is there an explicit form for cubic Bézier curves?

(See edits at the bottom)

I'm trying to use Bézier curves as an animation tool. Here's an image of what I'm talking about:

Basically, the value axis can represent anything that can be animated (position, scaling, color, basically any numerical value). The Bézier curve is used to control the speed at which the value is changing as well as it start and ending value and time. In this graphic, the animated value would slowly accelerate to a constant speed, then decelerate and stop.

The problem is, that Bézier curve is defined with parametric equations.

$f_x(t):=(1-t)^3p_{1x} + 3t(1-t)^2p_{2x} + 3t^2(1-t)p_{3x} + t^3p_{4x}$

$f_y(t):=(1-t)^3p_{1y} + 3t(1-t)^2p_{2y} + 3t^2(1-t)p_{3y} + t^3p_{4y}$

What I need is a representation of that same Bézier curve, but defined as value = g(time), that is, y = g(x).

I've tried solving for t in the x equation and substituting it in the y equation, but that 3rd degree is giving me some difficulty. I also tried integrating the derivative of the Bézier curve (dy/dx) with respect to t, but no luck.

Any ideas?

Note : "Undefined" situations are avoided by preventing the tangent control points from going outside the hull horizontally, preventing any overlap in the time axis.

EDIT : I have found two possible solutions. One uses Decasteljau's algorithm to approximate the $s$ parameter from the $t$ parameter, $s$ being the parameter of the parametric curve and $t$ being the time parameter. Here (at the bottom).

The other, from what I can understand of it, recreates a third degree polynomial equation matching the curve by solving a system of linear equation. Here. I understand the idea, but I'm not sure of the implementation. Any help?

-
Just some checks: Are $p1x$ and $p1y$ the coordinates of a point $p_1$ (and similar for the others)? Then it seems like what you are looking for is an equation $y=g(x)$ that represents the curve, is that right? I ask that because you have $x(t)$ and $y(t)$ which seems to be your f(time). By the way, to get a subscript in $\LaTeX$, you use the underline: $x_1$ or $p_{2y}$ (brackets for more than one character, and you can right-click and pick Show Source to see how it was done.) –  Ross Millikan Mar 14 '11 at 3:10
@Ross, yes, exactly. –  subb Mar 14 '11 at 4:05
Then I don't have anything better than what Alex suggested. The implicit function theorem guarantees reasonable behavior for a short while, at least most of the time. –  Ross Millikan Mar 14 '11 at 4:16
Any reason why you are not using Hermite splines instead of Bézier curves for this? A Hermite spline is given in an explicit form; here it amounts to just setting $x = t$. –  Rahul Mar 14 '11 at 4:36
Just some unrelated interesting stuff: LINK 1, LINK 2, LINK 3 –  muntoo Mar 14 '11 at 4:38
show 3 more comments

## 6 Answers

Assuming the intended meaning of $p1x$, etc. was as Ross believed, you should be able to solve for t explicitly in either equation using the formula at http://en.wikipedia.org/wiki/Cubic_equation#General_formula_of_roots. Of course, this is a bulky solution and you would need to identify which solution is real (though there should be only 1 assuming that the curve can be represented as $y = g(x)$).

-
I gave some kind of a try using mathematica and the final solution for y=g(x) takes about 2 pages long. I've tried with some sample control points and complex numbers popped out, even though I chose the only solution for t without complex numbers. There's probably another way... –  subb Mar 14 '11 at 5:29
Well, since this is for a computer calculation, rounding errors are inevitable so there is no reason not to go with a close approximate solution (which would allow you to cut down on some bulk). Different values of $p_i$ will result in different roots being real or complex, and certain values will likely result in unpleasant behavior, which could cause problems if you are changing the values of $p_i$. I see no way to avoid inverting $f_x$, since as you said $dy/dx$ is a function of $t$. –  Alex Becker Mar 14 '11 at 5:44
add comment

Notice that if you happen to have $p_{1y}=0$, $p_{2y}=1/3$, $p_{3y}=2/3$ and $p_{4y}=1$, so that $f_y(t)=t$, then the graph you are after is actually of the inverse function of $f_x(t)$, which is going to be a mess and inevitable as complicated as the usual formula for the roots of a cubic polynomial.

That shows that the general formula necessarily has to be complicated. I doubt there is anything useful to be done...

-
add comment

Any implicit Cartesian equation you'll attempt to derive from the Bézier curve is necessarily complicated because the explicit solution for the cubic equation is complicated, as explained by previous posters; if you desperately need a $y=f(x)$ for manipulations, you're probably better off constructing a (piecewise) Hermite interpolant, which assumes you have an appropriate number of derivatives available in addition to function values.

For the cubic case, one only needs two triples $(x_i,y_i,y_i^\prime)$ and $(x_{i+1},y_{i+1},y_{i+1}^\prime)$ available; then, there is a unique cubic $p_3(x)$ that satisfies the conditions $p_3(x_i)=y_i$ and $p_3^\prime(x_i)=y_i^\prime$ (and similarly for the other triple). If, say, you have $y_i$ as position values and $y_i^\prime$ as velocity values, you're all set. If you additionally have second derivative values, you can construct a quintic, but since that sort is rarely needed/wanted, a cubic usually suffices.

Note that cubic splines are but a special case of cubic Hermite interpolation; the additional thing is that continuity conditions (the agreement of first and second derivative values at certain points) are implemented.

-
add comment

I tried the two solutions I've linked to the original question (Solution 1 and Solution 2). Here are my results.

Solution 1

The idea is to recreate the curve with a third degree polynomial, by matching the value at P1 and P4 and their respective slope. This polynomial can be solve using a system of linear equations. The only problem is that it's possible to create an infinite slope at P1 or P4 with the Bezier curve, which is impossible to recreate with the polynomial. I've also tried using a 5th degree polynomial (matching value, first derivative and second derivative) without success, because it has the same problem.

Solution 2

This solution is pretty simple, but a bit hacky. The idea is to use the De Casteljau algorithm to search for a t (parameter of the Bézier curve) that matches a given x variable (x-axis). The algorithm is simple :

1. Split the curve in half
2. Is the x of the split point is approximatively equal to the searched x? If yes, return t
3. Else, if the searched x is greater that the x of the split point, repeat the algorithm with the segment on the right, else on the left.

Once you have the t, you can obtain the y value using the Bézier function $f_y(t)$ in my original post.

So, yeah, working, but a bit hacky.

-
add comment

You're really looking for a cubic equation in one dimension (time).

$$y = u_0(1-x^3) + 3u_1(1-x^2)x + 3u_2(1-x)x^2 + u_3x^3$$

Is all you need.

Walking $t$ at even intervals (say in steps of 0.1) takes evenly spaced points along the parametric curve.

So, the answer to your question is really quite simple. The parametric bezier curve provides 2 variables as the output, with only 1 variable as the input. To control an animation in time like these, that's only a 1 dimensional situation. So consider $t$ as time, and drop one variable (say drop $x$). Your animation ease curve is controlled by the $y$ value:

Now as $t=0,0.1..1$, you have an animation parameter that starts slowly, moves at medium speed in the middle, and slows down at the end.

Examples

Setting $u_0=0$, $u_1=0.05$, $u_2=0.25$, $u_3=1$ gives an ease-in curve (slow start, fast end)

Setting $u_0=0$, $u_1=0.75$, $u_2=0.95$, $u_3=1$ gives an ease-out curve (fast start, slow end)

-
add comment

The basic required function is $y = 3x^2 - 2x^3$.

This is a smooth "ramp" that rises from $y=0$ at $x= 0$ to $y = 1$ at $x=1$.

You can then shift it and scale it to suite your needs.

This is a real-valued Bezier curve that has "control points" 0, 0, 1, 1.

-
add comment