回上方

Lecture 1 迴圈與物件控制

建國高中特色選修課程 - 物理現象的程式設計與模擬
作者:曾靖夫
日期:2018/7/1


一、Vpython的物件插入

Vpython為Python程式的外掛套件之一,Vpython的優點是有很多視覺化套件可以使用簡單的指令插入,它的繪圖功能簡單,呈現的效果具體。很適合將物理中的方程式透過python的運算,然後用圖像的方式顯現出來,能幫助同學更具體理解物理觀念與現象。

1. sphere(球形物件):

ball = sphere(pos=vector(1,2,1), radius=0.5, color=color.blue)

  • 指令說明
    ball:為這個球形物件的「名稱」。
    pos:為ball這個物件的座標,Vpython的預設座標如上圖所示。
    radius:為ball的半徑長度。
    Color:為ball的顏色,以color.blue設為藍色。

2. box(盒狀物件):

mybox = box(pos=(x0,y0,z0), length=L, height=H, width=W)

  • 指令說明
    length:沿著x軸的長度。
    height:沿著y軸的長度。
    width:沿著z軸的長度。
    axis:為mybox的「軸方向」,預設為沿x方向。

3. cylinder(柱狀物件):

rod = cylinder(pos=vector(0,2,1), axis=vector(5,0,0), radius=1)

  • 指令說明
    pos:為rod的尾端位置座標。
    axis:為rod的軸方向,axis為由尾端指向頭端的向量。如右圖所示,rod的尾端座標相對於頭端座標即是axis,故其尾端座標為(x0,y0,z0)+(L,0,0)

4. arrow(箭形物件):

x = arrow(pos=vector(0,0,0), axis=vector(1,0,0), color=color.green)
y = arrow(pos=vector(0,0,0), axis=vector(0,1,0), color=color.red)
z = arrow(pos=vector(0,0,0), axis=vector(0,0,1), color=color.blue)

  • 指令說明
    這裡我們值些使用箭頭來表示圖像化向量的概念,指令中描述Vpython三維立體座標的x、y、z三個方向的單位向量。

5. helix(螺線物件):

spring = helix(pos=vector(0,2,1), axis=vector(5,0,0), radius=0.5)
  • 指令說明
    這也是一個長條形的物件,在物理中可以畫「彈簧」,基本上長條物件的指令與cylinder和arrow都差不多,僅差在一些圖形比例調整的指令。

二、Vpython 7 官方網頁

有關 Vpython 7 的所有物件指令,這裡沒有足夠的篇幅一一介紹,請同學養成習慣查詢官方網頁:http://www.glowscript.org/docs/VPythonDocs/VisualIntro.html
有少部份指令舊版的說明較完整一點點,也可以參考看看,Vpython 6 官方網頁:http://vpython.org/contents/docs/VisualIntro.html


三、向量的概念與應用

從前面的物件指令控制,同學們應該已經發現「空間向量」的慨念被廣泛的應用在python的程式運算上。在數學上,凡是有「大小」與「方向」的東西都可以用向量來表示,特別是在幾何學中的應用甚多。而在物理學中,同時需要清楚描述「大小」與「方向」的物理量更是不勝枚舉,比如位置、位移、速度、加速度、作用力、重力場、電場、磁場…等。
以下我們以二維向量為例,簡單介紹向量在物理中的應用:

1. 位置向量

用來描述物體在空間中相對於原點的位置,即是由原點指向物體的向量。圖中紅色箭頭為沿著x和y軸的單位向量。所有的向量都可以此為基本單位合成出來。

2. 向量的加法與減法(二維向量範例)

原則上物理學中的向量概念都是3D立體的空間向量,以上為方便繪製簡圖,因此僅以平面向量為例,但同學請注意在程式中都需要寫立體的向量!

3. 位移向量

假設物體由A點運動到B點,則位移可以表示為Δr

Δr=rBrA=(BxAx,ByAy,BzAz)

其中 rB 為末位置、rA 為初位置。

4. 速度向量

物體每單位時間的位移

v=ΔrΔt=(vx,vy,vz)

其中 Δt 如果足夠小,即為瞬時速度。

5. 加速度向量

物體每單位時間的速度變化

a=ΔvΔt=(ax,ay,az)

其中 Δt 如果足夠小,即為瞬時加速度。


四、while loop - 以迴圈控制物件的運動

while為一種條件式的迴圈控制,當條件式判斷為True時,就反覆執行while迴圈中的內容,一直到條件式判斷為False則中止迴圈,流程概念可參考右圖,因此我們常用迴圈來控制物件的連續運動。以下用等速度運動為例簡單示範迴圈指令:

圖片來源:https://www.tutorialspoint.com/python/python_while_loop.htm

Example 1 : while loop簡介-等速度運動

from vpython import* #引用視覺畫套件Vpython dt = 0.01 #每一次執行迴圈內容的時間間隔 t = 0.0 #第一次執行迴圈的初始時間 x = 0.0 #第一次執行迴圈的初始位置 v = 4.0 #物體的運動速度設為4m/s while x < 1: #在x<1的判斷成立時,執行迴圈的內容 t = t + dt #計時器,每一次迴圈增加dt的時間間隔 x = x + v*dt #位置,每經過一個迴圈,物體位置改變v*dt的位移 print (t, x) #在執行視窗印出每一刻的時間和位置

這裡我們分解步驟來看每一次迴圈發生了什麼事情:

迴圈計次 時間 t 的累加過程 位置 x 的累加過程
loop 1 t = 0 + 0.01 = 0.01 x = 0 + 4 * 0.01 = 0.04
loop 2 t = 0.01 + 0.01 = 0.02 x = 0.04 + 4 * 0.01 = 0.08
loop 3 t = 0.02 + 0.01 = 0.03 x = 0.08 + 4 * 0.01 = 0.12
loop 4 t = 0.03 + 0.01 = 0.04 x = 0.12 + 4 * 0.01 = 0.16
loop 5 t = 0.04 + 0.01 = 0.05 x = 0.16 + 4 * 0.01 = 0.20

這裡我們發現,每經過一個迴圈時間累加0.01秒,而位置的改變為0.04公尺,這即是標準的等速度運動模擬。雖然這裡只處理純量,但是在向量也是完全一模一樣的概念,現在我們可以試試將前面學到的物件插入,然後用迴圈連續改變位置向量,使其產生動態效果。範例程式如下:

Example 2 : 圖形化的等速度運動

from vpython import* #引用視覺畫套件Vpython size = 0.05 #設定球的大小為0.05公尺 x = arrow(pos=vector(0,0,0), axis=vector(1,0,0), shaftwidth=0.02, color=color.green) y = arrow(pos=vector(0,0,0), axis=vector(0,1,0), shaftwidth=0.02, color=color.red) z = arrow(pos=vector(0,0,0), axis=vector(0,0,1), shaftwidth=0.02, color=color.blue) #畫出3D直角座標沿x,y,z方向的單位向量 ball = sphere(radius=size, color=color.yellow, pos=vector(0,0,0), v=vector(1.0,0,0)) #畫球,球的半徑為size,顏色為黃色,位置在(0,0,0),速度為(1,0,0) dt = 0.001 #模擬的時間間隔 t = 0.0 #設定模擬的初始時間 while t<2: #條件判斷t<2成立時執行迴圈內容 rate(1/dt) #設定迴圈的執行速度,每秒執行1/dt次 t = t+dt #計時器 ball.pos = ball.pos + ball.v*dt #球的每一時刻位置,每次迴圈改變ball.v *dt的位移 print (t) #在執行視窗印出每一時刻的時間
  • 「.」的用法:例如ball.pos、ball.v
    在python中「.」的用法可以把它理解為中文「的」的意思,如ball.pos就是ball的pos,即ball的座標位置,又ball.pos.x為ball的位置向量的x方向分量。但如果使用ball.v(球的速度)就得留意,因為sphere的內建指令中並沒有v,所以電腦認不出來v是什麼。因此若要使用這樣的寫法,必須在sphere插入的時候就先定義v,例如:
    sphere(radius=size, color=color.yellow, pos=vector(0,0,0), v=vector(1.0,0,0))。

五、運動學 - 位置、速度、加速度與時間的關係

在運動學中我們很常用 xtvtat 圖來描述物體隨著時間的運動狀態,並從中看出規律以及運動的變化和趨勢。在python中我們已經學會用迴圈模擬出每一時刻的時間和位置,現在我們將加入vpython中繪製函數圖形的指令graph來檢視物件的運動。請參考以下範例程式:

Example 3 : 圖形化的等速度運動與函數圖

from vpython import* size = 0.1 scene = canvas(width=600, height=400, center=vector(2.5,0,0), background=vector(0,0,0)) #設定物件視窗的顯示畫面與背景,寬為600畫素、高為400畫素 #center為畫面中心,background為背景顏色 x = arrow(pos=vector(0,0,0), axis=vector(1,0,0), shaftwidth=0.02, color=color.green) y = arrow(pos=vector(0,0,0), axis=vector(0,1,0), shaftwidth=0.02, color=color.red) z = arrow(pos=vector(0,0,0), axis=vector(0,0,1), shaftwidth=0.02, color=color.blue) ball = sphere(radius=size, color=color.yellow, pos=vector(0,0,0), v=vector(1.0,0,0)) gd = graph(title = "x-t plot", width=600, height=400, xtitle="t", ytitle="x") #設定函數圖的畫面 f1 = gcurve(color=color.blue) #設定函數圖中線條的特性,這裡只設定顏色 dt = 0.001 t = 0.0 while t<5: rate(1/dt) t = t+dt ball.pos = ball.pos + ball.v*dt f1.plot(pos=(t,ball.pos.x)) #每一個迴圈畫一個點描出線條,x軸為時間,y軸為位置 print (t)

六、條件判斷結構

接著我們介紹極為常見的條件判斷結構(if-elif-else),指令架構圖如下:

圖片來源:https://www.codecademy.com/en/forum_questions/51684a3d4ce76309b4001b9c

上圖中的 a 和 b 稱為條件式,和前面學過得 while 裡面寫的條件式是一樣的。如上圖,這裡只要 a 是成立的就執行「do this」內容,若 a 不成立則程式往下判斷 b 是否成立,如果 b 成立了就執行「do that」內容。若 a、b 都不成立的話,程式將執行「whatever」內容。最後請記得條件判斷結構和迴圈結構都有「一層一層」的附屬概念,撰寫時請務必記得縮排!

以下我們簡單列出幾個常用的條件式算符:

operator function
< less than
<= less than or equal to
> greater than
>= greater than or equal to
== equal
!= not equal

以下我們試著使用這種結構來挑出物理模擬過程中的特定時機點。例如程式執行中我們想把 t = 2.0 秒的那瞬間抓出來,我們從 Example 3 進行示範。同學想想可以這樣寫嗎?

if t == 2.0:
    print(t)

還是應該要這樣寫:

if t+dt >= 2.0 and t < 2.0:
    print(t)

實際執行之後你會發現只有第二種成功了!

你會發現等於「==」要成立的條件判斷極其嚴苛,必須到小數點以下十幾位都要一樣,判斷才會成立。因此請同學養成習慣,用給定「範圍」的方式來寫條件判斷,才不會因為模擬過程中產生的誤差而錯過判斷點。

在 if 裡面結合兩個條件是的寫法,如 and 和 or … 等更多用法,請參閱python官網 - 3.1.7. Compound Boolean Expressions:http://anh.cs.luc.edu/handsonPythonTutorial/ifstatements.html#compound-boolean-expressions

課堂作業 1

如果你已知一球沿 x 軸作等加速度運動,加速度為 3 m/s2,初速為 2 m/s,由座標原點出發。請利用Vpython模擬此運動:

  1. 在視窗中畫出球與 xyz 三個座標軸,畫出 xtvtat 圖,並算出球在3秒瞬間的位置。
  2. 在程式中計算此物體的運動何時發生折返,並記錄物體在該折返點的時間、位置與速度。
  • 如何挑出折返點:
  1. 什麼是折返點:直線運動的折返點一般發生在速度歸零的那瞬間,因此在這個時間點之前和之後速度的方向是相反的。

  2. 條件判斷寫法:在某時刻如果發生以下現象,代表折返點到了

    if ball.v.x > 0 and ball.v.x + ball.a.x*dt < 0:
        print (時間...)
        print (位置...)
        print (速度...)
    

    這個條件判斷的意思是,在某時刻沿 x 方向的速度是正的,但是加上速度變化(ball.a.x*dt)推算下一時刻的速度會變成負的。速度沿某方向由正轉負的現象,一般只有在折返的時候才會發生。


進階作業 1-1

一人自靜止開始運動,其 at 圖如圖所示,則 6 秒內此人離出發點最遠的距離為何?

  1. 使物體沿 +x 方向出發,畫出 t=0t=6xtvtat 圖。
  2. 請在物體達到離出發點最遠距離瞬間,在執行視窗印出時間、球位置、球速度。

執行畫面如下:

  • 加速度的設定:用 if-else 在迴圈中將 t=2 秒以前和以後切開,分別設定成不同數值。

    if t <= 2:
        ball.a = ...
    else:
        ball.a = ...
    

進階作業 1-2

一質點以初速度 v=3i^ m/s,自原點出發,其加速度為 a=i^0.5j^ m/s2

  1. 當它達到 x 座標的極大值時,其速度為何?位於何處?此時距出發時間多少秒?
  2. 在畫面上每隔0.4秒在畫面上留下球與描述速度與加速度的箭頭,速度請用綠色、加速度請用紅色箭頭。

執行畫面如下圖所示:

  • 提示:
  1. 折返現象:當物體位置在 x 方向產生極大值時,代表物體沿 x 方向正要發生折返現象,請沿用課堂作業1挑出「折返點」的方法處理此問題。

  2. 餘數除法 %:取出餘數,你可以在執行視窗輸入以下算式練習

    x = 10 % 3    # 輸出結果為 1
    y = 87 % 10   # 輸出結果為 7
    z = 12 % 8.5  # 輸出結果為 3.5
    print ('x =',x, 'y =', y, 'z =', z)
    
  3. 利用餘數除法切出等時距的時間點:此畫面效果會非常像3D的打點計時器
    假設我們要每隔 T 秒畫一組物件,可以在迴圈中做如下設定:

    t = t + dt      #計時器
    plot_t = t%T    #用餘數除法設定畫圖計時器,t累加至超過T後歸零
    if plot_t + dt >= T and plot_t < T:    #用條件判斷設定畫圖時間點
        arrow(color=..., pos=..., axis=..., shaftwidth=0.05)    #畫速度箭頭
        arrow(color=..., pos=..., axis=..., shaftwidth=0.05)    #畫加速度箭頭
        sphere(color=..., pos=..., radius=...)                  #畫球
    

作業繳交:

平台連結:…

此平台由南港高中-高慧君老師設計建置


本單元課程自2018.7.1日起已被瀏覽 1546