---
# System prepended metadata

title: 'Lesson06: 直線運動'
tags: [多元選修, vpython, 運動科學模擬, 直線運動]

---

<font color=#008000>
    
>作者: 吳姿瑩
>更新:2022.10.21 
</font>[color=#008000]

# Lesson06: 直線運動
###### tags: `運動科學模擬` `多元選修` `vpython` `直線運動`

<iframe width="560" height="315" src="https://www.youtube.com/embed/eozi69ZP908" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

## :memo:引用函式庫
vpython是在python語法下使用，可將物體視覺化展先出來，並同步可繪畫出相關物理上變數，利用視覺化的方式展現！
故使用上語法和python雷同，而相關使用視覺上的展現須引入vpython的函式庫，寫法如下：
```javascript!=1
from vpython import *
```
- 每個程式語言都以 ==“Hello World!”== 開始吧！
```javascript!=2
text(text='Hello World', pos=vec(0,0,0),color=color.cyan, 
     billboard=True, emissive=True)
```
1. **位置vec**
其中vec表示vector向量，表這文字text放置的位置在此畫布canvas中所在的位置。
向量皆以3維表示，即為(x,y,z)。
:::spoiler **學生活動**
請更改向量的大小位置，試問vpython中三個向量(x, y, z)的方向順序分別為何？
:::

2. **顏色**
顏色的選擇為cyan青色，vpython可選的顏色為red, green, blue, purple, yellow, orange, cyan, magenta, black, white，同時也可使用HSV顏色語法來表示

```javascript!=3
text(text='Hello World', pos=vec(0,5,0),
     color=color.hsv_to_rgb(vector (60/255, 100/255, 100/255)) , 
      billboard=True, emissive=True)
```

3. **billboard**
billboard為vpython下text的語法，使用billboard只能唯讀顯示，不能做移動互動式的改變。


4. **觀看視角遠近**
嘗試將手指縮放，所看到的視角遠近皆會改變，也是在3D視覺化展現出來，可以從各個面向觀看運動狀態！

:::spoiler 參考網址
1.色碼表RGB :https://www.ifreesite.com/color/online-color-picker.htm
2.vpython color相關使用語法: https://www.glowscript.org/docs/VPythonDocs/color.html
3.vpython text相關使用語法：https://www.glowscript.org/docs/VPythonDocs/text.html
:::

:::spoiler 學生作業
1. Homework: 請利用vpython，進行文字顯示，將其==文字呈現於畫布正中央==，
    請將==程式code以及結果截圖== 至google classroom繳交作業。
2. 完成今日協作平台更新
3. 將code上傳至雲端硬碟中(Lesson06 vpython直線運動)
:::

## :memo:Step1 參數設定
寫程式時通常會將變數寫在最上方，如：運動質點的初速度、加速度等等參數，下方程式碼使用的變數亦用符號代表；未來欲改變不同情境時，可快速的在變數中更改，即可看到運動呈現，無需再至底下的程式當中更改，直接更改最上方參數變數即可。
```javascript!=1
from vpython import *

size = 0.05   # 木塊邊長
L = 1.55      # 地板長度
v = 0.05      # 木塊速度
t = 0         # 時間
dt = 0.01     # 時間間隔
```
其中dt為時間間隔，使用vpython畫出每一時刻的運動狀態以及運動相關數值，故將時間切的很細時，程式將會執行時間拉長，反之，將時間間隔拉很長時，許多細節並未紀錄到，會有較大的誤差，故將==時間間隔設置在0.01==呈現效果即可展現！

## :memo:Step2 畫布、圖表相關設置

- 3D的VPython畫布canvas名稱稱為==scene==，執行時會另外開啟視窗。canvas畫面中右方為 +x 軸方向，上方為 +y 軸方向，射出螢幕方向為 +z 軸方向。畫布的名稱可稱為自己的名稱scene，
```javascript!=8
scene = canvas(title="1D Motion", caption='等速運動', 
               width=640, height=400, x=0, y=0, center=vec(0, 0.3, 0),
               background=vec(204/255,204/255,255/255))
```
1. title 畫布名稱
訂定的名稱，會顯現在畫布的左上角
2. caption 畫布標題
訂定畫布的標題，會顯現在畫布的左下角
3. 畫布的大小
利用width, height來設置畫布大小，其中單位為像素pixel，預設值為width= 640，height= 400。
4. 畫布位置
x、y 表畫面於視窗中顯示的位置。
5. center
center表觀察者的位置，雖視角可以由滑鼠移動改變，一開始的觀察者視角可由座標軸訂定。
6. background 顏色
使用向量表示，此方式為不同方式，是利用RGB的顏色表來表示，每個數值用0~1來表示。


:::spoiler 參考網址
1. vpython canvas設置 :https://www.glowscript.org/docs/VPythonDocs/canvas.html
2. vpython 可畫的物品 :https://vpython.org/contents/docs/primitives.html
3. 色碼表RGB :https://www.ifreesite.com/color/online-color-picker.htm
:::

---
- 設置地板==floor(名稱為floor)==，利用vpython中的物件box，畫一個極薄的地板，使用的尺度為Step1的參數設定。
```javascript!=11
floor = box(pos=vec(0, 0, 0), size=vec(L, 0.01*size, 0.5*L), 
            color=color.green)
```
1. 向量表示亦為畫面中右方為 +x 軸方向，上方為 +y 軸方向，射出螢幕方向為 +z 軸方向，故在 y方向設置厚度極薄(與箱子相比極為薄)

2. box的位置使用vec來設定，其中位置為box的正中心，故將位置設置在 (0, 0, 0)，即在畫布的正中央處。



---

- 設置==木塊(名稱為cube)==，利用vpython中的物件box，畫一木塊
```javascript!=13
cube = box(pos=vec(-0.5*L + 0.5*size, 0.5*size+0.01*size, 0), 
           length=size, height=size, width=size, 
           color=color.red, v=vec(v, 0, 0))
```
1. 木塊box的位置pos(即position位置之意)由最左端移動至最右端，其中須考量木塊box的厚度，以及地板的厚度，才能將其木塊放置於地板上。


:::spoiler 參考網址
vpython box設置 :https://vpython.org/contents/docs/box.html
:::

---

- 圖表畫圖大致流程如下：
```flow
st=>start: 開畫布graph(gd)
e=>end: 結束
cond=>condition: 選擇畫圖方式 gcurve(xt)
op=>operation: 每一秒資訊寫入圖中 xt.plot


st->cond->op
cond(yes@True)->op
```

設置圖==graph==，物理上常會繪畫出x-t, v-t, a-t圖來確認斜率以及運動的狀態，所以要畫一圖即要開一個畫布graph讓每一時刻的資料 (如：位置x, 速度v, 加速度a 等等) 可以寫入。
```javascript!=16
gd = graph(title="x-t plot", width=600, height=450,
           xmax=35, x=0, y=600, xtitle="t(s)", ytitle="x(m)")

gd2 = graph(title="v-t plot", width=600, height=450,
            ymin=0, ymax=0.1, 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)
```
1. 開畫布gd 為 x - t圖，開畫布gd2 為 v - t圖
2. gd的畫法為gcurve，將每一時刻的資料點利用連續曲線來表示，其中畫出來的曲線儲存至gd圖中！
3. graph 的語法中有一x, y 數值，其中(x,y)為在瀏覽器打開的頁面中所在的位置！故可從語法中知，gd圖的位置會在gd2的位置之上。

:::spoiler 參考網址
vpytohn graph相關語法：https://vpython.org/contents/docs/graph.html
:::

## :memo:Step3 物體的運動
最後一步即是最富含有物理概念的部分，我們的挑戰即為，要將物理概念簡單的數學形式，寫成程式語言！

```javascript!=25
while(cube.pos.x <= 0.5*L- 0.5*size):
    rate(1000)
    cube.pos.x += v*dt          #x=x0+v*dt
    xt.plot(pos = (t, cube.pos.x))
    vt.plot(pos = (t, cube.v.x))
    t += dt
```
1. 利用while迴圈，當木塊達到畫布右端時（考量木塊厚度）即停止程式
2. rate(1000)即表每秒更新動畫1000次
3. 設置木塊的名稱稱為cube，每秒更新的資訊為木塊的 x 座標位置，故將每時間間距 dt 所移動距離，累加至木塊cube位置的 x 資訊。
4. 每一時刻所更新資訊，皆畫至xt, vt 圖中，橫軸資訊為 t，縱軸資訊為木塊的 x位置(cube.pos.x)與 x方向的速度(cube.v.x)。 
5. 儲存完資訊則更新時間間隔資訊 t += dt ，即 t = t + dt 。


:::spoiler **直線運動 完整程式碼**
```javascript=
"""
Auther   :吳姿瑩
Date     :2022/08/17
version  :python3.10.6 vpython7
chapter  :直線運動
"""

from vpython import *

"""
 1. 參數設定, 設定變數及初始值
"""
size = 0.05   # 木塊邊長
L = 1.55      # 地板長度
v = 0.05      # 木塊速度
t = 0         # 時間
dt = 0.01     # 時間間隔



"""
 2. 畫面設定
"""
#畫面設定，預設為 640 and 400 像素
#scene:backgroung有三個數字唯色碼表，https://www.ifreesite.com/color/online-color-picker.htm
scene = canvas(title="1D Motion",caption='等速運動', width=640, height=400, x=0, y=0, center=vec(0, 0.3, 0), background=vec(204/255,204/255,255/255))
floor = box(pos=vec(0, 0, 0), size=vec(L, 0.01*size, 0.5*L), color=color.green)
cube = box(pos=vec(-0.5*L + 0.5*size, 0.5*size+0.01*size, 0), length=size, height=size, width=size, color=color.red, v=vec(v, 0, 0))
#畫x-t圖v-t圖設定畫布
#找停止時間，設置x-t圖，x軸最大值
gd = graph(title="x-t plot", width=600, height=450,xmax=35, x=0, y=600, xtitle="t(s)", ytitle="x(m)")
gd2 = graph(title="v-t plot", width=600, height=450,ymin=0, ymax=0.1, 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          #x=x0+v*dt
    xt.plot(pos = (t, cube.pos.x))
    vt.plot(pos = (t, cube.v.x))
    t += dt

print("所需時間為t = ", t)
```
:::

:::spoiler **學生作業**
1. Homework: 試算木塊直線移動了2(m)，初速度為0.05(m/s)[==注意：木塊厚度、地板長度==]，所需時間為何？
Requirements要求:
(1)需畫出木塊移動
(2)需畫出木塊x-t圖，v-t圖
(3)需在idle中顯現出移動時間

2. 請將==程式code以及瀏覽器結果截圖、IDLE所需時間螢幕截圖== 至google classroom繳交作業。
3. 完成今日協作平台更新
4. 將code上傳至雲端硬碟中(Lesson06 vpython直線運動)
:::


## :memo:參考網址
1. 色碼表RGB :https://www.ifreesite.com/color/online-color-picker.htm
2. vpython color相關使用語法: https://www.glowscript.org/docs/VPythonDocs/color.html
3. vpython text相關使用語法：https://www.glowscript.org/docs/VPythonDocs/text.html
4. vpython canvas設置 :https://www.glowscript.org/docs/VPythonDocs/canvas.html
5. vpython 可畫的物品 :https://vpython.org/contents/docs/primitives.html
6. vpython box設置 :https://vpython.org/contents/docs/box.html
7. vpytohn graph相關語法：https://vpython.org/contents/docs/graph.html