# 速度選擇器 > 作者:王一哲 > 日期: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`