I need help with the solution provided here.
Create easy function 40% off set
I need to modify it so that the returned left and rights are extrapolated to
I created a modified version of Mike's split function so it fits it to a unit square :) It uses hkrish's pointers to do coordinate normalization.
Just set parameter fitUnitCell
to true. :)
function splitCubicBezier(options) {
var z = options.z,
cz = z-1,
z2 = z*z,
cz2 = cz*cz,
z3 = z2*z,
cz3 = cz2*cz,
x = options.x,
y = options.y;
var left = [
x[0],
y[0],
z*x[1] - cz*x[0],
z*y[1] - cz*y[0],
z2*x[2] - 2*z*cz*x[1] + cz2*x[0],
z2*y[2] - 2*z*cz*y[1] + cz2*y[0],
z3*x[3] - 3*z2*cz*x[2] + 3*z*cz2*x[1] - cz3*x[0],
z3*y[3] - 3*z2*cz*y[2] + 3*z*cz2*y[1] - cz3*y[0]];
var right = [
z3*x[3] - 3*z2*cz*x[2] + 3*z*cz2*x[1] - cz3*x[0],
z3*y[3] - 3*z2*cz*y[2] + 3*z*cz2*y[1] - cz3*y[0],
z2*x[3] - 2*z*cz*x[2] + cz2*x[1],
z2*y[3] - 2*z*cz*y[2] + cz2*y[1],
z*x[3] - cz*x[2],
z*y[3] - cz*y[2],
x[3],
y[3]];
if (options.fitUnitSquare) {
return {
left: left.map(function(el, i) {
if (i % 2 == 0) {
//return el * (1 / left[6])
var Xmin = left[0];
var Xmax = left[6]; //should be 1
var Sx = 1 / (Xmax - Xmin);
return (el - Xmin) * Sx;
} else {
//return el * (1 / left[7])
var Ymin = left[1];
var Ymax = left[7]; //should be 1
var Sy = 1 / (Ymax - Ymin);
return (el - Ymin) * Sy;
}
}),
right: right.map(function(el, i) {
if (i % 2 == 0) {
//xval
var Xmin = right[0]; //should be 0
var Xmax = right[6];
var Sx = 1 / (Xmax - Xmin);
return (el - Xmin) * Sx;
} else {
//yval
var Ymin = right[1]; //should be 0
var Ymax = right[7];
var Sy = 1 / (Ymax - Ymin);
return (el - Ymin) * Sy;
}
})
}
} else {
return { left: left, right: right};
}
}
var easeInOut = {
xs: [0, .42, .58, 1],
ys: [0, 0, 1, 1]
};
var splitRes = splitCubicBezier({
z: .5,
x: easeInOut.xs,
y: easeInOut.ys,
fitUnitSquare: false
});
alert(splitRes.toSource())
first half is ease-in which is cubic-bezier(.42,0,1,1) and graphically is http://cubic-bezier.com/#.42,0,1,1
Please verify this assumption. (curves original end points are 0,0, and 1,1 in a css timing function) The first half of the bezier curve [0,0, .42,0, .58,1, 1,1] should not be [0,0 .42,0, 1,1, 1,1] The end points are correct (after scaling to 1,1), but you have lost continuity there.
The values returned by Mike's algorithm is correct.
Try this visualisation for an explanation on why your assumption might be wrong.
The algorithm you are using to split is a well known algorithm called de Casteljau algorithm. This method can be geometrically expressed in a very simple manner. Check out the animated visualisations on how this splitting at any arbitrary point is possible https://en.wikipedia.org/wiki/B%C3%A9zier_curve.
However, You may soon hit an issue trying to correctly scale a split portion of a bezier curve to fit in a unit square, with endpoints fixed at 0,0 and 1,1. This probably you can try out quite easily on paper. The easiest way probably is to just linearly scale the control points of the bezier, you will get a squashed curve in most cases though.