自由落体运动
模拟物体从高处自由下落的过程,考虑重力加速度,绘制下落轨迹。
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
# 设置中文字体
plt.rcParams["font.family"] = ["SimHei"]
plt.rcParams["axes.unicode_minus"] = False
class FreeFallMotion:
def __init__(self, initial_height=100, g=9.8):
"""初始化自由落体运动的参数"""
self.initial_height = initial_height
self.g = g
self.fall_time = np.sqrt(2 * initial_height / g)
self.t = np.linspace(0, self.fall_time, 100)
self.y = initial_height - 0.5 * g * self.t ** 2
self.v = -g * self.t # 速度 (负号表示方向向下)
self.a = -g * np.ones_like(self.t) # 加速度
self.displacement = initial_height - self.y # 位移 (从初始位置算起)
# 创建包含4个子图的图形
self.fig, (self.ax1, self.ax2, self.ax3, self.ax4) = plt.subplots(1, 4, figsize=(20, 5))
self.fig.suptitle('自由落体运动分析')
# 设置轨迹子图
self.ax1.set_xlim(-1, 1)
self.ax1.set_ylim(0, initial_height * 1.1)
self.ax1.set_xlabel('水平位置 (米)')
self.ax1.set_ylabel('垂直高度 (米)')
self.ax1.set_title('运动轨迹')
self.ax1.grid(True)
# 设置位移子图
self.ax2.set_xlim(0, self.fall_time)
self.ax2.set_ylim(0, initial_height * 1.1)
self.ax2.set_xlabel('时间 (秒)')
self.ax2.set_ylabel('位移 (米)')
self.ax2.set_title('位移-时间关系')
self.ax2.grid(True)
# 设置速度子图
self.ax3.set_xlim(0, self.fall_time)
self.ax3.set_ylim(min(self.v) * 1.1, 0)
self.ax3.set_xlabel('时间 (秒)')
self.ax3.set_ylabel('速度 (米/秒)')
self.ax3.set_title('速度-时间关系')
self.ax3.grid(True)
# 设置加速度子图
self.ax4.set_xlim(0, self.fall_time)
self.ax4.set_ylim(self.a[0] * 1.1, 0)
self.ax4.set_xlabel('时间 (秒)')
self.ax4.set_ylabel('加速度 (米/秒²)')
self.ax4.set_title('加速度-时间关系')
self.ax4.grid(True)
# 初始化线条和点
self.trajectory_line, = self.ax1.plot([], [], 'b-', lw=2)
self.object_point, = self.ax1.plot([], [], 'ro', markersize=10)
self.displacement_line, = self.ax2.plot([], [], 'g-', lw=2)
self.displacement_point, = self.ax2.plot([], [], 'ro', markersize=8)
self.velocity_line, = self.ax3.plot([], [], 'm-', lw=2)
self.velocity_point, = self.ax3.plot([], [], 'ro', markersize=8)
self.acceleration_line, = self.ax4.plot([], [], 'c-', lw=2)
self.acceleration_point, = self.ax4.plot([], [], 'ro', markersize=8)
self.time_text = self.ax1.text(0.05, 0.95, '', transform=self.ax1.transAxes)
def init(self):
"""初始化动画"""
self.trajectory_line.set_data([], [])
self.object_point.set_data([], [])
self.displacement_line.set_data([], [])
self.displacement_point.set_data([], [])
self.velocity_line.set_data([], [])
self.velocity_point.set_data([], [])
self.acceleration_line.set_data([], [])
self.acceleration_point.set_data([], [])
self.time_text.set_text('')
return (self.trajectory_line, self.object_point,
self.displacement_line, self.displacement_point,
self.velocity_line, self.velocity_point,
self.acceleration_line, self.acceleration_point,
self.time_text)
def update(self, frame):
"""更新动画帧"""
# 更新轨迹和物体位置
self.trajectory_line.set_data([0] * len(self.y[:frame]), self.y[:frame])
self.object_point.set_data([0], [self.y[frame]])
# 更新位移曲线和当前位移点
self.displacement_line.set_data(self.t[:frame], self.displacement[:frame])
self.displacement_point.set_data([self.t[frame]], [self.displacement[frame]])
# 更新速度曲线和当前速度点
self.velocity_line.set_data(self.t[:frame], self.v[:frame])
self.velocity_point.set_data([self.t[frame]], [self.v[frame]])
# 更新加速度曲线和当前加速度点
self.acceleration_line.set_data(self.t[:frame], self.a[:frame])
self.acceleration_point.set_data([self.t[frame]], [self.a[frame]])
# 更新时间显示
self.time_text.set_text(f'时间: {self.t[frame]:.2f}秒')
return (self.trajectory_line, self.object_point,
self.displacement_line, self.displacement_point,
self.velocity_line, self.velocity_point,
self.acceleration_line, self.acceleration_point,
self.time_text)
def animate(self):
"""运行动画"""
anim = FuncAnimation(
self.fig, self.update, frames=len(self.t), init_func=self.init,
blit=True, interval=50
)
plt.tight_layout()
plt.show()
return anim
# 运行模拟
if __name__ == "__main__":
# 创建自由落体运动实例
fm = FreeFallMotion(initial_height=100, g=9.8)
# 显示动画
fm.animate()