以下是一个实现金属杆与圆形纸片运动模拟,并计算圆珠笔在纸片上轨迹热力图的 Python 程序。该程序使用 numpy
进行数值计算,matplotlib
进行可视化,tkinter
构建交互界面。
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.widgets import Slider
import tkinter as tk
from tkinter import messagebox# 定义常量
L = 525.83 # 金属杆长度 (mm)
theta0 = np.radians(18.53) # 初始角度 (弧度)
r = 373.38 # 纸片半径 (mm)
x0 = -443.33 # 纸片中心 x 坐标 (mm)
y0 = -256.402 # 纸片中心 y 坐标 (mm)# 初始化参数
T = 60 # 时间 (秒)
R = 30 # 转速 (转/分钟)
W = 10 # 扫动速度 (sweep/分钟)# 创建主窗口
root = tk.Tk()
root.title("运动模拟参数设置")# 创建标签和输入框
tk.Label(root, text="时间 T (5 - 1800 秒):").grid(row=0, column=0)
T_entry = tk.Entry(root)
T_entry.insert(0, str(T))
T_entry.grid(row=0, column=1)tk.Label(root, text="转速 R (5 - 150 转/分钟):").grid(row=1, column=0)
R_entry = tk.Entry(root)
R_entry.insert(0, str(R))
R_entry.grid(row=1, column=1)tk.Label(root, text="扫动速度 W (1 - 30 个 sweep/分钟):").grid(row=2, column=0)
W_entry = tk.Entry(root)
W_entry.insert(0, str(W))
W_entry.grid(row=2, column=1)def run_simulation():global T, R, Wtry:T = float(T_entry.get())R = float(R_entry.get())W = float(W_entry.get())if 5 <= T <= 1800 and 5 <= R <= 150 and 1 <= W <= 30:simulate(T, R, W)else:messagebox.showerror("输入错误", "请输入有效的参数范围。")except ValueError:messagebox.showerror("输入错误", "请输入有效的数字。")# 创建运行按钮
run_button = tk.Button(root, text="运行模拟", command=run_simulation)
run_button.grid(row=3, column=0, columnspan=2)def simulate(T, R, W):# 计算时间步长dt = 0.01 # 时间步长 (秒)num_steps = int(T / dt)# 初始化轨迹数组trajectory_x = []trajectory_y = []for t in np.arange(0, T, dt):# 计算纸片的旋转角度phi = 2 * np.pi * R * t / 60 # 纸片旋转角度 (弧度)# 计算金属杆的扫动角度sweep_angle = 2 * np.pi * W * t / 60 # 扫动角度 (弧度)theta = theta0 + sweep_angle# 计算圆珠笔的位置x_pen = L * np.sin(theta)y_pen = -L * np.cos(theta)# 计算纸片上点的位置x_circle = x0 + r * np.cos(phi)y_circle = y0 + r * np.sin(phi)# 计算圆珠笔在纸片上的投影位置dx = x_pen - x_circledy = y_pen - y_circledist = np.sqrt(dx**2 + dy**2)if dist <= r:trajectory_x.append(x_pen)trajectory_y.append(y_pen)# 创建热力图heatmap, xedges, yedges = np.histogram2d(trajectory_x, trajectory_y, bins=100)extent = [xedges[0], xedges[-1], yedges[0], yedges[-1]]plt.figure(figsize=(8, 8))plt.imshow(heatmap.T, extent=extent, origin='lower', cmap='hot')plt.colorbar(label='轨迹密度')plt.title('圆珠笔在纸片上的轨迹热力图')plt.xlabel('X 坐标 (mm)')plt.ylabel('Y 坐标 (mm)')plt.show()# 运行主循环
root.mainloop()
代码说明:
- 常量定义:定义金属杆长度、初始角度、纸片半径和中心坐标等常量。
- 交互界面:使用
tkinter
构建一个简单的交互界面,允许用户输入时间T
、转速R
和扫动速度W
。 - 模拟函数:
simulate
函数根据用户输入的参数进行运动模拟,计算圆珠笔在纸片上的轨迹,并生成热力图。 - 热力图生成:使用
numpy
的histogram2d
函数计算轨迹的二维直方图,然后使用matplotlib
的imshow
函数绘制热力图。
使用方法:
- 运行程序,弹出参数设置窗口。
- 输入时间
T
、转速R
和扫动速度W
,确保参数在有效范围内。 - 点击“运行模拟”按钮,程序将计算并显示圆珠笔在纸片上的轨迹热力图。