王克能Import numpy as np import matplotlib.pyplot as plt import matplotlib.animation as animation ...
Import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
zeta = 0.4 # 阻尼系数 (0 < zeta < 1,欠阻尼状态,呈现优美的螺旋收敛)
omega_n = 2.0 # 自然频率
t = np.linspace(0, 10, 400)
x0, v0 = 3.0, 2.0
alpha = zeta * omega_n
omega_d = omega_n * np.sqrt(1 - zeta**2)
C1 = x0
C2 = (v0 + alpha * x0) / omega_d
x = np.exp(-alpha * t) * (C1 * np.cos(omega_d * t) + C2 * np.sin(omega_d * t))
v = np.exp(-alpha * t) * (-alpha * C1 * np.cos(omega_d * t) - alpha * C2 * np.sin(omega_d * t)
- C1 * omega_d * np.sin(omega_d * t) + C2 * omega_d * np.cos(omega_d * t))
fig, ax = plt.subplots(figsize=(8, 8), facecolor='#0d1117')
ax.set_facecolor('#0d1117')
theta = np.linspace(0, 2*np.pi, 200)
for r in np.linspace(0.5, 4.0, 8):
# 简化的能量椭圆边界
ax.plot(r * np.cos(theta), r * np.sin(theta) / omega_n,
color='#1f6feb', alpha=0.3, linestyle='--', linewidth=1)
line, = ax.plot([], [], color='#58a6ff', linewidth=2.5, label='系统演化轨迹 (Trajectory)')
point, = ax.plot([], [], marker='o', color='#f85149', markersize=10, label='当前状态 (Perturbed State)')
origin, = ax.plot([0], [0], marker='*', color='#3fb950', markersize=15, label='平衡态 (Equilibrium)')
ax.set_xlim(-4.5, 4.5)
ax.set_ylim(-4.5, 4.5)
ax.axhline(0, color='#30363d', linewidth=1)
ax.axvline(0, color='#30363d', linewidth=1)
ax.set_title("Lyapunov Stability Region & Damping Convergence (ζ = {})".format(zeta),
color='#c9d1d9', fontsize=14, pad=15)
ax.set_xlabel("Displacement x (位移)", color='#8b949e', fontsize=12)
ax.set_ylabel("Velocity v (速度)", color='#8b949e', fontsize=12)
ax.tick_params(colors='#8b949e')
for spine in ax.spines.values():
spine.set_edgecolor('#30363d')
ax.legend(facecolor='#161b22', edgecolor='#30363d', labelcolor='#c9d1d9', loc='upper right')
def init():
line.set_data([], [])
point.set_data([], [])
return line, point
def update(frame):
# 轨迹动态延伸
line.set_data(x[:frame], v[:frame])
# 当前扰动点位置
point.set_data([x[frame]], [v[frame]])
return line, point
ani = animation.FuncAnimation(fig, update, frames=len(t), init_func=init, interval=30, blit=True)
ani.save('lyapunov_damping.gif', writer='pillow', fps=30)
plt.show()