I am implementing animated double
property from scratch, currently with SmoothStep easing, however when new target value is set, there is visible "jump" in animation speed (probably due to applied easing). I would like setTarget
to smoothly extend currently ongoing animation.
I have tried to calculate originalValue_
and remaining_
based on current t
(offsetting those correctly, I think, will solve the problem), but haven't managed to find the correct formula.
How do I smoothly extend ongoing smoothstep animation to new target value?
void setTargetValue(double value, double duration = 1.0)
{
originalValue_ = currentValue();
targetValue_ = value;
remaining_ = duration;
duration_ = duration;
t = 0.0;
}
double currentValue() const {
return SmoothStep(originalValue_, targetValue_, t); //x*x*(3 - 2*x)
}
void update(double deltaT) {
remaining_ = fmax(0.0, remaining_ - deltaT);
t = clamp(0.0, 1.0, 1.0 - remaining_ / duration_)
}
Answer
I was missing one important information - SmoothStep is a cubic spline interpolation with endpoints derivative being zero. There is well-known solution to cubic interpolation.
Luckily for case of animation there is no need to solve the linear equation system. Because the Di+1 is 0 by definition, all that is needed is first derivative Di at current t
which is trivial for fixed order polynomial. Substituting to the equations we get new coeficients:
double derivative(double t) const {
return coeff[0] + t * (2 * coeff[1] + 3 * t * coeff[2]); //b+2cx+3dx*x
}
//in setTargetValue compute new coefficients
double coeff[3];//a = 0 by definition
//note: in real implementation interval length compensation is also needed
coeff[0] = derivative(t);//b
coeff[1] = 3 - 2 * coeff[0];//c
coeff[2] = -2 + coeff[0];//d
and evaluate the SmoothStep t
mapping as follows
double SmoothStepT(double t) const {
return t * (coeff[0] + t * (coeff[1] + t * coeff[2])); //bx+cx*x+dx*x*x
}
double currentValue() const {
return Lerp(originalValue_, targetValue_, SmoothStepT(t));
}
desmos graph demonstrating smoothness with two extensions: note: coefficient a
and x - t
is added to "move" the extended animation to place where the previous one left to demonstrate smoothness.
note2: I am not a mathematician, if you see an error in my math, please correct me
No comments:
Post a Comment