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