日期:2018/3/7
終於要開始做物理模擬動畫,我們先從最單純的等速度直線運動開始,目標是畫出木塊、地板以及木塊的 x-t 圖、 v-t 圖,成果如下:GlowScript 網站動畫連結
等速度直線運動畫面截圖
木塊的 x-t 圖
木塊的 v-t 圖
程式 3-1:等速度直線運動
取得程式碼
"""
VPython教學: 3.等速度直線運動
Ver. 1: 2018/2/18
Ver. 2: 2019/9/5
作者: 王一哲
"""
from vpython import *
"""
1. 參數設定, 設定變數及初始值
"""
size = 0.1 # 木塊邊長
L = 1 # 地板長度
v = 0.03 # 木塊速度
t = 0 # 時間
dt = 0.01 # 時間間隔
"""
2. 畫面設定
"""
scene = canvas(title="1D Motion", width=800, height=600, x=0, y=0, center=vec(0, 0.1, 0), background=vec(0, 0.6, 0.6))
floor = box(pos=vec(0, 0, 0), size=vec(L, 0.1*size, 0.5*L), color=color.blue)
cube = box(pos=vec(-0.5*L + 0.5*size, 0.55*size, 0), size=vec(size, size, size), color=color.red, v=vec(v, 0, 0))
#cube = box(pos=vec(-0.5*L + 0.5*size, 0.55*size, 0), length=size, height=size, width=size, color=color.red, v=vec(v, 0, 0))
gd = graph(title="x-t plot", width=600, height=450, x=0, y=600, xtitle="t(s)", ytitle="x(m)")
gd2 = graph(title="v-t plot", width=600, height=450, x=0, y=1050, xtitle="t(s)", ytitle="v(m/s)")
xt = gcurve(graph=gd, color=color.red)
vt = gcurve(graph=gd2, color=color.red)
"""
3. 物體運動部分, 木塊到達地板邊緣時停止執行
"""
while(cube.pos.x <= 0.5*L- 0.5*size):
rate(1000)
cube.pos.x += v*dt
xt.plot(pos = (t, cube.pos.x))
vt.plot(pos = (t, cube.v.x))
t += dt
print("t = ", t)
如果將程式碼用 Python IDLE 的編輯器開啟,在預設狀態下看到的顏色應該會很類似上面的樣子,編輯器會自動將在 Python 中有特殊功能的保留字、引號內的文字、註解等用不同的顏色標示出來,這樣能便於閱讀程式碼。Python 有兩種註解方釋
- 多行註解:於兩行 """ 之間或兩行 '''的文字
- 單行註解:於 # 之後到該行結束為止的文字
直譯器在執行程式碼時會忽略註解的部分,雖然註解對程式運作沒有幫助,但是對使用者而言非常重要,如果沒有寫註解,很有可能連作者本人在過了幾天之後也忘記自己在寫什麼,更不用說要讓其他使用者看懂程式碼,所以請務必養成寫註解的習慣。
我習慣在一開始先寫清楚程式的名稱、功能、日期及作者,接下在參數設定之前寫上
from vpython import *
這是 Python 引用函式庫的語法,在預設狀態下不會引用 vpython 這個做物理模擬用的函式庫,所以我們需要加上這行程式碼,意思是從 vpython 這個函式庫引用所有的 函式。另外也可以寫成
importm vpython as 自訂名稱
假設自訂名稱為 vp ,則要引用 vpython 中的函式時需要寫 vp.[函式名稱];如果只寫importm vpython,則要引用 vpython 中的函式時需要寫 vpython.[函式名稱]。由於我們是以做動畫為主,建議採用第一種寫法,這樣在引用 vpython 中的函式時只需要寫函式名稱就可以了。
整個程式大約可以分成三個部分:
- 參數設定
- 畫面設定
- 物體運動
參數設定
在參數設定部分,我習慣將一些在程式常中會不斷用到的數值指定到對應的變數中,並幫這些變數取一些容易看懂的名稱。雖然 Python 3.X 版已經支援 Unicode,可以使用中文作為變數名稱,但還是建議以英文字母、數字及底線作為變數名稱,其中英文字母區分大小寫,變數名稱開頭不能為數字,不能使用系統保留字。理論上可以按照自己的喜好命名變數,但為了便於理解變數的用途,最好使用有意義的名稱,例如將木塊大小取名為 size。
我在此定義的變數有 size、L、v、t、dt,用途都已經寫在該行的註解中。其中時間間隔 dt 的數值要視實際需求調整,這是因為 VPython 是利用數值方法計算物體的受力、加速度、速度、位移……等物理量,如果代入的時間長度太長,得到的數值會有較大的誤差;但如果代入的時間長度太短,整個模擬動畫執行的時間會拉長。目前設定的值為 0.01,對這個模擬動畫而言已經夠精準了。
畫面設定
我們會用到的函式為 canvas、box、graph、gcurve,以下分別說明這幾個函式的語法。
canvas
canvas 是英文的帆布、畫布,在 VPython 中用來產生顯示動畫的畫面,目前是藉由瀏覽器來顯示,Google Chrome 或 FireFox 都可以,理論上 Windows Edge 應該也行,不過我完全不用 Windows Edge 所以就沒有測試。[1] 在 VPython 6 以及更早的版本,函數名稱是 display,執行時會另外開啟視窗。畫面中右方為 +x 軸方向,上方為 +y 軸方向,射出螢幕方向為 +z 軸方向。在這個程式中我將開啟的動畫視窗命名為 scene(英文,場景)。通常會調整的選項為:
- title: 畫面的標題,顯示於畫面的左上角。
- width: 畫面寬度(水平方向)。
- height: 畫面高度(鉛直方向)。
- x、y: 畫面左上角於瀏覽器視窗中顯示的位置,不過看起來 VPython 會依照已經存在的物件寬度、高度自動調整。
- center: 代表觀察者所在位置。
- background: 背景顏色,vector 括號中的數字依序為紅、綠、藍三原色的比例,範圍在 0 ~ 1 之間。另外也可以使用已經命名的常用顏色。[2]
box
box 是英文的箱子、盒子,在 VPython 中用來產生長方體,在這個程式中木塊 cube 和地板 floor 都是藉由 box 產生的。[3] 通常會調整的選項為:
- pos: 長方體中心的位置,數值為向量,vector(x, y, z),vector 也可以簡化為 vec。
- length、height、width 分別為 x、y、z 方向的長度,也可以簡化為 size = vector(x, y, z)。
- color: 長方體的顏色。
graph graph 是英文的圖,在 VPython 中用來產生繪圖視窗,在 VPython 6 以及更早的版本,函數名稱是 gdisplay。 [4] 在這個程式中我將兩個繪圖視窗分別命名為 gd 和 gd2,分別用來畫木塊的 x-t 圖和 v-t 圖。通常會調整的選項和 canvas 相似,title、width、height、x、y 的功能已經介紹過了,這畫用到較不同的選項為:
- xtitle: x 軸名稱。
- ytitle: y 軸名稱。
gcurve gcurve 在 VPython 中用來於繪圖視窗上畫出連續的曲線,在這個程式當中兩個曲線分別命名為 xt、vt,分別顯示於 gd 及 gd2 。通常會調整的選項為:
- graph: 顯示於哪一個繪圖視窗。
- color: 曲線的顏色。
物體運動
利用一個 while 迴圈每隔一小段時間 dt 更新一次物體的狀態,由於我希望當木塊到達地板邊緣時程式停止運作,因此在 while 裡設定的條件為cube.pos.x <= 0.5*L- 0.5*size
接下來逐行說明程式碼的用途。
- rate(1000) 是指每秒更新動畫1000次。
- cube.pos.x += v*dt 用來更新木塊的位置,cube.pos.x 用來讀取 cube 位置的 x 座標,將讀取到的值加上速度 v 乘以一小段時間 dt ,再重新指定給 cube 位置的 x 座標。
- xt.plot(pos = (t, cube.pos.x)) 用來畫木塊的 x-t 圖,線段的橫軸位置為時間 t ,縱軸位置為木塊位置 cube.pos.x。
- vt.plot(pos = (t, cube.v.x)) 用來畫木塊的 v-t 圖,線段的橫軸位置為時間 t ,縱軸位置為木塊速度 cube.v.x。
- t += dt 用來更新時間,將 t 加上 dt ,再重新指定給 t,寫法等同於 t = t + dt。
結語
雖然這個動畫的效果非常單純,甚至不需要動畫應該就能想像出物體運動的樣子。但也因為如此,很適合作為第一個動畫,只要動畫有任何不符合物理原理的地方都很容易看出來。之後會再把加速度、力量、角度……等更多的物理量加到動畫中。VPython官方說明書
- canvas: http://www.glowscript.org/docs/VPythonDocs/canvas.html
- color: http://www.glowscript.org/docs/VPythonDocs/color.html
- box: http://www.glowscript.org/docs/VPythonDocs/box.html
- graph: http://www.glowscript.org/docs/VPythonDocs/graph.html
HackMD 版本連結:https://hackmd.io/@yizhewang/HJ7Ejj-GX
沒有留言:
張貼留言