Easing

easing.h maps a timing's progress, from 0 to 1, onto eased progress. An mtwnEasing is a plain value: a maker checks its parameters and returns a status, and mtwnSampleEasing samples it, giving the eased progress through a pointer and its own status. It may be copied freely; what it references stays the host's: a host function's context must outlive every copy, and the points of linear() every copy the host keeps, since a transition or a clip copies the points in when it takes the easing.

Making and sampling

mtwnEasing ease;
mtwnResult made = mtwnMakeCssEasing(mtwn_cssEaseInOut, &ease); // CSS's ease-in-out
double eased = 0.0;
mtwnResult sampled = mtwnSampleEasing(&ease, 0.25, false, &eased); // a quarter of the way

mtwnEasing back;
made = mtwnMakeBackEasing(mtwn_easeOut, 1.70158, &back); // GSAP's back.out

The makers:

Maker Curves
mtwnMakeLinearEasing The identity; it cannot fail.
mtwnMakePowerEasing p^k: quad, cubic, quart, quint and any exponent above 0. GSAP's power(n) is k = n + 1.
mtwnMakePennerEasing Sine, expo, circ and bounce.
mtwnMakeBackEasing Back, with GSAP's and Penner's overshoot (1.70158 by default).
mtwnMakeElasticEasing Elastic, with GSAP's amplitude and period.
mtwnMakeCssEasing CSS's keywords: linear, ease, ease-in, ease-out, ease-in-out, step-start, step-end.
mtwnMakeCubicBezierEasing CSS's cubic-bezier(x1, y1, x2, y2).
mtwnMakeStepsEasing CSS's steps(n, position), every jump position.
mtwnMakeLinearPointsEasing CSS's linear() with points.
mtwnMakeRoughEasing A rough curve from a seed, below.
mtwnMakeSpringEasing A spring over a duration (see physics.md).
mtwnMakeHostEasing A function of the host's.

Every kind takes the same four modes: in (the curve as defined), out (1 - f(1 - p)), in-out and out-in. mtwnSetEaseMode changes the mode of an easing already made.

Not obvious

Rough easings

A rough easing wanders from a shape at points drawn from a seed, as GSAP's RoughEase and anime.js's irregular, the same curve for a seed on every platform. It fills points the host keeps, and is then linear() through them, so its ends stay exactly 0 and 1. A taper grows or calms the offsets toward the ends; the flags clamp the curve to 0 to 1, keep it rising, or set an even zig-zag with no seed.

mtwnLinearPoint points[22]; // kept while the easing is used
mtwnRoughDef def = {.shape = mtwnMakeLinearEasing(), .strength = 0.1, .seed = 42};
def.taper = mtwn_roughTaperOut; // calm by the end
mtwnEasing rough;
mtwnResult madeRough = mtwnMakeRoughEasing(&def, points, 22, &rough);

Tables and linear()

mtwnSampleEasingTable fills a table of evenly spaced samples, for a shader or a lookup; a sample past the floats' range is held at the largest finite float, as a target holds its value. mtwnFitLinearEasing turns any easing but steps into CSS linear() points within a tolerance, to hand to a browser or another engine: the points lie on the curve and the line between them is within the tolerance at 32 probes in each segment. A buffer that is too small gets mtwn_errorCapacity and the count needed, so call again with that capacity. A fit makes at most MTWN_MAX_FIT_POINTS points; a tolerance the curve cannot meet (below its rounding) ends with mtwn_errorLimit rather than with millions of them. The fit writes its points as it finds them, so a refused one leaves the buffer holding its first points, as many as fit, exactly as a larger buffer would start, and the rest as it was. Steps are refused: CSS writes them as steps().