储存、释放与损耗——运动系统的动画规律:弹簧动画

弹簧动画原理
弹簧动画指的是符合弹簧物理特性的动画,这种动画形式连贯流畅,能让动画元素显得更鲜活。例如,苹果等前端设计中常运用弹簧动画,为用户提供更丝滑的体验。
弹簧系统的物理基础
根据胡克定律,在弹簧系统中,弹力
根据这条定理,我们可以进一步推导出,在没有阻尼的情况下弹簧应该做简谐运动
在弹簧释放弹力的过程中,会由内部摩擦,外部摩擦等关系损耗掉这些弹力,因此,弹簧不会做往返的简谐运动,在此过程中,消耗掉弹力的因子我们称之为阻尼
阻尼的类型
根据阻尼的大小,弹簧的运动可以分为四种状态:无阻尼、欠阻尼、临界阻尼和过阻尼。下列代码展示了不同阻尼下弹簧的运动性质:
import numpy as np
import matplotlib.pyplot as plt
from scipy.integrate import solve_ivp
# 设置字体的属性
# plt.rcParams["font.sans-serif"] = "Arial Unicode MS"
plt.rcParams["font.sans-serif"] = "SimHei"
plt.rcParams["axes.unicode_minus"] = False
# 定义系统的参数
m = 1.0 # 质量
k = 1.0 # 弹簧常数
# 定义初始条件
x0 = -1.0 # 初始位移
v0 = 0.0 # 初始速度
# 定义时间范围
t = np.linspace(0, 20, 400)
# 系统的微分方程
def damped_oscillator(t, y, m, c, k):
x, v = y
dxdt = v
dvdt = -(c/m) * v - (k/m) * x
return [dxdt, dvdt]
# 不同阻尼情况的系数
damping_cases = {
'无阻尼': 0,
'欠阻尼': 0.5,
'临界阻尼': 2 * np.sqrt(m * k),
'过阻尼': 5,
}
# 创建绘图
plt.figure(figsize=(10, 8))
for label, c in damping_cases.items():
sol = solve_ivp(damped_oscillator, [0, t[-1]], [x0, v0], args=(m, c, k), t_eval=t)
plt.plot(sol.t, sol.y[0], label=label)
# 添加图例和标签
plt.title('弹簧系统的运动曲线')
plt.xlabel('时间 (s)')
plt.ylabel('位移 (m)')
plt.legend()
plt.grid(True)
# 显示图形
plt.show()
运行结果如下图所示:

而这就是弹簧动画所使用的曲线
-
无阻尼
无阻尼状态下,动画呈现简谐往返运动 -
欠阻尼
欠阻尼状态下,系统的超调量比较大,震荡比较厉害,整个动画看起来富有弹性 -
临界阻尼
临界阻尼下系统快速到达稳态,且不会产生震荡,动画看起来生动,迅速且不会富有弹性 -
过阻尼
过阻尼状态下,系统要一段时间之后才能达到稳态,动画流畅但缓慢