日期:2019/12/23
題目
在水平光滑桌面上有一個質量為 1.8 kg 的 U 形物體,左、右兩側各連接一條原長為 0.5 m、彈性常數為 5.0 N/m 的理想彈簧,將一個質量為 0.2 kg 的木塊放在水平底面上,將右側的彈簧向右壓縮 0.2 m,整個系統原為靜止,假設摩擦力可以忽略,將木塊釋放後整個系統會如何運動?
模擬動畫畫面截圖
理論推導
由於右側彈簧原來被壓縮,右側彈簧的回復力會將木塊往左推、將 U 形物體往右推;當木塊開始壓縮左側的彈簧時,左側彈簧的回復力會將木塊往右推、將 U 形物體往左推;由於整個系統所受外力合為0,系統動量守恆,質心速度為0。
模擬動畫程式
GlowScript 網站動畫連結
"""
VPython教學: U 形物體與木塊彈簧系統彈性碰撞
日期: 2019/12/23
作者: 王一哲
"""
from vpython import *
"""
1. 參數設定, 設定變數及初始值
"""
d1, m1, v1, c1 = 0.2, 0.2, 0.0, color.red # 木塊的寬度=0.2 m, 質量=0.2 kg, 初速, 紅色
d2, m2, v2, c2 = 0.2, 0.4, 0.0, color.blue # 牆壁的寬度=0.2 m, 質量=0.4 kg, 初速, 藍色
d3, m3, v3, c3 = 2.0, 1.0, 0.0, color.blue # 底部的寬度=1.0 m, 質量=1.0 kg, 初速, 藍色
L0, k = 0.5, 5.0 # 彈簧的原長=0.5 m, 彈性常數=5.0 N/m
t, dt = 0, 0.0005 # 時間, 時間間隔
"""
2. 畫面設定
"""
# 產生動畫視窗
scene = canvas(title="1-D Collision Between U-Shpaed Object and Block", width=800, height=400, center=vec(0, 0.4, 0),
background=color.black)
# 產生地板、木塊、左側牆壁、右側牆壁、底部並設定初速度
floor = box(pos=vec(0, -1.55*d2, 0), size=vec(2*d3, 0.1*d2, 0.5*d3), color=color.gray(0.5))
block = box(pos=vec(0.5, 0, 0), size=vec(d1, d1, d1), color=c1, m=m1, v=vec(v1, 0, 0))
bottom = box(pos=vec(0, -1.0*d2, 0), size=vec(d3, d2, 0.5*d3), color=c3, m=m3, v=vec(v3, 0, 0))
left = box(pos=vec(-0.5*d3 + 0.5*d2, 0, 0), size=vec(d2, d2, 0.5*d3), color=c2, m=m2, v=vec(v2, 0, 0))
right = box(pos=vec(0.5*d3 - 0.5*d2, 0, 0), size=vec(d2, d2, 0.5*d3), color=c2, m=m2, v=vec(v2, 0, 0))
# 產生彈簧
sleft = helix(pos=left.pos + vec(0.5*d2, 0, 0), axis=vec(L0, 0, 0), radius=0.05, thickness=0.03)
sright = helix(pos=right.pos - vec(0.5*d2, 0, 0), axis=block.pos-right.pos+vec(0.5*d1+0.5*d2, 0, 0),
radius=0.05, thickness=0.03)
# 繪圖部分
gd = graph(title="<i>v</i>-<i>t</i> plot", x=0, y=450, width=600, height=450,
foreground=color.white, background=color.white, fast=False, xtitle="<i>t</i> (s)",
ytitle="red: <i>v</i><sub>1</sub>, blue: <i>v</i><sub>2</sub> (m/s), orange: <i>v</i><sub>c</sub> (m/s)")
vt1 = gcurve(graph=gd, color=c1)
vt2 = gcurve(graph=gd, color=c2)
vtc = gcurve(graph=gd, color=color.orange)
"""
3. 物體運動部分
"""
while True:
rate(1000)
# 計算木塊間的距離, 更新彈簧長度, 計算彈簧回復力, 更新木塊、牆壁、底部加速度
dright = right.pos.x - block.pos.x - 0.5*d1 - 0.5*d2
dleft = block.pos.x - left.pos.x - 0.5*d1 - 0.5*d2
if dright < L0:
sright.axis = vec(-dright, 0, 0)
force = vec(k*(L0-dright), 0, 0)
block.a = -force/m1
left.a = right.a = bottom.a = force/(m2+m2+m3)
elif dleft < L0:
sleft.axis = vec(dleft, 0, 0)
force = vec(k*(L0-dleft), 0, 0)
block.a = force/m1
left.a = right.a = bottom.a = -force/(m2+m2+m3)
else:
block.a = left.a = right.a = bottom.a = vec(0, 0, 0)
# 更新木塊, 牆壁, 底部速度、位置, 更新彈簧位置
block.v += block.a*dt
left.v += left.a*dt
right.v += right.a*dt
bottom.v += bottom.a*dt
block.pos += block.v*dt
left.pos += left.v*dt
right.pos += right.v*dt
bottom.pos += bottom.v*dt
sleft.pos = left.pos + vec(0.5*d2, 0, 0)
sright.pos = right.pos - vec(0.5*d2, 0, 0)
# 畫v-t圖
vt1.plot(pos=(t, block.v.x))
vt2.plot(pos=(t, bottom.v.x))
vc = (block.v.x*m1 + left.v.x*m2 + right.v.x*m2 + bottom.v.x*m3) / (m1+m2+m2+m3)
vtc.plot(pos=(t, vc))
# 更新時間
t += dt
整個程式中最重要的部分是第47 - 61行,先計算木塊與右側牆壁間的距離 dright、木塊與左側牆壁間的距離 dleft,共有3種可能
- dright < L0:右側彈簧被壓縮,更新彈簧的長度及方向,計算彈簧的回復力,再更新木塊、兩側牆壁、底部的加速度。
- dleft < L0:左側彈簧被壓縮,更新彈簧的長度及方向,計算彈簧的回復力,再更新木塊、兩側牆壁、底部的加速度。
- 以上2種狀況皆不成立:彈簧沒有被壓縮,將木塊、牆壁、底部的加速度設定為0。
- 壓縮量為 0.1 m
- 壓縮量為 0.2 m
- 壓縮量為 0.3 m
- 壓縮量為 0.2 m,但將 U 形物體的質量改為 0.4 kg,木塊質量仍為 0.2 kg
組合1 v-t 圖
組合2 v-t 圖
組合3 v-t 圖
組合4 v-t 圖
結語
當彈簧一開始的壓縮量越大時,木塊及 U 形物體的最大速度都會變大,但由於前3種數據組合的質量比為 1 : 9,從 v-t 圖比較不容易直接看出最大速度量值比為 9 : 1;但是組合4的木塊及 U 形物體質量比為 1 : 2,從 v-t 圖比較容易看出最大速度量值比為 2 : 1。這個動畫可以用來說明系統外力合為零時系統動量守恆。HackMD 版本連結:https://hackmd.io/@yizhewang/ryYWcrRCr
沒有留言:
張貼留言