Calculate spline values

Although it is not strictly an opengl related problem, but it is math related and my knowledge is limited:

In my application I use keyframe animations and all animatable paramaters can have animation curves (Bezier splines to be exact, although the type of curve is not relevant here). These curves have time values in frames as x coordinates and parameter values as y coordinates. I would like to know how can I calculate an y value if I know the x (time) and of course the coordinates of the control points of the spline.

All algorithms I found on the net calculate x(t),y(t) coordinates where t can change from 0 to 1. But I cannot know the value of t at a particular moment, instead I know x(t) and need to calculate y(t).

Can anyone help me with this?

Thanks.

It seems you need to be able to back-calculate t from x(t), since principally the only common dependance between x(t) and y(t) is t. Sorry I can’t help you more than that.

Or make sure you know t at all times of course…

The problem is I can’t know t. All animation curves in all animation programs work like this, so there must be a - relatively easy - solution.

The only thing I did not find it on the net.

So you’re plotting y(t) with the x axis representing time. For starters, I’d say just set x(t) = t and you have simple y(x) function.

Is the reason you’re using x(t) is so you can vary the speed of the curve over time or the placement of the control points in time? I’m just guessing.

Using Bezier, that’s probably not going to look nice, since you have so little speed and continuity control.

If you want the y value of your graph to represent amplitude of some parameter, then simply use y(t) alone and let time be constant. In the case of bezier splies, you’d then have control points in the x direction at some regular interval, but get smoothing on the y value.

The better way to do this, IMO, is with better controlled splines. Even a basic b-spline uses a knot vector, which allows you to effectively set the time param for each control point. But a simple uniform or NURBS may do the trick.

A Kochanek-Bartels spline is interpolated and gives you tension, control, and bias at each of those controls, which is pretty good for animation control (simulates ease-in, etc…).

So for the more generalized splines, you’re still only computing a one-dimensional spline y(t) but allowing the time markers for each control to slide in x by adjusting the knot parameter for each.

It’s been a while, but that’s how I remember doing it. :slight_smile:

By animation curves I meant I need to calculate the changes of values like TranslateX or RotateZ over time.

I chose two types of splines. Cardinal and Bezier. Cardinal has the advantage of going through all keyframe points but with a single tension value shared by all. Bezier I use for additional control. Nothing fancy, just ease out (for P1) and ease in (for P4). P2 and P3 control points (which are not keyframes and are not on the curve) are set automatically by the program according to these two values.

Don’t you think the calculation would be quite off if I assumed x(t)=t?

Why do you think Kochanek-Bartels would be better considering x(t)=t would still be incorrect?

(BTW Basically I use Cardinal and Bezier because these two are very easy to draw with GDI+ :slight_smile: )

Thanks.

I mention Kochanek-Bartels because it’s used a lot in animation systems, generally where you see tension, control, and bias knobs per control point. It’s not critical.

I guess the key thing, apart from the knots trick, which I’m still not remembering completely, is that you’re really drawing one-dimensional values. The amount of translateX is the amplitude of your spline (y in your case). The time parameter is being graphed as x.

It sounds like you’re trying to draw 2D splines, without a solid reverse mapping from x to t. The problem is that a 2D spline can do “bad” things in space – looping back on itself. Just consider the case where X values are set as { 0, 1, 0.5, 1, 2 … } – the function will loop back on itself, meaning there is more than one answer for y(x). That can happen with interpolating splines even if you limit X to be monotonically increasing. And typically, the only empirical way to solve this is to iterate the curve – not a great solution.

Anyway, if you treat the curve as one-dimensional and make y the sole function of t, the downside is that the time values are generally evenly spaced (x=t) for curves like bezier. But the y value should still be correct and the function should at least be monotonic and easy to solve.

I don’t let the user draw a spline and I made sure there is no way for any curve to turn back in time. I think this is what you mean by looping back on itself.

If you are right about x=t not being a problem that would make me very happy because that is definitely easy to solve.

I plotted two curves. One where I calculated t from x(t) with a ‘brute force’ approach (it involves a lot of calculations, including two cube roots), and another one with the same control points but with the assumption that t=x(t).

Unfortunately they are quite different, and the latter one can hardly be influenced by moving the P2,P3 control points, therefore I don’t think it can be used.