建國高中特色選修課程 - 物理現象的程式設計與模擬
作者:賴奕帆
日期:2018/8/25
同學們,在看參考解之前,請先想清楚自己是否真的有花時間想過如何寫課堂作業和進階作業了呢?
學習無他,但求自己覺得好玩而已。
若真的想把一件事情學好,務必花時間才能掌握。
希望這邊的作業參考解法,真的都只是讓同學們拿來參考,而不是為了繳交作業的複製貼上。
想過了嗎? 那請認真參考吧。
請嘗試用雙重甚至三重的迴圈,做出如下圖的平板甚至是立方體的圖示吧。
用小球繪製平板,同學可以猜猜這裡有幾個小球,如何編號呢?
用小球繪製立方體,老師這裡用的球比較少,因為太多會嚴重lag,共有7x7x7顆球。
""" 練習List_改成利用紅球畫平板"""
for N1 in range(-50,51,1):
for N2 in range(-50,51,1):
balllist.append(sphere(pos=vector(N1*0.02*R,0, N2*0.02*R), radius = 0.1, color=color.red))
若成功修改,請嘗試想想這裡到底有幾顆球,10000顆嗎?這些球是如何排列編號的呢?請嘗試用 print (balllist[???].pos) 檢視自己的想法。
由於這裡的物件超過一萬,所以程式明顯產生lag。
改換回繪製立方體,在加多一層for迴圈,由於只要7x7x7顆球,因此修改for N1 in range(???,???,1)
如同課堂作業9-1,請同學嘗試修改上述的arrowlist append迴圈,寫出如下圖立方體空間的引力場。
arrowlist = [] #定義箭頭放置的List
for N1 in range(-5,6,1): #X軸
for N2 in range(-5,6,1):#Y軸
for N3 in range(-5,6,1): #Z軸
arrowlist.append(arrow(pos=vector(N1*Re,N2*Re,N3*Re),axis=vector(5,0,0),shaftwidth=1 , color=color.red))
105年 台大物理系二階段試題
在三維空間中有一xy平面,有兩個靜止的正面荷(電量為q)分別位於x軸的d/2和-d/2處,另有兩個靜止的負電荷(電量為-q)位於y軸的d/2和-d/2處,如下圖所示,請在xy平面上繪出電力線。
並嘗試在空間中也丟入一個綠色正電荷小球,使其受到這四顆固定電荷的靜電力,觀察其運動軌跡。
指定作業 9-1 參考解法步驟 :
"""重新放置四個電荷(2. 畫面設定)"""
Qx1 = sphere(pos = vec(2,0,0) , radius = size , color = color.blue)
Qx2 = sphere(pos = vec(-2,0,0) , radius = size , color = color.blue)
Qy1 = sphere(pos = ____________, radius = size , color = color.red)
Qy2 = sphere(pos = ____________, radius = size , color = color.red)
"""重新放置四組List場球(2. 畫面設定)"""
field_ball_x1=[]
for N in range(0,b_N,1):#build field ball from ball
field_ball_x1.append(sphere(pos=vector(size*cos(2*pi*N/b_N), size*sin(2*pi*N/b_N),0)+Qx1.pos,
radius=0.01, color=vec(1,1,0), make_trail=True, v=vector(0,0,0)))
field_ball_x2=[]
for N in range(0,b_N,1):#build field ball from ball
field_ball_x2.append(sphere(pos=vector(size*cos(2*pi*N/b_N), size*sin(2*pi*N/b_N),0)+Qx2.pos,
radius=0.01, color=vec(1,1,0), make_trail=True, v=vector(0,0,0)))
field_ball_y1=[]
for N in range(0,b_N,1):#build field ball from ball
field_ball_y1.append(sphere(pos=vector(size*cos(2*pi*N/b_N), size*sin(2*pi*N/b_N),0)+___________,
radius=0.01, color=vec(0.8,0.8,0.3), make_trail=True, v=vector(0,0,0)))
field_ball_y2=[]
for N in range(0,b_N,1):#build field ball from ball
field_ball_y2.append(sphere(pos=vector(size*cos(2*pi*N/b_N), size*sin(2*pi*N/b_N),0)+___________,
radius=0.01, color=vec(0.8,0.8,0.3), make_trail=True, v=vector(0,0,0)))
"""重新定義靜電力(電場)公式(2. 畫面設定)"""
def Force_E(r, q):#force of field
rx1 = r - Qx1.pos
rx2 = r - Qx2.pos
ry1 = r - ___________
ry2 = r - ___________
return k*q*Q1_charge*rx1.norm()/(rx1.mag*rx1.mag)+ k*q*Q1_charge*rx2.norm()/(rx2.mag*rx2.mag)+_________________________+________________________
""" 控制四組List電場球(3.執行迴圈)"""
for N in field_ball_x1:
N.v = Force_E(N.pos, 1.0).norm()
N.pos += N.v*dt
for N in field_ball_x2:
N.v = Force_E(N.pos, 1.0).norm()
N.pos += N.v*dt
for N in _____________:
N.v = __________________________
N.pos += N.v*dt
for N in _____________:
N.v = __________________________
N.pos += N.v*dt
請同學先執行以下程式碼
"""
建國中學 vpython 物理模擬
作者: 物理 科賴奕帆老師
高二物理
gas collision
"""
from vpython import *
from random import *
"""
1. 參數設定
"""
t = 0.0 ; t1 = 0.0 ; dt = 0.0001 #時間參數
theta = 30.0 * pi / 180 #氣體入射角度
d = 3.0 #氣體與牆壁距離
r = 0.50 #氣柱半徑
v0 = 2.0 # 氣體初速率
m = 0.01 #單一氣體質量
K = 5.0 #牆壁碰撞參數
per_N = 100.0 #每秒射出的氣體數
F_theory = 2*m*v0*cos(theta)*per_N #氣體碰撞的理論平均力
"""
2. 畫面設定
"""
scene = canvas(align = 'left' , center = vec ( -0.5*d , 0 , 0 ) , height=600, width=600, range=3.5,
auto_scale=False, background=vec(0.6,0.8,0.8) , fov = 0.004) #設定畫面
wall = box(pos=vec(0.0,0,0),length=0.6, height=5 , width=5, opacity = 0.9 , texture = textures.wood) #設定牆壁
gas = [] #氣體的List
F_t = graph(align='left',width=400,height=400, #畫J-t圖
title='F-t', xtitle='t', ytitle='F',
foreground=color.black,background=color.white,
xmax=5, xmin=0, ymax=2*F_theory, ymin=0)
f1 = gcurve(color=color.red)
f2 = gcurve(color=color.blue)
sum_F = 0 #計算程式中每顆小球撞擊牆壁時的總力
"""
3. 執行迴圈
"""
while True:
rate(10000)
t = t + dt #時間
t1 = t1 + dt
sum_F = 0 #每千分之一秒,程式內的總力要歸零重算
if t1 > 1/ per_N: # 設定per_N = 100.0時,則每1/100秒會射出一顆空氣分子
t1 = 0
r_dom = random() #空氣射出的位置隨機參數
p_dom = random() #空氣射出的角度位置參數
gas.append( sphere(pos = vector((-d*cos(theta)+r*r_dom*cos(p_dom*2*pi)*sin(theta)),(d*sin(theta)+r*r_dom*cos(p_dom*2*pi)*cos(theta)),(r*r_dom*sin(p_dom*2*pi))) , radius = 0.05, v = vec(v0*cos(theta),-v0*sin(theta),0) , Fx = 0 , visible = True))
# 每1/100秒會產生一個隨機位置的空氣分子,以相同的速度射出
for N in gas : #gas List內所有的空氣分子撞擊牆壁時,都會受到一個-Kx的向左受力
N.Fx = 0
if N.pos.x > wall.pos.x: #當x軸位置比牆壁還右側時,會受到-Kx的向左受力
N.Fx = - K*(N.pos.x - wall.pos.x) #牆壁給空氣分子的力
N.v.x += N.Fx / m * dt #力改變x軸方向的速度
N.pos += N.v*dt #速度控制位置
else: #若空氣分子沒碰到牆壁時,即等速度前進
N.pos += N.v*dt
sum_F += -N.Fx #累加所有空氣分子所受牆壁的受力
if N.pos.x < -d*cos(theta) - 0.3 : #當空氣分子打至左側 -d*cos(theta) - 0.3位置時,使其由List消失
N.Fx = 0
N.visible = False
N = None
f1.plot( pos=(t,sum_F)) #繪圖
f2.plot( pos=(t,F_theory))
gas collision是高三上物理 氣體動力論中常討論的問題,將空氣噴出,若碰撞到牆壁反彈,則牆壁所受到的平均力(平均壓力)的討論。
同學可以嘗試修改入射角度theta與每秒射出的氣體數per_N兩個基本參數玩看看。
請同學們嘗試將此模擬,加上上一節所教的靜電力概念,改成下圖另一個大家熟悉的金箔原子撞擊模擬。
希望同學們修完這九節課之後,都能有這樣的能力,加油。
指定作業 9-2 參考解法步驟 :
""" 擷取原程式中最主要的部份(執行迴圈)"""
if t1 > 1/ per_N: 每秒射出per_N的粒子
t1 = 0
r_dom = random()
p_dom = random()
gas.append( sphere(pos = vector((-d*cos(theta)+r*r_dom*cos(p_dom*2*pi)*sin(theta)),(d*sin(theta)+r*r_dom*cos(p_dom*2*pi)*cos(theta)),(r*r_dom*sin(p_dom*2*pi))) , radius = 0.05, v = vec(v0*cos(theta),-v0*sin(theta),0) , Fx = 0 , visible = True, make_trail=True))
for N in gas :
N.pos = N.pos+N.v*dt #讓粒子等速前進
if mag(N.pos - vec(0,0,0) ) > 4: #若粒子離原點超過4的距離就會從List消除
N.visible = False
N = None
""" 重新設定基本參數(1. 設定參數)"""
theta = 00.0 * pi / 180 #氣體入射角度, 改為平行入射
per_N = 5.0 #每秒射出的粒子數,改為每秒射入5個粒子
k = 9*10**9 #設定庫倫常數
Q_charge = 10**(-5) #設定金原子電量
q_charge = 10 **(-8) #設定粒子電量
q_m = 10**(-3) #設定粒子質量
""" 調整螢幕大小(2. 設定畫面)"""
scene = canvas(..., height=600, width=1000)
""" 讓粒子加上軌跡(3. 執行迴圈)"""
gas.append( sphere(...., visible = True, make_trail=True))
""" 2. 畫面設定"""
Q = sphere(pos = vec(0,0,0) , radius = 0.2 , color = color.yellow)
def Force_E(r, q):
r1 = r - Q.pos
return k*q*Q_charge*r1.norm()/(r1.mag*r1.mag)
""" 3. 執行迴圈"""
for N in gas :
N.v = N.v + Force_E(N.pos, q_charge)/q_m *dt
N.pos = N.pos+N.v*dt