# Lecture 9 List的練習 完整作業參考解法
>建國高中特色選修課程 - 物理現象的程式設計與模擬
>作者:賴奕帆
>日期:2018/8/25
:::success
* 同學們,在看參考解之前,請先想清楚自己是否真的有花時間想過如何寫課堂作業和進階作業了呢?
* 學習無他,但求自己覺得好玩而已。
* 若真的想把一件事情學好,務必花時間才能掌握。
* 希望這邊的作業參考解法,真的都只是讓同學們拿來參考,而不是為了繳交作業的複製貼上。
* 想過了嗎? 那請認真參考吧。
:::
>
>
## Lecture 9 檢核作業
### 檢核作業 9-1
請嘗試用雙重甚至三重的迴圈,做出如下圖的平板甚至是立方體的圖示吧。
* 用小球繪製平板,同學可以猜猜這裡有幾個小球,如何編號呢?
![](https://i.imgur.com/GeUov27.jpg)
* 用小球繪製立方體,老師這裡用的球比較少,因為太多會嚴重lag,共有7x7x7顆球。
<img style="display: block; margin-left: auto; margin-right: auto" height="50%" width="50%"
src="https://i.imgur.com/B7ffW2F.jpg">
:::success
#### 檢核作業 9-1 參考解法步驟 :
1. 將在for N in range(-50,51,1)改為for N1 in range(-50,51,1),並再多一層迴圈for N2 in range(-50,51,1),注意多層迴圈的程式縮排。
2. 修改pos=vector(N x 0.02 x R,0,0)為pos=vector(N1 x 0.02 x R,0,__________)。
```python3=26
""" 練習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))
```
3. 若成功修改,請嘗試想想這裡到底有幾顆球,10000顆嗎?這些球是如何排列編號的呢?請嘗試用 print (balllist[?????].pos) 檢視自己的想法。
4. 由於這裡的物件超過一萬,所以程式明顯產生lag。
5. 改換回繪製立方體,在加多一層for迴圈,由於只要7x7x7顆球,因此修改for N1 in range(?????,?????,1)
:::
### 檢核作業 9-2
如同課堂作業9-1,請同學嘗試修改上述的arrowlist append迴圈,寫出如下圖立方體空間的引力場。
<img style="display: block; margin-left: auto; margin-right: auto" height="70%" width="70%"
src="https://i.imgur.com/j8gVzDl.jpg">
:::success
#### 檢核作業 9-2 參考解法步驟 :
1. 將原有的平面for迴圈再多一層改為三層的立體for迴圈。
2. 將arrowlist.append(arrow(pos=vector(N1xRe,N2xRe,_______)中的Z軸位置補上。
```python3=22
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))
```
:::
### 指定作業 9-1
**105年 台大物理系二階段試題**
在三維空間中有一xy平面,有兩個靜止的正面荷(電量為q)分別位於x軸的d/2和-d/2處,另有兩個靜止的負電荷(電量為-q)位於y軸的d/2和-d/2處,如下圖所示,請在xy平面上繪出電力線。
<img style="display: block; margin-left: auto; margin-right: auto" height="50%" width="50%"
src="https://i.imgur.com/HjbQ6bE.jpg">
並嘗試在空間中也丟入一個綠色正電荷小球,使其受到這四顆固定電荷的靜電力,觀察其運動軌跡。
:::info
指定作業 9-1 參考解法步驟 :
1. 在畫面設定處,重新設定四個電荷的名稱與位置。
```python3=21
"""重新放置四個電荷(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)
```
2. 重新放置四組List的場球
```python3=26
"""重新放置四組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)))
```
3. 重新定義每顆場球受到四個電荷的靜電力(電場)
```python3=47
"""重新定義靜電力(電場)公式(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)+_________________________+________________________
```
4. 在迴圈處控制四組List電場球
```python3=47
""" 控制四組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
```
5. 放入綠色小球,觀察它的運動狀況
<img style="display: block; margin-left: auto; margin-right: auto" height="70%" width="70%"
src="https://i.imgur.com/bSGvJVw.jpg">
:::
### 指定作業 9-2
請同學先執行以下程式碼
```python3=1
"""
建國中學 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))
```
:::info
![](https://i.imgur.com/ztZo68f.jpg)
* gas collision是高三上物理 氣體動力論中常討論的問題,將空氣噴出,若碰撞到牆壁反彈,則牆壁所受到的平均力(平均壓力)的討論。
* 同學可以嘗試修改入射角度theta與每秒射出的氣體數per_N兩個基本參數玩看看。
* 請同學們嘗試將此模擬,加上上一節所教的靜電力概念,改成下圖另一個大家熟悉的金箔原子撞擊模擬。
* 希望同學們修完這九節課之後,都能有這樣的能力,加油。
![](https://i.imgur.com/7A6jvzE.jpg)
:::
:::info
指定作業 9-2 參考解法步驟 :
1. 先擷取此原程式中最主要的部份,即射出粒子的程式碼,並讓粒子能超過vec(0,0,0)一段距離後就能消失。其他不需要的都先用alt+3忽略。
```python3=
""" 擷取原程式中最主要的部份(執行迴圈)"""
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
```
2. 重新設定基本參數,包含萬有引力常數k,電荷電量與電荷質量等等,並且讓球射出的數量減少,調整螢幕大小。
```python3=
""" 重新設定基本參數(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. 讓射出的粒子加上軌跡
```python3=
""" 讓粒子加上軌跡(3. 執行迴圈)"""
gas.append( sphere(...., visible = True, make_trail=True))
```
* 若以上設定均調整無誤,應該可以看到螢幕左側射出粒子,並於右側消失。
![](https://i.imgur.com/6tLWgEh.jpg)
4. 在原點畫出金原子,並定義庫倫力公式。
```python3=
""" 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)
```
5. 在執行迴圈處讓List內的電荷都會受到金原子庫倫力的作用。
```python3=
""" 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
```