用ggb模擬物體運動的四種基礎(chǔ)方法(以豎直彈簧為例)
用ggb模擬物體運動的四種基礎(chǔ)方法(以豎直彈簧為例)
準(zhǔn)備工作
首先,輸入初始參數(shù),畫一個彈簧
初始參數(shù):重物質(zhì)量m=5, g=9.8, 彈簧原長l_0=10, 勁度系數(shù)k=10.
彈簧位置:創(chuàng)建原點O=(0,0),重物所在位置P=(x(O),y(O)-l_0).
畫彈簧:兩段線段segment(O,O-(0,1))以及segment(P,P+(0,1)). 彈簧本體用參數(shù)方程來畫較為方便(n為該段距離內(nèi)有多少個完整的周期),
從F-x關(guān)系出發(fā)的微元法(已知受力與物體位置的關(guān)系)
時間微元與時間:dt=0.01,t1=1,t=slider(0,40)
?
力矢量:F=vector((0,-m g)+(0,-k (y(P)+l_0)))
加速度矢量:a=F/m
速度矢量微元:dv=a*dt
速度矢量:v=(0,0)
位移矢量微元:dP=v*dt
?
初速度:v_0=0? //可隨意調(diào)節(jié)
重新定義重物位置:P=(0,-10)
?
按鈕1 重置:啟動動畫(t1,false);? 賦值(t,0);? 賦值(P,(x(O),y(O)-l_0));? 賦值(v,(0,v_0))? //此處P的初始位置也可隨意調(diào)節(jié),每次開始前要按一下重置按鈕。
?
按鈕2 開始:啟動動畫(t1,true)
按鈕3 暫停: 啟動動畫(t1,false)
?
t1腳本 更新時:賦值(t,t+dt);? 賦值(P,P+dP);? 賦值(v,v+dv).
?
從原長無處速度釋放的振幅:A=mg/k
速度箭頭:vector(P,P+v),設(shè)置標(biāo)題為“v”
y-t圖:(t,y(P)+l_0+A),顯示軌跡
?
?
數(shù)值解微分方程法(已知受力與物體位置的關(guān)系)
受力分析可知:F=-mg-k(y+l_0)
因此有微分方程組:??
?
創(chuàng)建初始值:
v_0=0;? x_0=-10;? //初始值可隨意調(diào)整
模擬運動的結(jié)束時間:t_f=50? //可隨意調(diào)整
?
計算軌跡:nsolveode({x’,v’},0,{x_0,v_0},t_f)? //可得兩個軌跡,第一個為x-t,第二個為v-t。
len=length(numericalIntegral1)? //測量該軌跡的點的個數(shù)
c=slider(0,1,1/len)? // 創(chuàng)建一個滑動條以便于在軌跡上描點
A=point(numericalIntegral1,c)? //其橫縱坐標(biāo)為對應(yīng)的時間與位移,即x-t圖
B=point(numericalIntegral2,c)? //其橫縱坐標(biāo)為對應(yīng)的時間與速度,即v-t圖
t=x(A)? //時間
P=(x(O),y(A))? //重新定義重物坐標(biāo)
?
?
直接模擬(已知位移與時間的關(guān)系)
創(chuàng)建時間:t=slider(0,50)? ?//進(jìn)入設(shè)置頁面將滑動條的速度設(shè)置為1/5
?
創(chuàng)建:偏離平衡位置的位移d=0
從原長釋放時的振幅:A_0=mg/k
原長處:y=-l_0
平衡位置:y=-l_0-A_0
實際的振幅:A=d
規(guī)定重物所到達(dá)的最低位置為零勢能面,則物體高度:h=y(P)+l_0+d+A_0
//(物體能到達(dá)的最低位置:y=-l_0-A_0-d,最高位置:y=-l_0-A_0+d)
?
重新定義重物位置:P=(x(O),)? //可隨意更改初相位
對上述關(guān)系式求導(dǎo)可得速度與時間的關(guān)系:
?
速度箭頭:vector(P,P+(0,v)),設(shè)置標(biāo)題為“v”
y-t圖:(t,y(P)+l_0+A_0),顯示軌跡
?
?
按鈕1 重置:啟動動畫(t,false);? 賦值(t,0);
按鈕2 開始:啟動動畫(t,true)
按鈕3 暫停: 啟動動畫(t,false)
?
?
?
從v-x關(guān)系出發(fā)的微元法(已知速度與物體位置的關(guān)系)
創(chuàng)建:偏離平衡位置的位移d=0
時間微元與時間:dt=0.01,t1=1,t=slider(0,40)
從原長釋放時的振幅:A_0=mg/k
原長處:y=-l_0
平衡位置:y=-l_0-A_0
實際的振幅:A=d
規(guī)定重物所到達(dá)的最低位置為零勢能面,則物體高度:h=y(P)+l_0+d+A_0
//(物體能到達(dá)的最低位置:y=-l_0-A_0-d,最高位置:y=-l_0-A_0+d)
//找到v-x關(guān)系:
速度:
? ? ? ? ? ?
重新定義重物位置:P=(0,-10)
?
?
?
按鈕1 重置:啟動動畫(t1,false);? 賦值(t,0);? 賦值(P, (x(O),y(O)-l_0-A_0+d));
按鈕2 開始:啟動動畫(t1,true)
按鈕3 暫停: 啟動動畫(t1,false)
?
?
?
以下操作包含了速度方向的判斷:
創(chuàng)建空列表:l1={}
t1腳本 更新時:
賦值(l1,insert(y(P),l1,1))? //獲取最新的y坐標(biāo)
if(t==0,賦值(P,P-(0,dt)))? //給一個微擾,讓模型啟動
賦值(t,t+dt)
if(length(l1)≥3,賦值(l1,take(l1,1,3)))??? //減小內(nèi)存,避免卡頓
?
if(l1(1)-l1(2)≤0&&y(P)+v_2*dt≥(-l_0-A_0-d) ∨y(P)+v_1*dt>-l_0-A_0+d ,賦值(P,P+v_2*dt))?? //這一步是速度小于零,即速度向下的情況,避免了在臨界點因模擬精度問題而導(dǎo)致的bug
if(l1(1)-l1(2)≥0&&y(P)+v_1*dt≤(-l_0-A_0+d) ∨y(P)+v_2*dt<-l_0-A_0-d ,賦值(P,P+v_1*dt))? //這一步是速度大于零,即速度向上的情況
?
速度矢量:v=vector((0,if(l1(1)-l1(2) ≤0,v_2,v_1)))
速度箭頭:vector(P,P+v),設(shè)置標(biāo)題為“v”
y-t圖:(t,y(P)+l_0+A_0),顯示軌跡
?
?
?
另:只知物體運動軌跡且物體速度大小不變時。
以勻速圓周運動為例:
半徑:r=5
圓心:A=(0,0)
圓周:c=circle(A,r)
速度大?。簐=2
滑動條:a=slider(0,1) ?//進(jìn)入設(shè)置,設(shè)置滑動條速度為v或者v/2等,以及重復(fù)方式為遞增,非遞增(一次)。
描點:B=point(c,a)
?
啟動滑動條a的動畫即可。
?
若要表示出速度矢量,則:
作切線:tangent(B,c)
在正確的方向上任取一點C,然后取向量BC:u=vector(B,C)
速度箭頭:vector(B,B+v*u/|u|),然后取標(biāo)題為v