Page 1 of 1

reverse-engineering linear() and ease()?

Posted: October 10th, 2019, 1:51 pm
by pablohotsauce
A while ago, I tried reverse-engineering AE's native linear() function, basically trying to recreate it from scratch. I was trying to do some auto-proximity animations in Blender, on a big array of 3D objects. I couldn't figure out the exact math + logic though, so my version didn't work exactly like I wanted it to.

Does anyone think they can reverse-engineer linear()? Or does anyone know of some JS libraries that include a replica? I'm sure it's only a few lines. Is there a generic term for what this function does? (Proportion calculation or sth?)

I'm guessing ease() is just extra stuff on top of linear(), involving an exponential transfer function.

Re: reverse-engineering linear() and ease()?

Posted: October 21st, 2019, 12:34 am
by pablohotsauce
Figured it out a while ago. According to StackOverflow, this type of function is a variation on what's called linear interpolation. My reverse-engineered version of AE's variation is below, in basic JavaScript. To apply eases, find some easing equation online and modify the var refProportion using that equation, so that it's not a straight line from 0 -> 1, but rather an exponential curve of whatever kind.

Code: Select all

function fauxLinear(ref, refStart, refEnd, outStart, outEnd) {
	// constrain ref to range of refStart-refEnd
	if (refEnd < refStart) { [refEnd, refStart] = [refStart, refEnd]; }
	ref =	(ref < refStart) ? refStart :
		(ref > refEnd) ? refEnd : ref;

	// calculate input range and ref proportion
	const refRange = Math.abs(refEnd - refStart) || .001; // avoid dbz
	const refProportion = (ref - refStart) / refRange;

	// calculations for final output
	let outRange = [], finalVal = [];
	if ( !Array.isArray(outStart) ) { outStart = [outStart], outEnd = [outEnd]; }

	for (let i in outStart) {
		outRange[i] = outEnd[i] - outStart[i];
		finalVal[i] = (outRange[i] * refProportion + outStart[i]);
	}

	return ( outStart.length == 1 ) ? finalVal[0] : finalVal;
}
When converted to Python and applied to objects in Blender, it enables stuff like the below. (And yeah, you can do this kinda stuff w/ add-ons, but I wanted to see how far I could get w/ code.)

Image

Image