# 電流的磁效應 > 作者:王一哲 > 日期:2018/5/14 <br /> 選修物理下第8章電流的磁效應會介紹必歐 - 沙伐定律 (Biot–Savart law),用來計算一小段載流導線於空間中某處產生的磁場,方程式為 $$ d \vec B = \frac{\mu_0}{4\pi} \frac{I d \vec L \times \hat r}{r^2} ~\Rightarrow~ dB = \frac{\mu_0}{4\pi} \frac{I dL \sin \theta}{r^2} $$ 利用必歐 - 沙伐定律可以算出長直載流導線垂直距離 r 處的磁場量值為 $$ B = \frac{\mu_0 I}{2 \pi r} $$ 半徑為 r 的載流線圈圓心處的磁場量值為 $$ B = \frac{\mu_0 I}{2 r} $$ 單位長度中有 n 匝線圈的的載流螺線管中心處的磁場量值為 $$ B = \mu_0 nI $$ 磁場應該是分布在空間中的,但是書上的圖卻都是平面的,因此我想要藉由 VPython 將空間中的磁場強度、方向畫出來,成果如下圖。 <img style="display: block; margin-left: auto; margin-right: auto" height="60%" width="60%" src="https://i.imgur.com/Xb3rU8V.png"> <div style="text-align:center">載流螺線管產生的磁場示意圖</div> <br /> ## 程式 25-1.長直載流導線產生的磁場 ([取得程式碼](https://github.com/YiZheWangTw/VPythonTutorial/blob/master/25.%E9%9B%BB%E6%B5%81%E7%9A%84%E7%A3%81%E6%95%88%E6%87%89/25-1.B_line.py)) ([GlowScript 網站動畫連結](https://www.glowscript.org/#/user/yizhe/folder/Public/program/25-1.Bline)) ```python= """ VPython教學: 25-1.長直載流導線產生的磁場 Ver. 1: 2018/4/20 Ver. 2: 2019/9/19 作者: 王一哲 """ from vpython import * """ 1. 參數設定, 設定變數及初始值 """ size = 0.4 # 導線截面的半徑 n = 200 # 導線分割成 n 等份 L = 80 # 導線長度, 畫面寬度 d = L/n # 導線分割後每段的長度 mu = 4*pi*1E-7 # 真空中的磁導率 current = 5E8 # 電流量值 direct = True # 電流方向, True 為姆指向右, Fasle 為姆指向左, 改變 dr 計算方式 N = 9 # 將顯示的空間每邊切成 N 等份 """ 2. 畫面設定 """ # 產生動畫視窗及導線 scene = canvas(title="Magnetic Field of Current Line", width=600, height=600, x=0, y=0, center=vec(0, 0.1*L, 0), background=color.black) line = cylinder(pos=vec(-0.5*L, 0, 0), axis=vec(L, 0, 0), radius=0.2*size, color=color.blue) # 產生串列 segs, 用 for 迴圈產生導線分割後的小球並填入串列 segs 中 #segs = [] #for i in range(n+1): # segs.append(sphere(pos=line.pos + vec(i*d, 0, 0), radius=size, color=color.cyan)) segs = [sphere(pos=line.pos + vec(i*d, 0, 0), radius=size, color=color.cyan) for i in range(n+1)] # 計算畫箭頭的位置並加到串列 locations 當中 locations = [] for i in range(N+1): for j in range(N+1): for k in range(N+1): location = vec(L/N*i - L/2, L/N*j - L/2, L/N*k - L/2) locations.append(location) # 自訂函式 magnetic, 計算某個位置的磁場 def magnetic(loc, segments): field = vec(0, 0, 0) for segment in segments: axis = loc - segment.pos if(direct): dr = vec(1, 0, 0) else: dr = vec(-1, 0, 0) field += mu*current/(4*pi)*d*cross(dr, axis.norm())/axis.mag2 return field # 依序讀取串列 locations 的元素, 在對應的位置產生箭頭 #fields = [] #for location in locations: # fields.append(arrow(pos=location, axis=vec(0, 0, 0), color=color.green)) fields = [arrow(pos=location, axis=vec(0, 0, 0), color=color.green) for location in locations] # 更新箭頭的長度及方向, 記錄磁場強度最大值, 量值接近最大值偏紅色, 量值接近 0 偏綠色 Bmax = 0 for field in fields: value = magnetic(field.pos, segs) if(value.mag >= Bmax): Bmax = value.mag field.axis = value for field in fields: field.color = vec(field.axis.mag/Bmax, 1 - field.axis.mag/Bmax, 0) ``` <br /> ### 參數設定 在此設定變數為 size、n、L、d、mu、current、direct、N,用途已寫在該行的註解當中。為了增加磁場量值,使箭頭的長度較為明顯,設定的電流量值非常地大。 <br /> ### 畫面設定 1. 產生動畫視窗及導線。 2. 產生空白串列 segs,用 for 迴圈產生導線分割後的小球並填入串列 segs 中。以下兩種寫法的效果相同,第一種寫法行數較多但比較容易看懂,第二種寫法比較精簡但是不容易看懂。 ```python segs = [] for i in range(n+1): segs.append(sphere(pos=line.pos + vec(i*d, 0, 0), radius=size, color=color.cyan)) ``` ```python segs = [sphere(pos=line.pos + vec(i*d, 0, 0), radius=size, color=color.cyan) for i in range(n+1)] ``` 3. 產生空白串列 locations,使用 3 層的 for 迴圈計算畫箭頭的位置並加到串列 locations 當中,同樣有兩種寫法。 ```python fields = [] for location in locations: fields.append(arrow(pos=location, axis=vec(0, 0, 0), color=color.green)) ``` ```python fields = [arrow(pos=location, axis=vec(0, 0, 0), color=color.green) for location in locations] ``` 4. 自訂函式 magnetic,輸入的參數 loc 是要計算磁場的位置坐標,segments 儲存分割後導線資料的串列,利用必歐 - 沙伐定律計算磁場。 5. 依序讀取串列 locations 的元素,在對應的位置產生箭頭。 6. 更新箭頭的長度及方向,記錄磁場強度最大值 Bmax,量值接近最大值箭頭偏紅色, 量值接近 0 箭頭偏綠色。 <br /> ### 模擬結果 試著修改 n、L、N 的數值,找出視覺效果較好的組合。有時候程式會出現錯誤,這是因為箭頭的位置正好在導線上,分母為0,如果要徹底避免這個錯誤,應該要加上一段程式碼,檢查箭頭與導線的位置是否重疊。 <img style="display: block; margin-left: auto; margin-right: auto" height="80%" width="80%" src="https://i.imgur.com/tXcVRS5.png"> <div style="text-align:center">程式 25-1:n = 100, L = 40, N = 5 畫面截圖</div> <br /> <img style="display: block; margin-left: auto; margin-right: auto" height="80%" width="80%" src="https://i.imgur.com/IHdM5Yt.png)"> <div style="text-align:center">程式 25-1:n = 200, L = 80, N = 9 畫面截圖</div> <br /> <img style="display: block; margin-left: auto; margin-right: auto" height="80%" width="80%" src="https://i.imgur.com/ug0uYO5.png"> <div style="text-align:center">程式 25-1:n = 200, L = 80, N = 9, 電流向左畫面截圖</div> <br /> ## 程式 25-2.載流線圈產生的磁場 ([取得程式碼](https://github.com/YiZheWangTw/VPythonTutorial/blob/master/25.%E9%9B%BB%E6%B5%81%E7%9A%84%E7%A3%81%E6%95%88%E6%87%89/25-2.B_loop.py)) ([GlowScript 網站動畫連結](http://www.glowscript.org/#/user/yizhe/folder/Public/program/25-2.Bloop)) ```python= """ VPython教學: 25-2.載流線圈產生的磁場 Ver. 1: 2018/4/10 Ver. 2: 2018/4/20 可調整範圍 Ver. 3: 2019/9/19 作者: 王一哲 """ from vpython import * """ 1. 參數設定, 設定變數及初始值 """ size = 0.4 # 線圈截面的半徑 r = 10 # 線圈的半徑 n = 100 # 線圈分割成 n 等份 part = 1.0 # 完整的線圈 part = 1 d = 2*pi*r*part/n # 線圈分割後每段的長度 mu = 4*pi*1E-7 # 真空中的磁導率 current = 5E8 # 電流量值 direct = True # 電流方向, True 為姆指向上, Fasle 為姆指向下, 改變 dr 計算方式 L = 40 # 畫面寬度 N = 5 # 將顯示的空間每邊切成 N 等份 Bmax = 5 # 顯示的磁場最大值 """ 2. 畫面設定 """ # 產生動畫視窗及線圈 scene = canvas(title="Magnetic Field of Current Loop", width=600, height=600, x=0, y=0, center=vec(0, 0.1*L, 0), background=color.black) loop = ring(pos=vec(0, 0, 0), axis=vec(0, 1, 0), radius=r, thickness=0.2*size, color=color.blue) # 產生串列 segs, 用 for 迴圈產生圓環分割後的小球並填入串列 segs 中 segs = [sphere(pos=vec(r*cos(i*2*pi*part/n), 0, -r*sin(i*2*pi*part/n)), radius=size, color=color.cyan) for i in range(n)] # 計算畫箭頭的位置並加到串列 locations 當中 locations = [] for i in range(N+1): for j in range(N+1): for k in range(N+1): location = vec(L/N*i - L/2, L/N*j - L/2, L/N*k - L/2) locations.append(location) # 自訂函式 magnetic, 計算某個位置的磁場 def magnetic(loc, segments): field = vec(0, 0, 0) for segment in segments: axis = loc - segment.pos if(direct): dr = norm(vec(segment.pos.z, 0, -segment.pos.x)) else: dr = norm(vec(-segment.pos.z, 0, segment.pos.x)) field += mu*current/(4*pi)*d*cross(dr, axis.norm())/axis.mag2 return field # 依序讀取串列 locations 的元素, 在對應的位置產生箭頭 fields = [arrow(pos=location, axis=vec(0, 0, 0), color=color.green) for location in locations] # 更新箭頭的長度及方向, 若磁場量值 >= Bmax 則設定為 Bmax, 以避免箭頭蓋住其它東西 # 量值接近 Bmax 偏紅色, 量值接近 0 偏綠色 for field in fields: value = magnetic(field.pos, segs) if(value.mag >= Bmax): value = value.norm() * Bmax field.axis = value field.color = vec(value.mag/Bmax, 1 - value.mag/Bmax, 0) ``` <br /> ### 程式設計部分 程式 25-2 與 25-1 非常相似,以下只說明不同之處。 1. 在此設定變數為 size、r、n、part、d、mu、current、direct、L、N、Bmax。由於磁場量值差異很大,因此將 Bmax 直接設定好,而不是從計算得到的值當中找最大值。 2. 使用 ring 物件產生線圈。 3. 圓環分割後的小球由 (r, 0, 0) 開始擺放,若由 +y 軸向原點看去,擺放的方向為逆時鐘方向,因此位置設定為 ```python (r*cos(i*2*pi*part/n), 0, -*sin(i*2*pi*part/n)) ``` 4. 在自訂函式中若電流為逆時鐘方向,也就是 **direct = True**,則 dr 設定為 ```python norm(vec(segment.pos.z, 0, -segment.pos.x)) ``` 反之設定為 ```python norm(vec(-segment.pos.z, 0, segment.pos.x)) ``` <br /> ### 模擬結果 修改 part 的數值,可以畫出不同比例的載流線圈產生的磁場,例如 part = 0.25 代表 1/4 個線圈。也可以修改 direct 控制電流的方向,觀察電方向對磁場的影響。 <img style="display: block; margin-left: auto; margin-right: auto" height="80%" width="80%" src="https://i.imgur.com/frKxT0o.png"> <div style="text-align:center">程式 25-2: 1/4 個載流線圈磁場示意圖</div> <br /> <img style="display: block; margin-left: auto; margin-right: auto" height="80%" width="80%" src="https://i.imgur.com/znx6VOm.png"> <div style="text-align:center">程式 25-2: 半個載流線圈磁場示意圖</div> <br /> <img style="display: block; margin-left: auto; margin-right: auto" height="80%" width="80%" src="https://i.imgur.com/GK1KVFg.png"> <div style="text-align:center">程式 25-2: 3/4 個載流線圈磁場示意圖</div> <br /> <img style="display: block; margin-left: auto; margin-right: auto" height="80%" width="80%" src="https://i.imgur.com/xy9Vn5e.png"> <div style="text-align:center">程式 25-2: 整個載流線圈磁場示意圖</div> <br /> <img style="display: block; margin-left: auto; margin-right: auto" height="80%" width="80%" src="https://i.imgur.com/20bJj2i.png"> <div style="text-align:center">程式 25-2: 整個載流線圈磁場示意圖(電流為順時鐘方向)</div> <br /> ## 程式 25-3.2個載流線圈產生的磁場 ([取得程式碼](https://github.com/YiZheWangTw/VPythonTutorial/blob/master/25.%E9%9B%BB%E6%B5%81%E7%9A%84%E7%A3%81%E6%95%88%E6%87%89/25-3.B_loops.py)) ([GlowScript 網站動畫連結](http://www.glowscript.org/#/user/yizhe/folder/Public/program/25-3.Bloops)) ```python= """ VPython教學: 25-3.2個載流線圈產生的磁場 Ver. 1: 2018/4/11 Ver. 2: 2018/4/20 可調整範圍 Ver. 3: 2019/9/19 作者: 王一哲 """ from vpython import * """ 1. 參數設定, 設定變數及初始值 """ size = 0.4 # 線圈截面的半徑 r = 10 # 線圈的半徑 n = 100 # 線圈分割成 n 等份 part = 1.0 # 完整的線圈 part = 1 d = 2*pi*r*part/n # 線圈分割後每段的長度 delta = r # 線圈圓心之間的距離為 2*delta mu = 4*pi*1E-7 # 真空中的磁導率 current = 5E8 # 電流量值 direct = True # 電流方向, True 為姆指向上, Fasle 為姆指向下, 改變 dr 計算方式 L = 40 # 畫面寬度 N = 5 # 將顯示的空間每邊切成 N 等份 Bmax = 5 # 顯示的磁場最大值 """ 2. 畫面設定 """ # 產生動畫視窗及線圈 scene = canvas(title="Magnetic Field of Two Current Loops", width=600, height=600, x=0, y=0, center=vec(0, 0.1*L, 0), background=color.black) loop1 = ring(pos=vec(0, delta, 0), axis=vec(0, 1, 0), radius=r, thickness=0.2*size, color=color.blue) loop2 = ring(pos=vec(0, -delta, 0), axis=vec(0, 1, 0), radius=r, thickness=0.2*size, color=color.blue) # 產生串列 segs, 用 for 迴圈產生圓環分割後的小球並填入串列 segs 中 segs1, segs2 = [], [] for i in range(n): segs1.append(sphere(pos=vec(r*cos(i*2*pi*part/n), delta, -r*sin(i*2*pi*part/n)), radius=size, color=color.cyan)) segs2.append(sphere(pos=vec(r*cos(i*2*pi*part/n), -delta, -r*sin(i*2*pi*part/n)), radius=size, color=color.cyan)) # 計算畫箭頭的位置並加到串列 locations 當中 locations = [] for i in range(N+1): for j in range(N+1): for k in range(N+1): location = vec(L/N*i - L/2, L/N*j - L/2, L/N*k - L/2) locations.append(location) # 自訂函式 magnetic, 計算某個位置的磁場 def magnetic(loc, segments): field = vec(0, 0, 0) for segment in segments: axis = loc - segment.pos if(direct): dr = norm(vec(segment.pos.z, 0, -segment.pos.x)) else: dr = norm(vec(-segment.pos.z, 0, segment.pos.x)) field += mu*current/(4*pi)*d*cross(dr, axis.norm())/axis.mag2 return field # 依序讀取串列 locations 的元素, 在對應的位置產生箭頭 fields = [arrow(pos = location, axis = vec(0, 0, 0), color = color.green) for location in locations] # 更新箭頭的長度及方向, 若磁場量值 >= Bmax 則設定為 Bmax, 以避免箭頭蓋住其它東西 # 量值接近 Bmax 偏紅色, 量值接近 0 偏綠色 for field in fields: value1 = magnetic(field.pos, segs1) value2 = magnetic(field.pos, segs2) value = value1 + value2 if(value.mag >= Bmax): value = value/value.mag * Bmax field.axis = value field.color = vec(value.mag/Bmax, 1 - value.mag/Bmax, 0) ``` <br /> ### 程式設計部分 程式 25-3 主要是為了畫出亥姆霍茲線圈 (Helmholtz coil) 的磁場,以 25-2 為基礎再加上另一個線圈,以下只說明不同之處。 1. 由於要再加上另一個線圈,需要多定義變數 delta,用來調整線圈之間的距離。兩個線圈分別位於 (0, delta, 0) 及 (0, -delta, 0) 處。 2. 圓環分割後的小球擺放方式不變,但兩個線圈分割後的小球資料分別儲存於兩個串列中。 3. 計算磁場時需要分別將 segs1 及 segs2 的資料代入自訂函式中,再算出磁場總合。 <br /> ### 模擬結果 由於亥姆霍茲線圈通常是完整的圓周,因此只調整 delta 和電流方向,觀察磁場的變化。 <img style="display: block; margin-left: auto; margin-right: auto" height="80%" width="80%" src="https://i.imgur.com/2fcE5fJ.png"> <div style="text-align:center">程式 25-3: delta = r/2 磁場示意圖(電流為逆時鐘方向)</div> <br /> <img style="display: block; margin-left: auto; margin-right: auto" height="80%" width="80%" src="https://i.imgur.com/U8lin8z.png"> <div style="text-align:center">程式 25-3: delta = r/2 磁場示意圖(電流為順時鐘方向)</div> <br /> <img style="display: block; margin-left: auto; margin-right: auto" height="80%" width="80%" src="https://i.imgur.com/x34OcrP.png"> <div style="text-align:center">程式 25-3: delta = r 磁場示意圖(電流為逆時鐘方向)</div> <br /> <img style="display: block; margin-left: auto; margin-right: auto" height="80%" width="80%" src="https://i.imgur.com/E9xh4Kq.png"> <div style="text-align:center">程式 25-3: delta = r 磁場示意圖(電流為順時鐘方向)</div> <br /> ## 程式 25-4.載流螺線管產生的磁場 ([取得程式碼](https://github.com/YiZheWangTw/VPythonTutorial/blob/master/25.%E9%9B%BB%E6%B5%81%E7%9A%84%E7%A3%81%E6%95%88%E6%87%89/25-4.B_solenoid.py)) ([GlowScript 網站動畫連結](http://www.glowscript.org/#/user/yizhe/folder/Public/program/25-4.Bsolenoid)) ```python= """ VPython教學: 25-4.載流螺線管產生的磁場 Ver. 1: 2018/4/21 Ver. 2: 2019/9/19 作者: 王一哲 """ from vpython import * """ 1. 參數設定, 設定變數及初始值 """ size = 0.4 # 螺線管截面的半徑 point_size = 0.2*size # 螺線管導線分割後標示位置用的小球半徑, 若要使小球較明顯設為1倍, 若要隱藏設為0.2倍 seg_size = 1.0*size # 螺線管導線分割後每一小段導線的半徑, 若要使導線較明顯設為1倍, 若要隱藏設為0.2倍 r = 10 # 螺線管的半徑 n = 500 # 螺線管分割成 n 等份 num = 10 # 螺線管匝數 mu = 4*pi*1E-7 # 真空中的磁導率 current = 1E8 # 電流量值 direct = True # 電流方向, True 為姆指向右, Fasle 為姆指向左, 改變 segment.axis 計算方式 L = 40 # 畫面寬度 N = 5 # 將顯示的空間每邊切成 N 等份 Bmax = 5 # 顯示的磁場最大值 """ 2. 畫面設定 """ # 產生動畫視窗 scene = canvas(title="Magnetic Field of Current Solenoid", width=600, height=600, x=0, y=0, center=vec(0, 0.1*L, 0), background=color.black) # 產生空白串列 points, 在螺線管上等距離取點並填入 points 中 points = [sphere(pos=vec(L/2 - i*L/n, r*cos(2*pi/n*num*i), r*sin(2*pi/n*num*i)), radius=point_size, color=color.cyan) for i in range(n)] # 產生空白串列 segs, 從 points 依序一次讀取兩個點, 計算軸向量, 中點位置, 將螺線管切成很多小圓柱並填入 segs 中 segs = [] for i in range(n-1): if(direct): dis = points[i+1].pos - points[i].pos else: dis = points[i].pos - points[i+1].pos mid = (points[i+1].pos + points[i].pos)/2 segs.append(cylinder(pos = mid, axis = dis, radius = seg_size, color = color.yellow)) # 計算畫箭頭的位置並加到串列 locations 當中 locations = [] for i in range(N+1): for j in range(N+1): for k in range(N+1): location = vec(L/N*i - L/2, L/N*j - L/2, L/N*k - L/2) locations.append(location) # 自訂函式 magnetic, 計算某個位置的磁場 def magnetic(loc, segments): field = vec(0, 0, 0) for segment in segments: axis = loc - segment.pos field += mu*current/(4*pi)*segment.axis.mag*cross(segment.axis, axis.norm())/axis.mag2 return field # 依序讀取串列 locations 的元素, 在對應的位置產生箭頭 fields = [arrow(pos=location, axis=vec(0, 0, 0), color=color.green) for location in locations] # 更新箭頭的長度及方向, 若磁場量值 >= Bmax 則設定為 Bmax, 以避免箭頭蓋住其它東西 # 量值接近 Bmax 偏紅色, 量值接近 0 偏綠色 for field in fields: value = magnetic(field.pos, segs) if(value.mag >= Bmax): value = value/value.mag * Bmax field.axis = value field.color = vec(value.mag/Bmax, 1 - value.mag/Bmax, 0) ``` <br /> ### 程式設計部分 程式 25-4 是以 25-2 為基礎修改而成,以下只說明不同之處。 1. 新增變數為小球的半徑 point_size、導線的半徑 seg_size、螺線管的半徑 r、螺線管的匝數 num。 2. 用 for 迴圈將 500 個小球排成縲旋線,將資料存入串列 points。 3. 用 for 迴圈從串列 points 中一次讀取相鄰的兩個小球,計算兩球連線長度與方向,以兩球的中點為起點畫出導線,將資料存入串列 segs。 <br /> ### 模擬結果 我只畫出兩種不同電流方向的磁場示意圖,可以試著改變其它參數,看看會有什麼變化。 <img style="display: block; margin-left: auto; margin-right: auto" height="80%" width="80%" src="https://i.imgur.com/czqqAfa.png"> <div style="text-align:center">程式25-4:螺線管中心處磁場向左,將小球半徑調大</div> <br /> <img style="display: block; margin-left: auto; margin-right: auto" height="80%" width="80%" src="https://i.imgur.com/3DlCBho.png"> <div style="text-align:center">程式25-4:螺線管中心處磁場向左,從側面看螺線管</div> <br /> <img style="display: block; margin-left: auto; margin-right: auto" height="80%" width="80%" src="https://i.imgur.com/sKO9QNR.png"> <div style="text-align:center">程式25-4:螺線管中心處磁場向左,從左側開口處看螺線管</div> <br /> <img style="display: block; margin-left: auto; margin-right: auto" height="80%" width="80%" src="https://i.imgur.com/oeKzKAp.png"> <div style="text-align:center">程式25-4:螺線管中心處磁場向右,從側面看螺線管</div> <br /> <img style="display: block; margin-left: auto; margin-right: auto" height="80%" width="80%" src="https://i.imgur.com/3BDNezg.png"> <div style="text-align:center">程式25-4:螺線管中心處磁場向右,從左側開口處看螺線管</div> <br /> ## 結語 這是目前已經做好的 VPython 動畫講義的最後一篇,同學們可以試著依據這些動畫為基礎,修改成自己想要的樣子,解決自己想要研究的物理問題。 <br /> ## VPython官方說明書 1. **canvas**: http://www.glowscript.org/docs/VPythonDocs/canvas.html 2. **sphere**: http://www.glowscript.org/docs/VPythonDocs/sphere.html 3. **cylinder**: http://www.glowscript.org/docs/VPythonDocs/cylinder.html 4. **ring**: http://www.glowscript.org/docs/VPythonDocs/ring.html 5. **arrow**: http://www.glowscript.org/docs/VPythonDocs/arrow.html --- ###### tags:`VPython`