📚專題:物理撞擊實驗室
📕 引言
- 汽車撞擊測試是一種對市售新車所做的撞擊試驗,測試車輛的耐撞性是否符合安全設計標準,讓車子在發生車禍事故發生時,能最大程度保障司機與乘客的安全。
-
(2分05秒, 資料來源:1)
在正面、後面與測面撞擊的測試中,車子與障礙物的質量、速度、方向、結構、材料…等,都會影響撞擊結果,從車內假人身上的感測器,也可以了解撞擊過程中,對人類身體的影響。
在之前的學習中,相信各位已經練習過利用物理程式來做運動物理量的設置與模擬。在本專題中,請做出一個與物理撞擊模擬有關的程式。
建議先備課程
在學習本專題前,建議先完成 「力與運動遊樂場」 ,在學習概念銜接上會較為平順。
📙 問題
要如何進行撞擊的模擬呢?
首先,將撞擊模擬的物體分成「撞擊物」與「障礙物」,分別以圓形及方形做為代表。
接著思考以下的問題:
-
撞擊物的運動有哪些性質呢?
-
障礙物的排列結構有哪些形式?
-
什麼因素會影響撞擊的結果?
想一想,還有想到與撞擊模擬相關的問題嗎?
📗 搜尋
利用搜尋引擎,運用「運動定律」「碰撞」…等關鍵字,可以找到許多相關的資料。
- 障礙物參考資料:
- 可能會影響碰撞的因素:
除了以上的資料,還有沒有其他的參考資料?找到資料後,要怎麼運用這些資料呢?
📒 構思
- 在進行撞擊模擬時,會參考下圖的方式,由撞擊後掉落物體的多或少,來判斷撞擊力的大小:
-
(資料來源:2)
參考資料並簡化後,將採用3種障礙物設計,供撞擊物做不同的碰撞模擬:
在程式的操作方式,撞擊物使用滑鼠控制,障礙物以鍵盤設置,模擬操作的設計構想如下圖:
📘 實作(7)
程式結構
- 由於物理程式是採用事件驅動的方式,所以程式的主要流程與結構設計會考慮到鍵盤與滑鼠的事件處理函式,如下圖:
初步完成規劃後,就可以動手寫程式的主要結構。
範例程式 程式結構 - - - - - - - (專題實作1/7 新檔)
【長度4:18 章節時間如下】
- 0:00 檔案儲存、模組設定
- 0:59 程式結構
from 物理模組 import *
舞台 = 物理引擎(800,800)
def 按下鍵盤時(按鍵, x, y):
if 按鍵 == key.LEFT :
print('柱')
if 按鍵 == key.RIGHT :
print('牆')
if 按鍵 == key.UP :
print('金字塔')
def 按下滑鼠時(x, y):
print('發射')
模擬主迴圈()
模擬主迴圈
結構化程式設計
發射撞擊物
為了讓碰撞模擬在操作上有多變性與互動性,撞擊物的設計在點擊滑鼠時會從左向右射出
當一開始施力於撞擊物時,根據牛頓運動定律,會產生加速度並且移動,物體在空中移動的同時也會受到重力的影響,產生如下的拋物線軌跡:
由上圖可以得知,讓撞擊物的開始方向些微的斜上,可以讓運動的軌跡不會降低太快也不會飛得太高。所以在發射的程式中,會加一些向上的力量,儘量保持高度。
動手寫寫看發射的程式。
範例程式 發射撞擊物 - - - - - - - (專題實作2/7 接續)
【長度1:55 章節時間如下】
- 4:23 發射撞擊物
from 物理模組 import *
舞台 = 物理引擎(800,800)
def 按下鍵盤時(按鍵, x, y):
if 按鍵 == key.LEFT :
print('柱')
if 按鍵 == key.RIGHT :
print('牆')
if 按鍵 == key.UP :
print('金字塔')
def 按下滑鼠時(x, y):
print('發射')
物體 = 新增圓球(半徑=20)
物體.位置 = [0, y]
向量 = [2000, 200]
物體.施加衝力(向量)
模擬主迴圈()
障礙物 - 柱
先利用之前學到的方式,按滑鼠就會產生方塊。之後就要思考一下,如何使用重複結構(迴圈),一次就能產生柱的障礙物。在迴圈中,柱的直排方塊座標,有沒有什麼規律呢?
動手實作看看。
範例程式 障礙物-柱 - - - - - - - (專題實作3/7 接續)
【長度3:30 章節時間如下】
- 6:20 障礙物-柱
from 物理模組 import *
舞台 = 物理引擎(800,800)
def 柱(x, y) :
for 直 in range(10) :
物體 = 新增方塊(寬=20,高=20)
物體.位置 = [x, y + 20 * 直]
def 按下鍵盤時(按鍵, x, y):
if 按鍵 == key.LEFT :
print('柱')
柱(x, y)
if 按鍵 == key.RIGHT :
print('牆')
if 按鍵 == key.UP :
print('金字塔')
def 按下滑鼠時(x, y):
print('發射')
物體 = 新增圓球(半徑=20)
物體.位置 = [0, y]
向量 = [2000, 200]
物體.施加衝力(向量)
模擬主迴圈()
結構化程式設計
障礙物 - 牆
牆的實作可以從柱的程式而來,柱是一層迴圈,而牆就需要使用双層迴圈。在双層迴圈中,能夠找出方塊座標的樣式嗎?
請試著寫出程式。
範例程式 障礙物-牆 - - - - - - - (專題實作4/7 接續)
【長度2:07 章節時間如下】
- 9:55 障礙物-牆
from 物理模組 import *
舞台 = 物理引擎(800,800)
def 柱(x, y) :
for 直 in range(10) :
物體 = 新增方塊(寬=20,高=20)
物體.位置 = [x, y + 20 * 直]
def 牆(x, y) :
for 橫 in range(10) :
for 直 in range(10) :
物體 = 新增方塊(寬=20,高=20)
物體.位置 = [x + 20 * 橫, y + 20 * 直]
def 按下鍵盤時(按鍵, x, y):
if 按鍵 == key.LEFT :
print('柱')
柱(x, y)
if 按鍵 == key.RIGHT :
print('牆')
牆(x, y)
if 按鍵 == key.UP :
print('金字塔')
def 按下滑鼠時(x, y):
print('發射')
物體 = 新增圓球(半徑=20)
物體.位置 = [0, y]
向量 = [2000, 200]
物體.施加衝力(向量)
模擬主迴圈()
障礙物 - 金字塔
如何從牆的程式來做出金字塔呢?要先思考兩個迴圈之間的關係,做出樓梯的形狀。再思考如何從樓梯形狀變化成金字塔形狀。相關思考如下圖:
動手寫出程式
範例程式 障礙物-金字塔 - - - - - - - (專題實作5/7 接續)
【長度2:41 章節時間如下】
- 12:04 障礙物-金字塔
from 物理模組 import *
舞台 = 物理引擎(800,800)
def 柱(x, y) :
for 直 in range(10) :
物體 = 新增方塊(寬=20,高=20)
物體.位置 = [x, y + 20 * 直]
def 牆(x, y) :
for 橫 in range(10) :
for 直 in range(10) :
物體 = 新增方塊(寬=20,高=20)
物體.位置 = [x + 20 * 橫, y + 20 * 直]
def 金字塔(x, y) :
for 橫 in range(10) :
for 直 in range(10 - 橫) :
物體 = 新增方塊(寬=20,高=20)
物體.位置 = [x + 20 * 橫 + 10 * 直, y + 20 * 直]
def 按下鍵盤時(按鍵, x, y):
if 按鍵 == key.LEFT :
print('柱')
柱(x, y)
if 按鍵 == key.RIGHT :
print('牆')
牆(x, y)
if 按鍵 == key.UP :
print('金字塔')
金字塔(x, y)
def 按下滑鼠時(x, y):
print('發射')
物體 = 新增圓球(半徑=20)
物體.位置 = [0, y]
向量 = [2000, 200]
物體.施加衝力(向量)
模擬主迴圈()
實驗組與對照組
為了讓撞擊的結果更為清楚,會將畫面分成上下兩部份,上方為實驗組,下方為對照組。
依規劃的方式動手實作
如何新增地形?
範例程式 實驗組與對照組 - - - - - - - (專題實作6/7 接續)
【長度2:06 章節時間如下】
- 14:48 實驗組與對照組
# 地形建立方法請參考操作影片
from 物理模組 import *
舞台 = 物理引擎(800,800)
def 柱(x, y) :
for 直 in range(10) :
物體 = 新增方塊(寬=20,高=20)
物體.位置 = [x, y + 20 * 直]
def 牆(x, y) :
for 橫 in range(10) :
for 直 in range(10) :
物體 = 新增方塊(寬=20,高=20)
物體.位置 = [x + 20 * 橫, y + 20 * 直]
def 金字塔(x, y) :
for 橫 in range(10) :
for 直 in range(10 - 橫) :
物體 = 新增方塊(寬=20,高=20)
物體.位置 = [x + 20 * 橫 + 10 * 直, y + 20 * 直]
def 按下鍵盤時(按鍵, x, y):
if 按鍵 == key.LEFT :
print('柱')
柱(x, y)
if 按鍵 == key.RIGHT :
print('牆')
牆(x, y)
if 按鍵 == key.UP :
print('金字塔')
金字塔(x, y)
def 按下滑鼠時(x, y):
print('發射')
if y > 400 :
print('實驗組')
物體 = 新增圓球(半徑=20)
物體.位置 = [0, y]
向量 = [2000, 200]
物體.施加衝力(向量)
else :
print('對照組')
物體 = 新增圓球(半徑=20)
物體.位置 = [0, y]
向量 = [2000, 200]
物體.施加衝力(向量)
模擬主迴圈()
撞擊測試
到此終於可以開始進行撞擊測試了。到底什麼會影響撞擊的結果呢?
越重的物體也有可能會影響結果,但是當撞擊物有不同大小時,要如何決定重量呢?先了解一下什麼是密度:
-
(2分17秒, 資料來源:3)
根據以上的思考,將會對「不同結構」、「不同高度」、「不同大小」、「不同密度」,分別進行撞擊測試。
範例程式 撞擊測試 - - - - - - - (專題實作7/7 接續)
【長度4:11 章節時間如下】
- 16:56 撞擊測試
# 地形建立方法請參考操作影片
from 物理模組 import *
舞台 = 物理引擎(800,800)
def 柱(x, y) :
for 直 in range(10) :
物體 = 新增方塊(寬=20,高=20)
物體.位置 = [x, y + 20 * 直]
物體.密度 = 1
def 牆(x, y) :
for 橫 in range(10) :
for 直 in range(10) :
物體 = 新增方塊(寬=20,高=20)
物體.位置 = [x + 20 * 橫, y + 20 * 直]
物體.密度 = 1
def 金字塔(x, y) :
for 橫 in range(10) :
for 直 in range(10 - 橫) :
物體 = 新增方塊(寬=20,高=20)
物體.位置 = [x + 20 * 橫 + 10 * 直, y + 20 * 直]
物體.密度 = 1
def 按下鍵盤時(按鍵, x, y):
if 按鍵 == key.LEFT :
print('柱')
柱(x, y)
if 按鍵 == key.RIGHT :
print('牆')
牆(x, y)
if 按鍵 == key.UP :
print('金字塔')
金字塔(x, y)
def 按下滑鼠時(x, y):
print('發射')
if y > 400 :
print('實驗組')
物體 = 新增圓球(半徑=60)
物體.位置 = [0, y]
向量 = [2000, 200]
物體.施加衝力(向量)
物體.密度 = 10
else :
print('對照組')
物體 = 新增圓球(半徑=60)
物體.位置 = [0, y]
向量 = [2000, 200]
物體.施加衝力(向量)
物體.密度 = 1
模擬主迴圈()
📙 擴展(2)
慢動作
在有些真實世界的實驗中,會使用高速攝影機錄影,在事後以慢動作播放來做出更詳細的分析,看一下高速攝影機的慢動作效果:
-
(36秒, 資料來源:4)
物理程式中有慢動作的控制方法,增加新的事件處理函式,可以利用按鍵來控制慢動作的有無。
一起來實作看看。
範例程式 慢動作 - - - - - - - (專題擴展1/2 接續)
【長度2:26 章節時間如下】
- 21:09 慢動作
# 地形建立方法請參考操作影片
from 物理模組 import *
舞台 = 物理引擎(800,800)
def 柱(x, y) :
for 直 in range(10) :
物體 = 新增方塊(寬=20,高=20)
物體.位置 = [x, y + 20 * 直]
物體.密度 = 1
def 牆(x, y) :
for 橫 in range(10) :
for 直 in range(10) :
物體 = 新增方塊(寬=20,高=20)
物體.位置 = [x + 20 * 橫, y + 20 * 直]
物體.密度 = 1
def 金字塔(x, y) :
for 橫 in range(10) :
for 直 in range(10 - 橫) :
物體 = 新增方塊(寬=20,高=20)
物體.位置 = [x + 20 * 橫 + 10 * 直, y + 20 * 直]
物體.密度 = 1
def 按下鍵盤時(按鍵, x, y):
if 按鍵 == key.LEFT :
print('柱')
柱(x, y)
if 按鍵 == key.RIGHT :
print('牆')
牆(x, y)
if 按鍵 == key.UP :
print('金字塔')
金字塔(x, y)
if 按鍵 == key.SPACE :
舞台.慢動作 = True
def 放開鍵盤時(按鍵, x, y):
舞台.慢動作 = False
def 按下滑鼠時(x, y):
print('發射')
if y > 400 :
print('實驗組')
物體 = 新增圓球(半徑=60)
物體.位置 = [0, y]
向量 = [2000, 200]
物體.施加衝力(向量)
物體.密度 = 10
else :
print('對照組')
物體 = 新增圓球(半徑=60)
物體.位置 = [0, y]
向量 = [2000, 200]
物體.施加衝力(向量)
物體.密度 = 1
模擬主迴圈()
子彈射擊
撞擊物的開始速度會不會影響結果?我們先來看一下子彈發射的樣子:
-
(2分46秒, 資料來源:5)
在物理程式的內部原理是經由物理公式計算出來的一格一格畫面,當撞擊物速度快到某個程度時,會產生穿越的情形,這是物理程式模擬的原理與極限。不過我們會儘量在此限制中做出子彈模擬,只要找出適當的速度,並且將且將障礙物放在適當的位置(瞬間到達的位置)就可以。
請動手做做看。
範例程式 子彈射擊 - - - - - - - (專題擴展2/2 接續)
【長度1:44 章節時間如下】
- 23:37 子彈射擊
# 地形建立方法請參考操作影片
from 物理模組 import *
舞台 = 物理引擎(800,800)
def 柱(x, y) :
for 直 in range(10) :
物體 = 新增方塊(寬=20,高=20)
物體.位置 = [x, y + 20 * 直]
物體.密度 = 1
def 牆(x, y) :
for 橫 in range(10) :
for 直 in range(10) :
物體 = 新增方塊(寬=20,高=20)
物體.位置 = [x + 20 * 橫, y + 20 * 直]
物體.密度 = 1
def 金字塔(x, y) :
for 橫 in range(10) :
for 直 in range(10 - 橫) :
物體 = 新增方塊(寬=20,高=20)
物體.位置 = [x + 20 * 橫 + 10 * 直, y + 20 * 直]
物體.密度 = 1
def 按下鍵盤時(按鍵, x, y):
if 按鍵 == key.LEFT :
print('柱')
柱(x, y)
if 按鍵 == key.RIGHT :
print('牆')
牆(x, y)
if 按鍵 == key.UP :
print('金字塔')
金字塔(x, y)
if 按鍵 == key.SPACE :
舞台.慢動作 = True
def 放開鍵盤時(按鍵, x, y):
舞台.慢動作 = False
def 按下滑鼠時(x, y):
print('發射')
if y > 400 :
print('實驗組')
物體 = 新增圓球(半徑=10)
物體.位置 = [0, y]
向量 = [100000, 200]
物體.施加衝力(向量)
物體.密度 = 1
else :
print('對照組')
物體 = 新增圓球(半徑=10)
物體.位置 = [0, y]
向量 = [2000, 200]
物體.施加衝力(向量)
物體.密度 = 1
模擬主迴圈()
📒 結語
如果沒有實際的實驗做為基礎,物理的學習很容易會發展成像數學一樣的抽象,不易理解。
物理程式的模擬與物體互動的具體呈現,提供一種方式,讓我們能理解在力與運動中各個物理量之間的關係,也可以在有趣的氣氛下學習知識、實踐知識。
希望本課程可以讓你有不同的體驗及收獲,提高你對相關學科的興趣,下次再見了。