使用 For 迴圈計算水平抛射資料
作者:王一哲
日期:2018/3/28
在前一篇文章〈水平抛射〉中,我們寫了一個模擬水平抛射運動的程式,再手動修高度 h 計算飛行時間 t 及水平射程 R。但是手動修改是很麻煩的,如果能多寫一個 for 迴圈,就能讓程式幫我們自動代入不同的 h 並將資料存成文字檔。以下共有兩個程式:
程式 5-4:水平抛射, 改變h, 記錄R (取得程式碼)
這個程式是程式 5-1 的簡化版,由於我只想算出飛行時間 t 及水平射程 R,小球碰到地板後就可以停止動畫,因此 while 迴圈中設定的條件為
手動修改 h,分別以 5、10、15、……50代入,再將計算得到的 t 和 R 手動輸入 SciDAVis 並作圖,這個作法雖然可行,但是相當費時。
數據處理原則
通常我們只用 XY 散布圖,而且只畫數據點,不會將數據點連線,畫完數據點之後再加上擬合直線式曲線。如果應變數與自變數的關係圖為曲線,還要想辦法化為直線,最後的成果一定要用線性擬合,還要解釋最接近直線的斜率、y軸截距的物理意義,要求相當嚴謹。使用 SciDAVis 畫 XY 散布圖的方法請參考另一篇文章〈SciDAVis繪圖:XY散布圖〉。
先畫 t - h 關係圖,由於圖形看起來像是二次曲線,就試著用多項式擬合,最高次方為二次,結果為
但這畢竟是猜測的結果,不一定正確。比較好的作法是取 、,畫 關係圖,畫出來的圖為斜直線,最接近直線為
由斜率可以猜測 。理論上
為了驗證這個猜測,新增一欄數據計算 ,畫 關係圖,畫出來的圖為斜直線,最接近直線為
理論上
理論值與模擬得到的值很接近,可以確定程式應該沒有問題。
Image Not Showing
Possible Reasons
- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →
於 SciDAVis 手動輸入數據
Image Not Showing
Possible Reasons
- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →
t - h 關係圖
Image Not Showing
Possible Reasons
- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →
log(t) - log(h) 關係圖
Image Not Showing
Possible Reasons
- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →
t - h1/2 關係圖
程式 5-5:水平抛射, 用for迴圈改變h, 記錄t、R (取得程式碼)
"""
VPython教學: 5-5.水平抛射, 用for迴圈改變h, 記錄t、R
Ver. 1: 2018/3/21
Ver. 2: 2018/6/13 加上用 matplotlib.pyplot 繪圖的部分
Ver. 3: 2019/10/10 改用 with 開啟檔案, 上課用的版本
作者: 王一哲
"""
from vpython import *
import matplotlib.pyplot as plt
"""
1. 參數設定, 設定變數及初始值
"""
size = 1
v0 = 5
L = 50
g = 9.8
dt = 0.001
data_y, data_x = [], []
"""
2. 畫面設定
"""
scene = canvas(title="Projectile", width=800, height=600, x=0, y=0, center=vec(0, 5, 0), background=vec(0, 0.6, 0.6))
floor = box(pos=vec(0, -size, 0), size=vec(L, 0.01, 10), texture=textures.metal)
with open("5-5_data.csv", "w", encoding="UTF-8") as file:
file.write("h(m), t(s), R(m)\n")
"""
3. 主程式
"""
def main(h):
t = 0
ball = sphere(pos=vec(-L/2, h, 0), radius=size, texture=textures.wood, make_trail=True,
v=vec(v0, 0, 0), a=vec(0, -g, 0))
while ball.pos.y - floor.pos.y > size + 0.5*floor.height:
rate(1000)
ball.v += ball.a*dt
ball.pos += ball.v*dt
t += dt
return t, ball.pos.x + L/2
"""
4. 用for迴圈改變h, 計算t、R, 寫入檔案
"""
for h in range(5, 51, 1):
t, r = main(h)
with open("5-5_data.csv", "a", encoding="UTF-8") as file:
file.write(str(h) + "," + str(t) + "," + str(r) + "\n")
data_y.append(t)
data_x.append(h)
plt.figure(figsize=(8, 6), dpi=100)
plt.xlabel(r'$h ~\mathrm{(m)}$', fontsize=16)
plt.ylabel(r'$t ~\mathrm{(s)}$', fontsize=16)
plt.xticks(fontsize=12)
plt.yticks(fontsize=12)
plt.grid(color='red', linestyle='--', linewidth=1)
plt.plot(data_x, data_y, marker='o', markerfacecolor='blue', markersize=8, color='skyblue', linewidth=3)
plt.savefig('t-h_plot.svg')
plt.savefig('t-h_plot.png')
plt.show()
Image Not Showing
Possible Reasons
- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →
程式 5-5 模擬結果畫面截圖
程式 5-5 當中運用了串列 (list) 及自訂函式 (def) 兩個新的物件,詳細的說明請參考另外兩篇講義〈串列〉、〈自訂函式〉 ,以下先說明與程式 5-4 的不同之處。
-
為了將資料儲存到文字檔中,需要加上以下的程式碼:
第一行程式碼用來開啟名稱為 5-5_data.csv 的文字檔,如果檔案已存在則覆蓋檔案內容,文字編碼為 UTF-8。第二行程式碼會在 5-5_data.csv 中寫入文字 h(m), t(s), R(m) 並換行。
-
第 34 ~ 42 行,用 def 自訂名為 main 的函式,輸入變數 h 數值,自動跑完小球落下的過程,回傳落下需要的時間 t 以及水平射程 ball.pos.x + L/2 。如果要讓動畫不要執行地太快,要在 while 迴圈當中加上 rate(1000)。
-
為了讓程式自動改變 h 的數值並代入後續的程式碼中運算,需要用到 for 迴圈。
h 的數值由 5 開始代入,每次增加 1,直到數量為 50 為止。將每個小球的飛行時間及水平射程回傳為 t 及 r,再用
將 h、t、r 轉為字串、用逗號分隔、寫入檔案。
-
由於是用 with 開啟檔案,不需要加上 file.close() 關閉檔案。
-
儲存到文字檔中的資料格式如下(取得檔案):
-
第 55 ~ 64 行的程式碼是利用 matplotlib 套件繪圖,如果想要用其它軟體讀取 5-5_data.csv 的資料並繪圖,可以刪除這幾行。
-
由於 GlowScript 網站上不能將資料儲存成文字檔,也不支援 matplotlib,可以使用以下的程式碼,將不支援的部分刪掉,並用 print 輸出需要的資料。程式碼第1行 Web VPython 3.2 是在網站上建立程式時自動産生的,會自動採用最新的版本,不需要手動輸入,也不需要再寫 from vpython import *,這是 GlowScript 動畫連結。
Image Not Showing
Possible Reasons
- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →
Image Not Showing
Possible Reasons
- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →
於 GlowScript 網站執行的結果
數據處理原則
仿照程式 5-4 的方法,先畫 t - h 關係圖,多項式擬合的結果為
再畫 關係圖,畫出來的圖為斜直線,最接近直線為
由斜率可以猜測 。接著新增一欄數據計算 ,畫 關係圖,畫出來的圖為斜直線,最接近直線為
斜率的理論值為 0.45175,理論值與模擬得到的值很接近,可以確定程式應該沒有問題。
Image Not Showing
Possible Reasons
- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →
t - h 關係圖
Image Not Showing
Possible Reasons
- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →
log(t) - log(h) 關係圖
Image Not Showing
Possible Reasons
- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →
t - h1/2 關係圖
Image Not Showing
Possible Reasons
- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →
使用 Matplotlib 繪製的 t - h 關係圖
結語
本文是以改變 h 為例,可以試著用相同的方法改變其它的變數值,例如改變空氣阻力的係數,找出飛行時間與空氣阻力係數的關係。而且用 for 迴圈自動改變數值,再將運算結果存入文字檔中,比手動改變數值所需要的時間少很多,這樣才能發揮寫程式的好處。
VPython官方說明書
- canvas: http://www.glowscript.org/docs/VPythonDocs/canvas.html
- box: http://www.glowscript.org/docs/VPythonDocs/box.html
- sphere: http://www.glowscript.org/docs/VPythonDocs/sphere.html
- texture: http://www.glowscript.org/docs/VPythonDocs/textures.html