三次方缓动函数及其导数实现正确性验证与速度衔接问题排查
问题排查与修正
1. 原缓动函数的核心错误
你的CubicEaseIn和CubicEaseOut函数本身不符合缓动函数的基本逻辑:缓动函数应让物体从startValue移动到endValue,当currentTime=duration时结果必须等于endValue,但你的原函数此时会得到endValue + startValue,完全偏离预期。
修正后的基础缓动函数
// 三次方缓入:从startValue开始,加速向endValue移动 public static float CubicEaseIn(float currentTime, float startValue, float endValue, float duration) { float t = currentTime / duration; // 标准公式:起始值 + (目标差值) * 缓动因子 return startValue + (endValue - startValue) * t * t * t; } // 三次方缓出:从startValue开始,减速向endValue移动 public static float CubicEaseOut(float currentTime, float startValue, float endValue, float duration) { float t = currentTime / duration; // 标准公式:起始值 + (目标差值) * (1 - (1-t)^3) float easedT = 1 - (1 - t) * (1 - t) * (1 - t); return startValue + (endValue - startValue) * easedT; }
2. 导数函数的错误分析与修正
速度是位移函数对时间的导数,需注意两点:
- 常数项(
startValue)的导数为0,导数函数中不应包含startValue - 必须正确应用复合函数求导的链式法则
修正后的CubicEaseInD(缓入速度)
原位移函数为f(t) = startValue + (endValue - startValue) * (t/d)^3,求导得:f’(t) = (endValue - startValue) * 3*(t/d)^2 * (1/d) = 3*(endValue - startValue)*t² / d³
对应代码:
public static float CubicEaseInD(float currentTime, float startValue, float endValue, float duration) { float t = currentTime / duration; // 链式法则求导,需除以duration return 3 * (endValue - startValue) * t * t / duration; }
用你给出的参数测试:currentTime=3、startValue=0、endValue=1.5、duration=3,代入得结果1.5,符合预期——缓入结束时速度为1.5单位/秒,线性运动3秒的移动距离为1.5*3=4.5个卷轴长度,完美衔接速度。
修正后的CubicEaseOutD(缓出速度)
原位移函数为f(t) = startValue + (endValue - startValue)*(1 - (1-t/d)^3),求导得:f’(t) = (endValue - startValue)*3*(1-t/d)^2*(1/d)
对应代码:
public static float CubicEaseOutD(float currentTime, float startValue, float endValue, float duration) { float t = currentTime / duration; float oneMinusT = 1 - t; return 3 * (endValue - startValue) * oneMinusT * oneMinusT / duration; }
3. 老虎机场景验证
修正后,缓入阶段结束速度为1.5单位/秒,线性运动3秒的移动距离为4.5个卷轴长度,完全匹配你“速度衔接、匀速运动”的需求。
内容的提问来源于stack exchange,提问作者Programmer9000
相关产品推荐
相关产品推荐

