2019年12月23日 星期一

U 形物體與木塊系統的動量守恆

作者:王一哲
日期: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種可能

  1. dright < L0:右側彈簧被壓縮,更新彈簧的長度及方向,計算彈簧的回復力,再更新木塊、兩側牆壁、底部的加速度。


  2. dleft < L0:左側彈簧被壓縮,更新彈簧的長度及方向,計算彈簧的回復力,再更新木塊、兩側牆壁、底部的加速度。


  3. 以上2種狀況皆不成立:彈簧沒有被壓縮,將木塊、牆壁、底部的加速度設定為0。


接下來我測試了幾種參數的組合
  1. 壓縮量為 0.1 m
  2. 壓縮量為 0.2 m
  3. 壓縮量為 0.3 m
  4. 壓縮量為 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

沒有留言:

張貼留言