# 速度選擇器
> 作者:王一哲
> 日期:2018/5/10
<br />
速度選擇器是用來篩選具有特定速度帶電粒子的裝置,基本的構造如下圖。用兩塊平行帶電板製造向下的電場,再加上垂直射入紙面的磁場,若帶正電的粒子由左側以水平速度 v 進入速度選擇器,粒子會受到向下的靜電力以及向上的磁力,當合力為零時粒子等速度前進,此時
$$ qE = qvB ~\Rightarrow~ v = \frac{E}{B} = \frac{V}{Bd} $$
如果在右側加上只有一個小孔的擋板,只有向右直線前進的粒子可以通過,就可以藉由改變電場、磁場的量值控制通過裝置的粒子速度量值。以下共有兩個程式:
1. 程式20-1:畫電場、磁場、平行帶電板、粒子運動軌跡出來,粒子撞到平行帶電板後停止運動。
2. 程式20-2:以20-1為基礎,於出口處加上擋板。
<img style="display: block; margin-left: auto; margin-right: auto" height="35%" width="35%" src="https://i.imgur.com/7M5MKS4.png">
<div style="text-align:center">速度選擇器構造示意圖</div>
<br />
## 程式 20-1.速度選擇器 ([取得程式碼](https://github.com/YiZheWangTw/VPythonTutorial/blob/master/20.%E9%80%9F%E5%BA%A6%E9%81%B8%E6%93%87%E5%99%A8/20-1_velocity_selector.py)) ([GlowScript 網站動畫連結](http://www.glowscript.org/#/user/yizhe/folder/Public/program/20-1velocityselector))
```python=
"""
VPython教學: 20-1.速度選擇器
Ver. 1: 2018/4/7
Ver. 2: 2019/9/16
作者: 王一哲
"""
from vpython import *
"""
1. 參數設定, 設定變數及初始值
"""
size, m, v0, q = 0.005, 1E-10, 10, 1E-9 # 粒子半徑, 質量, 水平速度, 電量
V, d, L, B = 1, 0.1, 0.2, 1 # 平行帶電板間的電壓, 距離, 長度, 外加磁場強度
E_field = vec(0, -V/d, 0) # 電場
B_field = vec(0, 0, -B) # 磁場
t, dt = 0, 1E-5 # 時間, 時間間隔
"""
2. 畫面設定
"""
# 產生動畫視窗、平行帶電板、水平線、帶電粒子
scene = canvas(title="Velocity Selector", width=800, height=600, x=0, y=0, center=vec(0, 0, 0), background=color.black)
p1 = box(pos=vec(0, d/2, 0), size=vec(L, 0.01*L, L), color=color.blue)
p2 = box(pos=vec(0, -d/2, 0), size=vec(L, 0.01*L, L), color=color.blue)
line = cylinder(pos=vec(-L, 0, 0), radius=0.1*size, axis=vec(2*L, 0, 0), color=color.yellow)
charge = sphere(pos=vec(-L, 0, 0), v=vec(v0, 0, 0), radius=size, color=color.red, m=m, make_trail=True)
# 產生表示電場、磁場的箭頭及標籤
arrow_E = arrow(pos=vec(-L/2, d/2, 0), axis=vec(0, -0.1, 0), shaftwidth=size, color=color.green)
arrow_B = arrow(pos=vec(-L/2, 0, d/2), axis=vec(0, 0, -0.1), shaftwidth=size, color=color.orange)
label_E = label(pos=vec(-L/2, d/2, 0), text="E", xoffset=-25, yoffset=25, color=color.green, font="sans")
label_B = label(pos=vec(-L/2, 0, d/2), text="B", xoffset=-25, yoffset=-25, color=color.orange, font="sans")
# 產生表示速度、加速度的箭頭
arrow_v = arrow(pos=charge.pos, shaftwidth=0.3*size, color=color.cyan)
arrow_a = arrow(pos=charge.pos, shaftwidth=0.3*size, color=color.magenta)
"""
3. 物體運動部分, 當帶電粒子到達畫面最右側或撞到平行帶電板時停止
"""
while(charge.pos.x < L and abs(charge.pos.y) < d/2 - p1.height - size):
rate(500)
# 計算帶電粒子所受合力, 在平行帶電板間才有電場、磁場
if(-L/2 <= charge.pos.x <= L/2): F = q*(E_field + cross(charge.v, B_field))
else: F = vec(0, 0, 0)
# 更新帶電粒子加速度、速度、位置
charge.a = F/charge.m
charge.v += charge.a*dt
charge.pos += charge.v*dt
# 更新表示速度、加速度的箭頭, 只畫出方向以避免動畫自動縮小
arrow_v.pos = charge.pos
arrow_a.pos = charge.pos
arrow_v.axis = charge.v.norm()*0.05
arrow_a.axis = charge.a.norm()*0.05
# 更新時間
t += dt
```
<br />
### 參數設定
在此設定變數為size、m、v0、q、V、d、L、B、E_field、B_field、t、dt,用途已寫在該行的註解當中。為了使動畫較為順暢,粒子的加速度不能太大,因此粒子的質量比真實的原子核質量大很多。
<br />
### 畫面設定
1. 產生動畫視窗、平行帶電板、水平線、帶電粒子。
2. 產生表示速度、加速度的箭頭。
3. 產生表示電場、磁場的箭頭及標籤。標籤的語法為
```python
[標籤名稱] = label(pos=[位置向量], text="[標籤內容]", xoffset=[x方向位移量], yoffset=[y方向位移量], color=[顏色名稱或RGB值], font="[字體名稱]")
```
[]中的內容請換成自己需要的參數。
4. 開啟繪圖視窗,畫小球的位置、速度、加速度與時間關係圖。
<br />
### 物體運動
1. 為了使動畫在帶電粒子到達畫面最右側或撞到平行帶電板時停止,將 while 迴圈當中的條件設定為 **charge.pos.x < L and abs(charge.pos.y) < d/2 - p1.height - size**。
2. 計算帶電粒子所受合力,由於平行帶電板間才有電場、磁場,在平行帶電板外設為零。計算帶電粒子所受合力的數學式為 $\vec F = q(\vec E + \vec v \times \vec B)$,對應的程式碼為
```python
F = q*(E_field + cross(charge.v, B_field))
```
3. 更新帶電粒子加速度、速度、位置。
4. 更新表示速度、加速度的箭頭,只畫出方向以避免動畫自動縮小。
5. 更新時間。
<br />
### 模擬結果
以下是5種不同的數據組合及測試結果:
1. v0 = 10, V = 1, d = 0.1, B = 1 ⇒ 等速度直線運動
2. q > 0, v0 = 20 其它條件與組合1相同 ⇒ 向上偏移
3. q > 0, d = 0.2 其它條件與組合1相同 ⇒ 向上偏移
4. q > 0, V = 2 其它條件與組合1相同 ⇒ 向下偏移
5. q > 0, B = 5 其它條件與組合1相同 ⇒ 向上偏移
<img style="display: block; margin-left: auto; margin-right: auto" height="80%" width="80%" src="https://i.imgur.com/gk4abiM.png">
<div style="text-align:center">程式 20-1 數據組合1畫面截圖</div>
<br />
<img style="display: block; margin-left: auto; margin-right: auto" height="80%" width="80%" src="https://i.imgur.com/cXcdVwp.png">
<div style="text-align:center">程式 20-1 數據組合2畫面截圖</div>
<br />
<img style="display: block; margin-left: auto; margin-right: auto" height="80%" width="80%" src="https://i.imgur.com/pIqwmlw.png">
<div style="text-align:center">程式 20-1 數據組合3畫面截圖</div>
<br />
<img style="display: block; margin-left: auto; margin-right: auto" height="80%" width="80%" src="https://i.imgur.com/HseVWVW.png">
<div style="text-align:center">程式 20-1 數據組合4畫面截圖</div>
<br />
<img style="display: block; margin-left: auto; margin-right: auto" height="80%" width="80%" src="https://i.imgur.com/d96anGc.png">
<div style="text-align:center">程式 20-1 數據組合5畫面截圖</div>
<br />
## 程式 20-2.速度選擇器, 加上出口處的擋板 ([取得程式碼](https://github.com/YiZheWangTw/VPythonTutorial/blob/master/20.%E9%80%9F%E5%BA%A6%E9%81%B8%E6%93%87%E5%99%A8/20-2_velocity_selector.py)) ([GlowScript 網站動畫連結](http://www.glowscript.org/#/user/yizhe/folder/Public/program/20-2velocityselectorv2))
```python=
"""
VPython教學: 20-2.速度選擇器, 加上出口處的擋板
Ver. 1: 2018/5/10
Ver. 2: 201/9/16
作者: 王一哲
"""
from vpython import *
"""
1. 參數設定, 設定變數及初始值
"""
size, m, v0, q = 0.005, 1E-10, 10, 1E-9 # 粒子半徑, 質量, 水平速度, 電量
V, d, L, B = 1, 0.1, 0.2, 1 # 平行帶電板間的電壓, 距離, 長度, 外加磁場強度
E_field = vec(0, -V/d, 0) # 電場
B_field = vec(0, 0, -B) # 磁場
t, dt = 0, 1E-5 # 時間, 時間間隔
"""
2. 畫面設定
"""
# 產生動畫視窗、平行帶電板、出口處的擋板、水平線、帶電粒子
scene = canvas(title="Velocity Selector", width=800, height=600, x=0, y=0, center=vec(0, 0, 0), background=color.black)
p1 = box(pos=vec(0, d/2, 0), size=vec(L, 0.01*L, L), color=color.blue)
p2 = box(pos=vec(0, -d/2, 0), size=vec(L, 0.01*L, L), color=color.blue)
b1 = box(pos=vec(L/2, d/4 + size, 0), size=vec(0.01*L, 0.5*d, L), color = color.gray(0.7))
b2 = box(pos=vec(L/2, -d/4 - size, 0), size=vec(0.01*L, 0.5*d, L), color = color.gray(0.7))
line = cylinder(pos=vec(-L, 0, 0), radius=0.1*size, axis=vec(2*L, 0, 0), color=color.yellow)
charge = sphere(pos=vec(-L, 0, 0), v=vec(v0, 0, 0), radius=size, color=color.red, m=m, make_trail=True)
# 產生表示電場、磁場的箭頭及標籤
arrow_E = arrow(pos=vec(-L/2, d/2, 0), axis=vec(0, -0.1, 0), shaftwidth=size, color=color.green)
arrow_B = arrow(pos=vec(-L/2, 0, d/2), axis=vec(0, 0, -0.1), shaftwidth=size, color=color.orange)
label_E = label(pos=vec(-L/2, d/2, 0), text="E", xoffset=-25, yoffset=25, color=color.green, font="sans")
label_B = label(pos=vec(-L/2, 0, d/2), text="B", xoffset=-25, yoffset=-25, color=color.orange, font="sans")
# 產生表示速度、加速度的箭頭
arrow_v = arrow(pos=charge.pos, shaftwidth=0.3*size, color=color.cyan)
arrow_a = arrow(pos=charge.pos, shaftwidth=0.3*size, color=color.magenta)
"""
3. 物體運動部分, 當帶電粒子到達畫面最右側、撞到平行帶電板或撞到擋板時停止
"""
while((charge.pos.x + size + b1.length/2 < L/2 and abs(charge.pos.y) < d/2 - p1.height - size) or \
(L/2 < charge.pos.x + size + b1.length/2 < L and abs(charge.pos.y) < 0.1*size)):
rate(500)
# 計算帶電粒子所受合力, 在平行帶電板間才有電場、磁場
if(-L/2 <= charge.pos.x <= L/2): F = q*(E_field + cross(charge.v, B_field))
else: F = vector(0, 0, 0)
# 更新帶電粒子加速度、速度、位置
charge.a = F/charge.m
charge.v += charge.a*dt
charge.pos += charge.v*dt
# 更新表示速度、加速度的箭頭, 只畫出方向以避免動畫自動縮小
arrow_v.pos = charge.pos
arrow_a.pos = charge.pos
arrow_v.axis = charge.v.norm()*0.05
arrow_a.axis = charge.a.norm()*0.05
# 更新時間
t += dt
```
<br />
### 程式設計部分
實際上只修改了3處:
1. 在出口處加上擋板
```python
b1 = box(pos=vec(L/2, d/4 + size, 0), size=vec(0.01*L, 0.5*d, L), color = color.gray(0.7))
b2 = box(pos=vec(L/2, -d/4 - size, 0), size=vec(0.01*L, 0.5*d, L), color = color.gray(0.7))
```
2. while 迴圈運作的條作改為
```python
(charge.pos.x + size + b1.length/2 < L/2 and abs(charge.pos.y) < d/2 - p1.height - size) or \
(L/2 < charge.pos.x + size + b1.length/2 < L and abs(charge.pos.y) < 0.1*size)
```
(a) 第1個部分的效果:當粒子在平行帶電板之間,如果還沒有撞到平行帶電板則動畫繼續進行。
(b) 第2個部分的效果:當粒子還未到達畫面邊緣且沒有撞到擋板則動畫繼續進行。
<br />
### 模擬結果
以下是5種不同的數據組合及測試結果:
1. v0 = 10, V = 1, d = 0.1, B = 1 ⇒ 等速度直線運動
2. q > 0, v0 = 20 其它條件與組合1相同 ⇒ 向上偏移
3. q > 0, d = 0.2 其它條件與組合1相同 ⇒ 向上偏移
4. q > 0, V = 2 其它條件與組合1相同 ⇒ 向下偏移
5. q > 0, B = 5 其它條件與組合1相同 ⇒ 向上偏移
<img style="display: block; margin-left: auto; margin-right: auto" height="80%" width="80%" src="https://i.imgur.com/tT4G1Cb.png">
<div style="text-align:center">程式 20-2 數據組合1畫面截圖</div>
<br />
<img style="display: block; margin-left: auto; margin-right: auto" height="80%" width="80%" src="https://i.imgur.com/b7kyvyM.png">
<div style="text-align:center">程式 20-2 數據組合2畫面截圖</div>
<br />
<img style="display: block; margin-left: auto; margin-right: auto" height="80%" width="80%" src="https://i.imgur.com/KcqbDJK.png">
<div style="text-align:center">程式 20-2 數據組合3畫面截圖</div>
<br />
<img style="display: block; margin-left: auto; margin-right: auto" height="80%" width="80%" src="https://i.imgur.com/ZuPy9No.png">
<div style="text-align:center">程式 20-2 數據組合4畫面截圖</div>
<br />
<img style="display: block; margin-left: auto; margin-right: auto" height="80%" width="80%" src="https://i.imgur.com/CAGgU7S.png">
<div style="text-align:center">程式 20-2 數據組合5畫面截圖</div>
<br />
## 結語
我一開始想要全部採用真實數據製作動畫,例如將 q 和 m 設定電子的電量和質量,但是這樣在帶電粒子合力不為零時粒子的加速度非常大,很難看清楚粒子運動的過程,所以才會將粒子的質量增加很多。這個動畫的目的是為了看出粒子的受力情形與偏轉方向,雖然不是採用真實數據,但至少能清楚地看到粒子的運動過程。
<br />
## VPython官方說明書
1. **canvas**: http://www.glowscript.org/docs/VPythonDocs/canvas.html
2. **box**: http://www.glowscript.org/docs/VPythonDocs/box.html
3. **cylinder**: http://www.glowscript.org/docs/VPythonDocs/cylinder.html
4. **sphere**: http://www.glowscript.org/docs/VPythonDocs/sphere.html
5. **arrow**: http://www.glowscript.org/docs/VPythonDocs/arrow.html
6. **label**: http://www.glowscript.org/docs/VPythonDocs/label.html
---
###### tags:`VPython`