Converting Anim Editor Handles from Accel/Slope to XY?

Hi all,

I’m trying to use the Animation Editor to generate simple cubic bezier curves for an external application, however; the target app needs both the points and handles expressed in the same X,Y coordinates, similar to the below image.


(source: devmag.org.za/2011/04/05/bzier-c … -tutorial/)

Currently in the Animation Editor, points are already expressed in X, Y, but the handles are expressed as “inslope, inaccell, outslope, and outaccell” of their respective points.

The Graph COMP appears to be rendering the handles in a scaled and clamped fashion, not actually drawing them like the above image.

So question is probably more geared for Derivative: how is the Graph COMP drawing handles, and/or what’s the method for converting accell and slope to X,Y?

1 Like

Hey Phil,

I’ll have a closer look tomorrow, but does this link help:
moshplant.com/direct-or/bezier/lines.html

Cheers
Markus

Can someone help explain how the animation curves work in TD? I’m wrapping my head as to how to interpret “standard” (from my point of view, as an animator coming from after effects, c4d & web animation) cubic-bezier data into the TD keyframes. As the OP stated, it seems like the values are normalized and after digging through the doc’s I still can’t find any clarification on “inslope, inaccell…” etc.

For example, I’d like to take something like cubic-bezier(.99,.03,.47,.95) ([url]cubic-bezier.com) and understand how that translates that into a TD animation curve.

Is the issue that the cubic-bezier() function doesn’t exist in TD? (I see only separate calls for cubic() and bezier() from the drop down)

In the case of bezier() animation curves it uses some trig to convert inslope, inacceleration, invalue, outslope, outacceleration, outvalue into 4 vertices, to build a 2D bezier.
From this 2D bezier, it then extracts a unique value for each point in time (roughly a 1D function).

To avoid this conversion into a 1D function, you may consider using proper 3D Bezier curves (or 2D by keeping the Z component at zero), in geometry.

derivative.ca/wiki099/index. … zier_Class
derivative.ca/wiki099/index. … tSOP_Class

However, if you’re interested in working through the animation editor, I’ve extracted the pseudo code for the original conversion functions you’re looking for below.
Cheers,
Rob.

{
	// point 0  (endpoint)

	x[0] = inputTime;
	y[0] = inputValue;


	// point 3	 (endpoint)

	x[3] = outputTime;
	y[3] = outputValue;


	// point 1
	{

		sintheta = inputSlope / sqrtf(inputSlope*inputSlope + (float)1.);
		if( (inputSlope = fabs(inputSlope)) > 1.0 )
		{
			float one_over_m = 1.0 / inputSlope;
			costheta = one_over_m / sqrtf(one_over_m * one_over_m + 1);
		}
		else
			costheta = sqrtf((float)1. - sintheta*sintheta);

		a0 = fabs(inputAccel);
		dx = inputTime + a0*costheta;
		if (dx > outputTime)
		{
			dx = outputTime;
			a0 = (dx - inputTime) / costheta;
		}
		x[1] = dx;
		y[1] = inputValue + a0*sintheta;
	}
	

	// point 2
	{
		sintheta = outputSlope / sqrtf(outputSlope*outputSlope + (float)1.);
		if( (outputSlope = fabs(outputSlope)) > 1.0 )
		{
			float one_over_m = 1.0 / outputSlope;
			costheta = one_over_m / sqrtf(one_over_m * one_over_m + 1);
		}
		else
			costheta = sqrtf((float)1. - sintheta*sintheta);

		a3 = fabs(outputAccel);
		dx = outputTime - a3*costheta;
		if (dx < inputTime)
		{
			dx = inputTime;
			a3 = (outputTime - dx) / costheta;
		}
		x[2] = dx;
		y[2] = outputValue - a3*sintheta;
	}

}

Thank you for the detailed response. Using the references to the Bezier Class and ScriptSOP, I put together a simple script that does indeed give me the appropriate bezier-curve I’m looking for (in reference to: cubic-bezier.com/#.99,.03,.47,.95). I added parameters for controlling the X/Y of each tangent pair, omitting Z like you mentioned.

Two additional questions:
1— How do I use this curve in my animation? Previously I’d create an Animation Comp and set a 2D keyframe curve manually, then I’d hook that up to a Lookup CHOP driven by a custom slider or TimerCHOP to create a proper normalized output (that I’d remap via Math CHOP’s to my needs). Is there a way to send this curve to the Keyframe component or hook it up directly into the Lookup CHOP?

2— Back to my original question: Is there any default way I can create this cubic-bezier curve using just the Keyframe editor? If not, I’m planning on turning this into a tox component I can share… once I figure out how to use it, of course :slight_smile:
scriptSop_BezierCurve_wip.jpg

Hi.

1- It’s tricky. You’ll need to map this 2D object onto a timeline.
Different solutions may involve:

  1. Resample SOP → resample evenly along X
    (then each point is equidistant along the X axis)

  2. Ray SOP, where you cast a ray from the desired time upwards towards the curve.
    You’ll need to extend the curve, using extrude, to give it some thickness, to make sure the ray doesn’t skim past it.

  3. Some numerical approximation method, in python, using the Prim.eval(u,v) method on the Bezier on the Bezier to find out which u,v produce the target X (then read Y).


2- You’ll need to invert the pseudo code to calculate the in/out slope/value/acceleration for the Keyframe table values.

Either method could work, but Im leaning towards the first solution, keeping it as geometry, and using some SOPs.

I can expand further on them soon.

Okay, attached is a simple example, where I take an input curve (in this case a Bezier), then Resample evenly in 0.1 increments along X.

The result is fetched into both a table and a CHOP.

You can now treat X as time, to evaluate Y.
You may also want to use the second page of a Transform SOP options to normalize the geometry to units bounds.

Cheers,
Rob.
zz_bezier.3.toe (4.11 KB)