Loading [MathJax]/jax/output/HTML-CSS/jax.js

熱門文章

2020年7月9日 星期四

兩個木塊的簡諧運動

作者:王一哲
日期:2020/7/9

題目(改編自101指考非選題二)


質量分別為 Mm 的木塊放置於光滑水平面上,兩個木塊之間以彈性常數為 k 的理想彈簧連接。若將兩個木塊向內壓縮 ΔL 再由靜止釋放木塊,試求以下的物理量。

  1. 木塊做簡諧運動週期
  2. 木塊做簡諧運動的最大速率
  3. 木塊做簡諧運動的振幅





理論分析


木塊做簡諧運動週期


若將 x 軸的原點設定在 M 的位置,則質心與 M 之間的距離為

xC=mLM+m

由於系統的質心位置固定,可以將彈簧從質心位置分割為左、右兩段,長度比為 m:M ,其彈性常數分別為

kM=M+mmk

km=M+mMk

兩個木塊做簡諧運動的週期分別為

TM=2πMk1=2πMm(M+m)k

Tm=2πmk2=2πMm(M+m)k

兩個木塊做簡諧運動的週期相等,這樣系統質心位置才會固定,這是合理的計算結果。另一種方法是利用約化質量 (reduced mass)

μ=MmM+m

簡諧運動的週期為

T=2πμk=2πMm(M+m)k



2022/5/15 補充說明約化質量的推導過程

假設木塊 M 受的到作用力為 FM,木塊 m 受的到作用力為 Fm,由於兩者之間用彈簧連接,Mm、彈簧系統水平方向沒有外力,因此 FM+Fm=0  Fm=FM 兩者的加速度分別為 aM=FMM     am=Fmm=FMm=MmaM M 相對於 m 的加速度為 aMm=aMam=(1+Mm)aM=M+mmFMM  FM=MmM+maMm 若定義約化質量 μ=MmM+m 則上式可改寫為 FM=μaMm 運用約化質量,可以將兩個物體的運動,簡化成其中一個物體相對於另一個物體的運動。


木塊做簡諧運動的最大速率


由於系統水平方向不受外力作用,系統動量守恆,兩個木塊的動量

pM+pm=0  pM=pm

當彈簧回到原長時、木塊到達平衡點,此時兩個木塊的動能比為

KM:Km=p2M2M:p2m2m=m:M

由於系統力學能守恆,由彈簧被壓縮 ΔL 時與彈簧回到原長時可得

12k(ΔL)2=KM+Km

若將

Km=MmKM

代入上式可得

12k(ΔL)2=KM(1+Mm)  KM=mk(ΔL)22(M+m)

Km=Mmmk(ΔL)22(M+m)=Mk(ΔL)22(M+m)

兩個木塊的最大速率分別為

vM=2KMM=2Mmk(ΔL)22(M+m)=mkM(M+m)ΔL

vm=2Kmm=2mMk(ΔL)22(M+m)=Mkm(M+m)ΔL




木塊做簡諧運動的振幅


由於系統的質心位置固定,因此兩個木塊離開平衡點的距離與質量成反比,兩者的振幅比

RM:Rm=m:M

但是彈簧的最大壓縮量為 ΔL,因此

RM+Rm=ΔL

由以上兩式可得

RM=mM+mΔL

Rm=MM+mΔL




驗算木塊做簡諧運動的最大速率


配合先前得到的簡諧運動週期可得兩者的最大速率分別為

vM=2πRMT=2πmM+mΔL12π(M+m)kMm=mkM(M+m)ΔL

vm=2πRmT=2πMM+mΔL12π(M+m)kMm=Mkm(M+m)ΔL




VPython 模擬


以下是使用 VPython 模擬的程式碼以及 GlowScript 網站動畫連結,程式碼中的變數值與題目的物理量關係如下:

  1. 木塊1的質量為 M=m1=0.2 kg
  2. 木塊2的質量為 m=m2=0.1 kg
  3. 彈簧的彈性常數 k=5.0 N/m
  4. 彈簧初始壓縮量 ΔL=dL=0.5 m



模擬畫面截圖



"""
 VPython教學: 14-2.水平彈簧與木塊組成的雙重簡諧運動, 101指考題
 日期: 2020/7/9
 作者: 王一哲
"""

from vpython import *

"""
 1. 參數設定, 設定變數及初始值
"""
d1, m1, c1 = 0.2, 0.2, color.red     # 木塊1的質量、初速、顏色
d2, m2, c2 = 0.2, 0.1, color.green   # 木塊2的質量、質量、初速、顏色
L0, k, dL = 1.0, 5.0, 0.5            # 彈簧的原長 L0=1 m, 彈性常數 k=5.0 N/m, 最大壓縮量 dL=0.5 m
t, dt = 0, 0.00005                   # 時間, 時間間隔

"""
 2. 畫面設定
"""
# 產生動畫視窗
scene = canvas(title="Double Simple Harmonic Motion", width=800, height=300, 
               background=vec(0, 0.6, 0.6), range=0.7*L0)
# 產生左側木塊 b1, 右側木塊 b2
b1 = box(pos=vec(-0.5*L0-0.5*d1, 0, 0), size=vec(d1, d1, d1), color=c1, v=vec(0, 0, 0))
b2 = box(pos=vec(0.5*L0+0.5*d2-dL, 0, 0), size=vec(d2, d2, d2), color=c2, v=vec(0, 0, 0))
# 產生彈簧, 起點為 b1.pos, 方向為 b2.pos - b1.pos
spring = helix(pos=b1.pos+vec(0.5*d1, 0, 0), axis=b2.pos-b1.pos-vec(0.5*(d1+d2), 0, 0),
               radius=0.3*d1, thickness=0.1*d1)
# 產生地板
floor = box(pos=vec(0.5*(b1.pos.x+b2.pos.x), -0.75*d2, 0),
            size=vec(2.2*L0, 0.5*d2, 0.8), color=color.blue)
scene.center = floor.pos+vec(0, 0.2, 0)
# 繪圖部分
gd = graph(title="<i>x</i> - <i>t</i> plot", x=0, y=300, width=600, height=450, xtitle="<i>t</i> (s)",
           ytitle="red: <i>x</i><sub>1</sub>, green: <i>x</i><sub>2</sub> (m)")
xt1 = gcurve(graph=gd, color=c1)
xt2 = gcurve(graph=gd, color=c2)
gd2 = graph(title="<i>v</i> - <i>t</i> plot", x=0, y=750, width=600, height=450, xtitle="<i>t</i> (s)",
            ytitle="red: <i>v</i><sub>1</sub>, green: <i>v</i><sub>2</sub> (m/s)")
vt1 = gcurve(graph=gd2, color=c1)
vt2 = gcurve(graph=gd2, color=c2)

"""
 3. 物體運動部分
"""
T0 = 2*pi*sqrt(m1*m2/(k*(m1+m2)))    # 簡諧運動週期理論值
R1, R2 = m2*dL/(m1+m2), m1*dL/(m1+m2)# 簡諧運動振幅理論值
vp1, vp2 = 0.0, 0.0
xp1, xp2 = b1.pos.x, b2.pos.x
count1, count2 = 0, 0
print("週期理論值 T0 = {:f} s".format(T0))
print("振幅理論值 R1 = {:f} m, R2 = {:f} m".format(R1, R2))

while t <= 3*T0:
    rate(1000)
# 更新彈簧的起點位置、長度、方向
    spring.pos = b1.pos+vec(0.5*d1, 0, 0)
    spring.axis = b2.pos-b1.pos-vec(0.5*(d1+d2), 0, 0)
# 計算彈簧回復力,更新小球的加速度、速度、位置
    force = -k*(spring.axis.mag - L0) * spring.axis.norm()
    b1.a = -force/m1     
    b2.a = force/m2
    b1.v += b1.a * dt
    b2.v += b2.a * dt
    b1.pos += b1.v * dt
    b2.pos += b2.v * dt
# 檢驗木塊是否經過一個週期
    vc1, vc2 = b1.v.x, b2.v.x
    if vp1 > 0 and vc1 < 0:
        print("木塊1經過一個週期, 此時 t = {:f} s".format(t))
    if vp2 < 0 and vc2 > 0:
        print("木塊2經過一個週期, 此時 t = {:f} s".format(t))   
# 計算木塊的振幅
    if vp1 < 0 and vc1 > 0 and count1 == 0:
        xc1 = b1.pos.x
        print("木塊1振幅 R1 = {:f} m".format(abs(xc1-xp1)/2))
        xp1 = xc1
        count1 += 1
    if vp2 > 0 and vc2 < 0 and count2 == 0:
        xc2 = b2.pos.x
        print("木塊2振幅 R2 = {:f} m".format(abs(xc2-xp2)/2))
        xp2 = xc2
        count2 += 1
# 更新 vp1, vp2
    vp1, vp2 = vc1, vc2
# 畫 x-t 圖, v-t 圖
    xt1.plot(pos=(t, b1.pos.x))
    xt2.plot(pos=(t, b2.pos.x))
    vt1.plot(pos=(t, b1.v.x))
    vt2.plot(pos=(t, b2.v.x))
# 更新時間
    t += dt



模擬結果如下,週期模擬值與理論值的差異是由程式碼中採用的時間間隔 dt = 0.00005 造成的,振幅的模擬值與理論值完全相同。

週期理論值 T0 = 0.725520 s
振幅理論值 R1 = 0.166667 m, R2 = 0.333333 m
木塊1振幅 R1 = 0.166667 m
木塊2振幅 R2 = 0.333333 m
木塊1經過一個週期, 此時 t = 0.725500 s
木塊2經過一個週期, 此時 t = 0.725500 s
木塊1經過一個週期, 此時 t = 1.451000 s
木塊2經過一個週期, 此時 t = 1.451000 s
木塊1經過一個週期, 此時 t = 2.176550 s
木塊2經過一個週期, 此時 t = 2.176550 s




x - t




v - t



結語


此題原為101年指考物理非選題二,原版的題目及參考解答請參考大考中心的網站(題目參考解答)。原版的題目中第3小題是要求 M 的振幅,我在上課時曾經試著用質心位置固定以外的方法解題,但是效果似乎不太好,再加上學生不容易想像木塊的運動方式,所以我寫了完整的理論計算以及模擬動畫,希望能幫助學生理解這個題目。






HackMD 版本連結:https://hackmd.io/@yizhewang/SyN30IX1w

5 則留言:

  1. 作者已經移除這則留言。

    回覆刪除
  2. 你好 我想請問一個vpython的問題
    假設我製造兩塊木板 一塊斜面一塊平面
    再製造一顆球體由上滾落 重量設為1 斜板長度4.9 平板長度20 球半徑0.2
    我可以讓他滾下來
    但是今天如果要賦予球跟板子摩擦力
    讓球滾落時會因摩擦力而停下
    請問該怎麼寫呢
    若需要看我寫的程式碼請留言跟我說
    謝謝了

    回覆刪除
    回覆
    1. 假設小球半徑為 r,在斜面上為純滾動,小球所受的重力平行斜面分量為 mg sin θ 平行斜面方向向下,斜面對小球的摩擦力為 f 沿著平行斜面方向向上,合力產生的加速度為a,角加速度為 α,則

      mg sin θ -f = ma
      fr = Iα

      其中 I 為小球相對於質心的轉動慣量。由於小球與斜面接觸的點沒有滑動,因此 a = rα。當小球到達地面時,理論上小球與地面會有相對滑動,這部分就很麻煩了......

      刪除
    2. 謝謝老師的解釋
      不過我要把他轉換到Python上還是有點難
      總是會在撞到平面的時候直接停下來
      不然就是到平面的時候直接等速度滾過去了

      刪除
    3. 這需要看到程式碼才能除錯,但通常是 if 的條件沒有設定好,需要再修改一下。

      刪除