用Python模拟完全弹性碰撞:从公式推导到可视化演示(附完整代码)
用Python模拟完全弹性碰撞从公式推导到可视化演示附完整代码在物理仿真领域完全弹性碰撞是一个经典的研究课题。它不仅帮助我们理解动量守恒和能量守恒的基本原理还能通过编程实现直观的可视化效果。本文将带你从零开始用Python构建一个完整的弹性碰撞模拟系统并通过matplotlib实现动态演示。1. 理解完全弹性碰撞的物理原理完全弹性碰撞是指两个物体碰撞前后总动能保持不变的理想情况。这种碰撞满足两个基本守恒定律动量守恒系统总动量在碰撞前后保持不变动能守恒系统总动能在碰撞前后保持不变用数学公式表示为动量守恒m₁v₁₀ m₂v₂₀ m₁v₁ m₂v₂ 动能守恒½m₁v₁₀² ½m₂v₂₀² ½m₁v₁² ½m₂v₂²注意在实际编程中我们通常会简化场景假设第二个物体初始静止(v₂₀0)这样公式推导会更简洁。2. 碰撞后的速度公式推导基于上述守恒定律我们可以推导出碰撞后两物体的速度表达式。假设物体2初始静止(v₂₀0)推导过程如下由动量守恒 m₁v₁₀ m₁v₁ m₂v₂由动能守恒 ½m₁v₁₀² ½m₁v₁² ½m₂v₂²通过代数运算可以得到碰撞后的速度v₁ (m₁ - m₂)/(m₁ m₂) * v₁₀ v₂ (2m₁)/(m₁ m₂) * v₁₀这个结果有几个有趣的特例质量比碰撞后物体1速度碰撞后物体2速度物理意义m₁m₂0v₁₀物体1停止物体2获得全部速度m₁m₂v₁₀2v₁₀大质量物体几乎不受影响小质量物体获得两倍速度m₁m₂-v₁₀0小质量物体反弹大质量物体几乎不动3. Python实现碰撞模拟现在我们将上述物理原理转化为Python代码。首先需要安装必要的库pip install numpy matplotlib然后创建一个CollisionSimulator类来封装我们的模拟逻辑import numpy as np import matplotlib.pyplot as plt from matplotlib.animation import FuncAnimation class CollisionSimulator: def __init__(self, m11.0, m21.0, v11.0, v20.0): self.m1 m1 # 物体1质量 self.m2 m2 # 物体2质量 self.v1 v1 # 物体1初速度 self.v2 v2 # 物体2初速度 self.x1 -5 # 物体1初始位置 self.x2 0 # 物体2初始位置 self.radius 0.5 # 物体显示半径 self.time 0 self.dt 0.01 # 时间步长 def calculate_velocities(self): 计算碰撞后的速度 v1_new ((self.m1 - self.m2) / (self.m1 self.m2)) * self.v1 \ ((2 * self.m2) / (self.m1 self.m2)) * self.v2 v2_new ((2 * self.m1) / (self.m1 self.m2)) * self.v1 \ ((self.m2 - self.m1) / (self.m1 self.m2)) * self.v2 return v1_new, v2_new def update_positions(self): 更新物体位置 self.x1 self.v1 * self.dt self.x2 self.v2 * self.dt self.time self.dt # 检测碰撞 if abs(self.x1 - self.x2) 2 * self.radius: self.v1, self.v2 self.calculate_velocities() def get_state(self): 返回当前状态 return { time: self.time, x1: self.x1, x2: self.x2, v1: self.v1, v2: self.v2 }4. 可视化碰撞过程有了模拟器后我们可以用matplotlib创建动画来直观展示碰撞过程def run_simulation(m11.0, m21.0, v11.0, v20.0, duration10): sim CollisionSimulator(m1, m2, v1, v2) # 设置图形 fig, ax plt.subplots(figsize(10, 4)) ax.set_xlim(-10, 10) ax.set_ylim(-1, 1) ax.set_aspect(equal) ax.grid(True) # 创建物体表示 circle1 plt.Circle((sim.x1, 0), sim.radius, colorblue) circle2 plt.Circle((sim.x2, 0), sim.radius, colorred) ax.add_patch(circle1) ax.add_patch(circle2) # 添加质量标签 mass_text1 ax.text(sim.x1, 0.7, fm1{m1}, hacenter) mass_text2 ax.text(sim.x2, 0.7, fm2{m2}, hacenter) # 动画更新函数 def update(frame): sim.update_positions() circle1.center (sim.x1, 0) circle2.center (sim.x2, 0) mass_text1.set_position((sim.x1, 0.7)) mass_text2.set_position((sim.x2, 0.7)) return circle1, circle2, mass_text1, mass_text2 # 创建动画 frames int(duration / sim.dt) ani FuncAnimation(fig, update, framesframes, interval20, blitTrue) plt.title(完全弹性碰撞模拟) plt.xlabel(位置) plt.show() return ani5. 模拟不同质量比的碰撞效果现在我们可以通过改变质量参数来观察不同的碰撞效果。以下是几个典型场景的模拟5.1 等质量碰撞(m1m21)run_simulation(m11.0, m21.0, v12.0)这种情况下物体1会完全停止物体2会获得物体1的全部速度。5.2 大质量撞击小质量(m110, m21)run_simulation(m110.0, m21.0, v11.0)大质量物体几乎不受影响小质量物体会被高速弹开。5.3 小质量撞击大质量(m11, m210)run_simulation(m11.0, m210.0, v12.0)小质量物体会以接近原速度反弹大质量物体几乎保持静止。6. 扩展功能能量和动量跟踪为了更深入理解碰撞过程我们可以添加能量和动量的计算与显示def run_simulation_with_metrics(m11.0, m21.0, v11.0, v20.0): sim CollisionSimulator(m1, m2, v1, v2) # 设置图形 fig, (ax1, ax2) plt.subplots(2, 1, figsize(10, 8)) ax1.set_xlim(-10, 10) ax1.set_ylim(-1, 1) ax1.set_aspect(equal) ax1.grid(True) # 创建物体 circle1 plt.Circle((sim.x1, 0), sim.radius, colorblue) circle2 plt.Circle((sim.x2, 0), sim.radius, colorred) ax1.add_patch(circle1) ax1.add_patch(circle2) # 初始化能量和动量曲线 time_data [] momentum_data [] energy_data [] line_momentum, ax2.plot([], [], b-, label总动量) line_energy, ax2.plot([], [], r-, label总动能) ax2.legend() ax2.set_xlim(0, 10) ax2.set_ylim(0, max(1, 0.5*m1*v1**2 0.5*m2*v2**2)*1.2) ax2.set_xlabel(时间) ax2.set_ylabel(值) ax2.grid(True) def update(frame): sim.update_positions() circle1.center (sim.x1, 0) circle2.center (sim.x2, 0) # 计算动量和能量 momentum m1 * sim.v1 m2 * sim.v2 energy 0.5 * m1 * sim.v1**2 0.5 * m2 * sim.v2**2 time_data.append(sim.time) momentum_data.append(momentum) energy_data.append(energy) line_momentum.set_data(time_data, momentum_data) line_energy.set_data(time_data, energy_data) # 调整坐标轴范围 if sim.time ax2.get_xlim()[1]: ax2.set_xlim(0, sim.time) return circle1, circle2, line_momentum, line_energy ani FuncAnimation(fig, update, frames500, interval20, blitTrue) plt.suptitle(完全弹性碰撞模拟 - 动量与能量守恒) plt.show() return ani这个扩展版本可以直观展示碰撞过程中动量和能量的守恒情况验证我们的模拟确实符合物理定律。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2437853.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!