Since the problem is so limited (function x(t) is monotonic), we can probably get away with using a pretty cheap method of solution-- binary search.
var bezier = function(x0, y0, x1, y1, x2, y2, x3, y3, t) {
/* whatever you're using to calculate points on the curve */
return undefined; //I'll assume this returns array [x, y].
};
//we actually need a target x value to go with the middle control
//points, don't we? ;)
var yFromX = function(xTarget, x1, y1, x2, y2) {
var xTolerance = 0.0001; //adjust as you please
var myBezier = function(t) {
return bezier(0, 0, x1, y1, x2, y2, 1, 1, t);
};
//we could do something less stupid, but since the x is monotonic
//increasing given the problem constraints, we'll do a binary search.
//establish bounds
var lower = 0;
var upper = 1;
var percent = (upper + lower) / 2;
//get initial x
var x = myBezier(percent)[0];
//loop until completion
while(Math.abs(xTarget - x) > xTolerance) {
if(xTarget > x)
lower = percent;
else
upper = percent;
percent = (upper + lower) / 2;
x = myBezier(percent)[0];
}
//we're within tolerance of the desired x value.
//return the y value.
return myBezier(percent)[1];
};
This should certainly break on some inputs outside of your constraints.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…