代码:
from vpython import * # 加载vpython模块
s1 = canvas(width=1200, height=500, background=color.white, center=vector(0, 1, 0)) # 定义画布
L0 = 1.4 # 定义初始高度
natural_length = 0.9 # 设置弹簧原长
base_spring = box(pos=vector(0, 0, 0), size=vector(0.1, 0.02, 0.1), color=color.white) # 创建基座
ball1 = sphere(pos=vector(0, L0, 0), radius=0.05, color=color.blue) # 创建小球
spring = helix(pos=vector(0, 0, 0), axis=vector(0, 1, 0), radius=0.03, coils=13, length=natural_length, thickness=0.01,
color=color.yellow) # 创建弹簧
s1.autoscale = 0 # 禁止画面自动缩放
g1 = graph(width=400, height=300, xtitle="时间/s", ytitle="能量/J", align="left") # 定义曲线显示窗口
EKcurve = gcurve(color=color.red, graph=g1, label="动能") # 定义动能曲线
EPEcurve = gcurve(color=color.blue, graph=g1, label="弹性势能") # 定义弹性势能曲线
EPHcurve = gcurve(color=color.green, graph=g1, label="重力势能") # 定义弹性势能曲线
EEcurve = gcurve(color=color.yellow, graph=g1, label="小球机械能") # 定义小球机械能曲线
Ecurve = gcurve(color=color.black, graph=g1, label="系统机械能") # 定义系统机械能曲线
g2 = graph(width=400, height=300, xtitle="时间/s", ytitle="速度/m/s", align="left") # 定义曲线显示窗口
Vcurve = gcurve(color=color.red, graph=g2, label="速度") # 定义动能曲线
g3 = graph(width=400, height=300, xtitle="时间/s", ytitle="加速度/m/s^2", align="left") # 定义曲线显示窗口
Acurve = gcurve(color=color.magenta, graph=g3, label="加速度") # 定义动能曲线
vector_f = arrow(color=color.black, shaftwidth=0.01) # 定义弹簧弹力矢量箭头
f_label = label(text="T", height=20, opacity=0, box=False) # 定义弹簧弹力标签
vector_g = arrow(color=color.red, shaftwidth=0.01) # 定义重力矢量箭头
g_label = label(text='G', height=20, opacity=0, box=False) # 定义重力标签
EK_label = label(text="动能", height=20, opacity=0, box=False) # 定义小球动能标签
EPE_label = label(text="弹性势能", height=20, opacity=0, box=False) # 定义弹性势能标签
EPH_label = label(text="重力势能", height=20, opacity=0, box=False) # 定义弹性势能标签
vector_scale = 0.1 # 设置箭头缩放系数
m = 0.2 # 设定小球质量
k = 10 # 设置弹簧劲度系数
g = -10 # 设置重力加速度
ball1.v = vector(0, 0, 0) # 设定小球初始速度矢量
ball1.a = vector(0, 0, 0) # 设定小球初始加速度矢量
t = 0 # 设定时间变量
dt = 0.0001 # 设置时间间隔
EPE = 0 # 设定重力势能
G = m * g # 设定重力
while t < 5: # 设置循环总时间
rate(1000) # 设置每秒循环次数
if (ball1.pos.y > natural_length):
ball1.a.y = g # 自由落体加速度
ball1.v = ball1.v + ball1.a * dt # 计算小球速度矢量更新值
ball1.pos = ball1.pos + ball1.v * dt # 计算小球位置矢量更新值
else:
spring.length = ball1.pos.y # 计算新的弹簧长度
delta_length = spring.length - natural_length # 计算弹簧变形长度
f = -k * delta_length # 计算弹簧弹力
ball1.a.y = (f + G) / m # 根据牛顿第二定律计算小球加速度
ball1.v = ball1.v + ball1.a * dt # 计算小球速度矢量更新值
ball1.pos = ball1.pos + ball1.v * dt # 计算小球位置矢量更新值
EPE = 0.5 * k * delta_length ** 2 # 计算弹簧弹性势能
vector_f.pos = ball1.pos # 更新弹力箭头位置
vector_f.axis = vector(0, f, 0) * vector_scale # 更新弹力箭头大小
if (f > -G): # 更新弹力箭头颜色
vector_f.color = color.orange
else:
vector_f.color = color.purple
f_label.pos = vector_f.pos + vector_f.axis * 1.2 # 设置弹力标签位置
f_label.pos.x = f_label.pos.x - 0.1
f_label.text = "f=" + str(f)[:4] # 设置弹力标签显示内容
EK = 0.5 * m * (mag(ball1.v)) ** 2 # 计算小球动能
EPH = m * g * (L0 - ball1.pos.y)
E = EK + EPE + EPH # 计算系统机械能
EE = EK + EPH # 计算小球机械能
vector_g.pos = ball1.pos # 更新弹力箭头位置
vector_g.axis = vector(0, G, 0) * vector_scale # 更新弹力箭头大小
g_label.pos = vector_g.pos + vector_g.axis * 1.2 # 设置弹力标签位置
g_label.pos.x = g_label.pos.x - 0.1
g_label.text = "G=" + str(G)[:4] # 设置弹力标签显示内容
EK_label.pos = vector(ball1.pos.x + 0.5, ball1.pos.y, ball1.pos.z) # 设置动能标签位置
EK_label.text = "动 能=" + str("%.2f" % EK) # 设置动能标签显示内容
EPE_label.pos = vector(EK_label.pos.x + 0.0, EK_label.pos.y - 0.2, EK_label.pos.z) # 设置弹性势能标签位置
EPE_label.text = "弹性势能=" + str("%.2f" % EPE) # 设置弹性势能标签显示内容
EPH_label.pos = vector(ball1.pos.x + 0.5, ball1.pos.y - 0.1, ball1.pos.z) # 设置弹性势能标签位置
EPH_label.text = "重力势能=" + str("%.2f" % EPH) # 设置弹性势能标签显示内容
EKcurve.plot(t, EK) # 绘制动能曲线
EPEcurve.plot(t, EPE) # 绘制弹性势能曲线
EPHcurve.plot(t, EPH) # 绘制重力势能曲线
Ecurve.plot(t, E) # 绘制系统机械能曲线
EEcurve.plot(t, EE) # 绘制机械能曲线
Vcurve.plot(t, ball1.v.y) # 绘制速度曲线
Acurve.plot(t, ball1.a.y) # 绘制加速度曲线
t = t + dt # 迭代时间
结果:
运行会弹出到浏览器显示