python中学物理实验模拟:匀速直线运动和匀变速直线运动对比
在物理学中,匀速直线运动((Uniform Linear Motion))和匀变速直线运动(Uniformly Accelerated Linear Motion)是两种基本的直线运动形式。
匀速直线运动:物体沿着一条直线运动,在任意相等的时间间隔内,物体的位移都相等。
位移公式:s = vt(s 为位移,t 为时间)。
关键特征
- 速度恒定:速度(v)是定值,即任意相等时间内通过的位移相等。
- 加速度为零:加速度(a)= 0,因为速度无变化。
实际例子:
光滑水平面上匀速滑动的木块;在非常光滑的冰面上匀速滑行的物体(近似匀速)。
匀变速直线运动:物体沿着一条直线运动,在任意相等的时间间隔内,物体的速度变化量都相等。
位移公式:s = v₀t + ½at², 速度公式:v = v₀ + at
(s 为位移,v₀初速度,a加速度,t 为时间)
关键特征
- 加速度恒定:加速度(a)为定值,速度变化率不变。
- 速度变化:速度(v)随时间均匀增加(加速)或减小(减速)。
分类
- 匀加速直线运动:加速度与速度方向相同,速度逐渐增大。
- 匀减速直线运动:加速度与速度方向相反,速度逐渐减小(可能减速至零后反向加速)。
实际例子:
汽车启动: 汽车从静止开始,油门保持稳定,在平直道路上加速(v₀ = 0, a > 0)。
汽车刹车: 汽车以一定速度行驶,踩下刹车踏板进行匀减速直到停止(v₀ > 0, a < 0)。
简单记忆
- 匀速: 速度不变 (v = 常量),位移随时间均匀增加 (s ∝ t)。
- 匀变速: 加速度不变 (a = 常量),速度随时间均匀变化 (v ∝ t),位移随时间不均匀增加 (s ∝ t²)。
这个模拟器可以帮助学生直观理解两种基本运动规律的差异。
运行情况截图
源码如下:
import tkinter as tk
from tkinter import ttk
import math
import time
class MotionSimulator:
def __init__(self):
self.root = tk.Tk()
self.root.title("物体运动实验")
self.root.geometry("800x700")
self.root.configure(bg='lightgray')
# 运动参数
self.uniform_velocity = tk.StringVar(value="200")
self.accelerated_velocity = tk.StringVar(value="200")
self.acceleration = tk.StringVar(value="10")
# 动画控制
self.uniform_running = False
self.accelerated_running = False
self.uniform_position = 0
self.accelerated_position = 0
self.uniform_time = 0
self.accelerated_time = 0
self.setup_ui()
def setup_ui(self):
# 匀速直线运动部分
uniform_frame = tk.LabelFrame(self.root, text="匀速直线运动",
font=("Arial", 12), bg='lightgray',
width=750, height=250)
uniform_frame.pack(padx=10, pady=5, fill='x')
uniform_frame.pack_propagate(False)
# 初速度输入
tk.Label(uniform_frame, text="初速:", bg='lightgray',
font=("Arial", 10)).place(x=30, y=30)
uniform_entry = tk.Entry(uniform_frame, textvariable=self.uniform_velocity,
width=10, font=("Arial", 10))
uniform_entry.place(x=80, y=30)
# 匀速运动画布
self.uniform_canvas = tk.Canvas(uniform_frame, width=700, height=100,
bg='white', relief='sunken', bd=2)
self.uniform_canvas.place(x=25, y=60)
# 画轨道线
self.uniform_canvas.create_line(50, 96, 650, 96, width=3, fill='black')
# 创建小车(车身)
self.uniform_car = self.uniform_canvas.create_rectangle(
60, 50, 110, 90, fill='lightblue', outline='black', width=2)
# 创建车轮(作为小车的一部分)
self.uniform_wheel1 = self.uniform_canvas.create_oval(65, 85, 75, 95, fill='black')
self.uniform_wheel2 = self.uniform_canvas.create_oval(95, 85, 105, 95, fill='black')
# 控制按钮
button_frame1 = tk.Frame(uniform_frame, bg='lightgray')
button_frame1.place(x=200, y=170)
tk.Button(button_frame1, text="归位", command=self.reset_uniform,
font=("Arial", 10), width=8).pack(side='left', padx=5)
tk.Button(button_frame1, text="走", command=self.start_uniform,
font=("Arial", 10), width=8).pack(side='left', padx=5)
tk.Button(button_frame1, text="停", command=self.stop_uniform,
font=("Arial", 10), width=8).pack(side='left', padx=5)
# 统一控制按钮区域
control_frame = tk.LabelFrame(self.root, text="统一控制",
font=("Arial", 12), bg='lightgray',
width=750, height=80)
control_frame.pack(padx=10, pady=5, fill='x')
control_frame.pack_propagate(False)
# 统一控制按钮 - 调整垂直位置
unified_button_frame = tk.Frame(control_frame, bg='lightgray')
unified_button_frame.place(x=250, y=5) # 从y=25改为y=5,
tk.Button(unified_button_frame, text="归位", command=self.reset_all,
font=("Arial", 12), width=10, bg='lightcoral').pack(side='left', padx=10)
tk.Button(unified_button_frame, text="走", command=self.start_all,
font=("Arial", 12), width=10, bg='lightgreen').pack(side='left', padx=10)
tk.Button(unified_button_frame, text="停", command=self.stop_all,
font=("Arial", 12), width=10, bg='lightyellow').pack(side='left', padx=10)
# 匀变速直线运动部分
accelerated_frame = tk.LabelFrame(self.root, text="匀变速直线运动",
font=("Arial", 12), bg='lightgray',
width=750, height=280)
accelerated_frame.pack(padx=10, pady=5, fill='x')
accelerated_frame.pack_propagate(False)
# 参数输入
tk.Label(accelerated_frame, text="初速:", bg='lightgray',
font=("Arial", 10)).place(x=30, y=30)
accelerated_v_entry = tk.Entry(accelerated_frame,
textvariable=self.accelerated_velocity,
width=10, font=("Arial", 10))
accelerated_v_entry.place(x=80, y=30)
tk.Label(accelerated_frame, text="加速度:", bg='lightgray',
font=("Arial", 10)).place(x=180, y=30)
acc_entry = tk.Entry(accelerated_frame, textvariable=self.acceleration,
width=10, font=("Arial", 10))
acc_entry.place(x=240, y=30)
# 说明文字
tk.Label(accelerated_frame, text="为正为匀加速;为负为匀减速",
bg='lightgray', font=("Arial", 9), fg='red').place(x=180, y=55)
# 匀变速运动画布
self.accelerated_canvas = tk.Canvas(accelerated_frame, width=700, height=100,
bg='white', relief='sunken', bd=2)
self.accelerated_canvas.place(x=25, y=80)
# 画轨道线
self.accelerated_canvas.create_line(50, 96, 650, 96, width=3, fill='black')
# 创建小车(车身)
self.accelerated_car = self.accelerated_canvas.create_rectangle(
60, 50, 110, 90, fill='lightgreen', outline='black', width=2)
# 创建车轮(作为小车的一部分)
self.accelerated_wheel1 = self.accelerated_canvas.create_oval(65, 85, 75, 95, fill='black')
self.accelerated_wheel2 = self.accelerated_canvas.create_oval(95, 85, 105, 95, fill='black')
# 控制按钮
button_frame2 = tk.Frame(accelerated_frame, bg='lightgray')
button_frame2.place(x=200, y=190)
tk.Button(button_frame2, text="归位", command=self.reset_accelerated,
font=("Arial", 10), width=8).pack(side='left', padx=5)
tk.Button(button_frame2, text="走", command=self.start_accelerated,
font=("Arial", 10), width=8).pack(side='left', padx=5)
tk.Button(button_frame2, text="停", command=self.stop_accelerated,
font=("Arial", 10), width=8).pack(side='left', padx=5)
# 显示运动参数
self.info_frame = tk.Frame(self.root, bg='lightgray')
self.info_frame.pack(pady=10)
self.uniform_info = tk.Label(self.info_frame, text="匀速运动: 位移=0, 时间=0",
bg='lightgray', font=("Arial", 10))
self.uniform_info.pack()
self.accelerated_info = tk.Label(self.info_frame, text="变速运动: 位移=0, 速度=0, 时间=0",
bg='lightgray', font=("Arial", 10))
self.accelerated_info.pack()
# 统一控制方法
def start_all(self):
"""同时开始两种运动"""
self.start_uniform()
self.start_accelerated()
def stop_all(self):
"""同时停止两种运动"""
self.stop_uniform()
self.stop_accelerated()
def reset_all(self):
"""同时重置两种运动"""
self.reset_uniform()
self.reset_accelerated()
def start_uniform(self):
"""开始匀速运动"""
if not self.uniform_running:
self.uniform_running = True
self.animate_uniform()
def stop_uniform(self):
"""停止匀速运动"""
self.uniform_running = False
def reset_uniform(self):
"""重置匀速运动"""
self.uniform_running = False
self.uniform_position = 0
self.uniform_time = 0
# 重置车身和车轮位置
self.uniform_canvas.coords(self.uniform_car, 60, 50, 110, 90)
self.uniform_canvas.coords(self.uniform_wheel1, 65, 85, 75, 95)
self.uniform_canvas.coords(self.uniform_wheel2, 95, 85, 105, 95)
self.update_info()
def animate_uniform(self):
"""匀速运动动画"""
if self.uniform_running:
try:
velocity = float(self.uniform_velocity.get())
# 时间步长
dt = 0.05 # 50ms
# 计算位移变化 (速度单位: pixels/second)
dx = velocity * dt * 0.1 # 缩放因子
# 更新位置
self.uniform_position += dx
self.uniform_time += dt
# 移动小车和车轮
current_pos = self.uniform_canvas.coords(self.uniform_car)
new_x = current_pos[0] + dx
# 边界检查
if new_x < 650 - 50: # 50是小车宽度
self.uniform_canvas.move(self.uniform_car, dx, 0)
self.uniform_canvas.move(self.uniform_wheel1, dx, 0)
self.uniform_canvas.move(self.uniform_wheel2, dx, 0)
else:
self.uniform_running = False
self.update_info()
self.root.after(50, self.animate_uniform)
except ValueError:
self.uniform_running = False
def start_accelerated(self):
"""开始匀变速运动"""
if not self.accelerated_running:
self.accelerated_running = True
self.animate_accelerated()
def stop_accelerated(self):
"""停止匀变速运动"""
self.accelerated_running = False
def reset_accelerated(self):
"""重置匀变速运动"""
self.accelerated_running = False
self.accelerated_position = 0
self.accelerated_time = 0
# 重置车身和车轮位置
self.accelerated_canvas.coords(self.accelerated_car, 60, 50, 110, 90)
self.accelerated_canvas.coords(self.accelerated_wheel1, 65, 85, 75, 95)
self.accelerated_canvas.coords(self.accelerated_wheel2, 95, 85, 105, 95)
self.update_info()
def animate_accelerated(self):
"""匀变速运动动画"""
if self.accelerated_running:
try:
v0 = float(self.accelerated_velocity.get())
a = float(self.acceleration.get())
# 时间步长
dt = 0.05 # 50ms
self.accelerated_time += dt
# 计算当前速度 v = v0 + at
current_velocity = v0 + a * self.accelerated_time
# 计算位移 s = v0*t + 0.5*a*t²
displacement = v0 * self.accelerated_time + 0.5 * a * (self.accelerated_time ** 2)
# 计算位移变化
new_position = displacement * 0.1 # 缩放因子
dx = new_position - self.accelerated_position
self.accelerated_position = new_position
# 移动小车和车轮
current_pos = self.accelerated_canvas.coords(self.accelerated_car)
new_x = current_pos[0] + dx
# 边界检查和速度检查
if new_x < 650 - 50 and new_x > 10 and current_velocity > -50:
self.accelerated_canvas.move(self.accelerated_car, dx, 0)
self.accelerated_canvas.move(self.accelerated_wheel1, dx, 0)
self.accelerated_canvas.move(self.accelerated_wheel2, dx, 0)
else:
self.accelerated_running = False
self.update_info()
self.root.after(50, self.animate_accelerated)
except ValueError:
self.accelerated_running = False
def update_info(self):
"""更新显示信息"""
# 匀速运动信息
uniform_text = f"匀速运动: 位移={self.uniform_position:.1f}, 时间={self.uniform_time:.1f}s"
self.uniform_info.config(text=uniform_text)
# 匀变速运动信息
try:
v0 = float(self.accelerated_velocity.get())
a = float(self.acceleration.get())
current_v = v0 + a * self.accelerated_time
accelerated_text = f"变速运动: 位移={self.accelerated_position:.1f}, 速度={current_v:.1f}, 时间={self.accelerated_time:.1f}s"
except:
accelerated_text = f"变速运动: 位移={self.accelerated_position:.1f}, 速度=0, 时间={self.accelerated_time:.1f}s"
self.accelerated_info.config(text=accelerated_text)
def run(self):
"""运行程序"""
self.root.mainloop()
# 运行程序
if __name__ == "__main__":
simulator = MotionSimulator()
simulator.run()
OK !