熱門文章

2018年2月2日 星期五

水波節線、腹線

水波節線、腹線
 日期:2018/2/2
這是一個很常見的指考題:「假設在水波槽中有兩個同相的點波源,點波源間的距離為L,水波波長為λ,請計算水波槽上節線與腹線的數量分別為多少?」解答如下:「由於兩個波源同相,兩個水波在正中央的波程差為0,中央一定是腹線,由中央腹線向左右兩側移動λ/4會遇到節線,再移動λ/4會遇到腹線,按照這個規律就可以找到所有的節線及腹線。」但是否能用 GeoGebra 畫出答案呢?下圖就是最後的成果。我也有將檔案傳到 GeoGebra 的網站,可以直接在網頁上玩玩看https://ggbm.at/uSjh5KWT
L = 12、λ = 2 ~ 12 的節線、腹線位置


繪圖步驟

1. 先在繪圖區上新增兩個點波源S1、S2的位置,選取工具列上的新點接著用滑鼠在繪圖區x軸上點左鍵兩下,或是直接用指令
S_1 = Point({-6, 0})
S_2 = Point({6, 0})
工具:新點

2. 找到S1、S2的中點C,選取工具列上的中心點接著用滑鼠在S1、S2上各點左鍵一下,或是直接用指令
C = Midpoint(S_1, S_2)
工具:中心點

3. 畫出過C點且垂直於x軸的直線,選取工具列上的垂直線接著用滑鼠在C和x軸上各點左鍵一下,或是直接用指令
a = PerpendicularLine(C, xAxis)
工具:垂直線

4. 新增控制波長λ的數值滑桿,最小值2,最大值12,增量0.1,或是直接用指令
λ = Slider(2, 12, 0.1)

5. 定義S1、S2之間的距離
len = abs(x(S_2) - x(S_1))
上式中 abs 代表取絕對值,例如 abs(-1.9) = 1.9。x(S_2)代表讀取S_2的x座標值。

6. 定義腹點數量 n_a
n_a = floor(len / λ)*2 + 1
上式中 floor 代表無條件捨去,例如 floor(1.9) = 1。

7. 定義節點數量 n_n
n_n = round(len / λ)*2
上式中 round 代表4捨5入,例如 round(1.5) = 2。

8. 定義x方向單位向量u並設定為不顯示
u = Vector((0, 0), (1, 0))
這是等一下要畫射線用的,先設定好比較方便。上式指令格式為 Vector(起點座標, 終點座標)

9. 畫出右半邊的腹點
antinode = Sequence(Point({x(C) + λ/2*i, y(C)}), i, 0, (n_a - 1) / 2, 1)
上式指令格式為 Sequence(含有變數i的表達式, i, i的初值, i的末值, 增量),增量的預設值為1,可以省略。這在這用的表達式為 Point({x(C) + λ/2*i, y(C)}),意思是在 (C點 x 座標 + i 個半波長, C點 y 座標)處畫點。i的末值為 (n_a - 1) / 2 是為了扣掉中央腹點後再除以2。

10. 畫出左半邊的腹點,由於圖形左右對稱,可以用鏡射的方式偷懶,選取工具列上的線對稱接著用滑鼠在右半邊的腹點和直線a上各點左鍵一下,或是直接用指令
antinode' = Reflect(antinode, a)
上式指令格式為 Reflect(物件名稱, 對稱線名稱)
工具:線對稱

11. 畫出大部分的腹線
antinodeline = If(x(antinode((n_a + 1) / 2)) != x(S_2)Sequence(Hyperbola(S_1, S_2, antinode(i)), i, 1, (n_a + 1) / 2, 1), Sequence(Hyperbola(S_1, S_2, antinode(i)), i, 1, (n_a - 1) / 2, 1))
這應該是整個過程當中最麻煩的一個步驟,If 當中的條件是用來檢驗波源上是否正好為腹點,如果不是的話就將所有的腹線都畫出來,如果是的話不畫出最後一組腹線。會這麼麻煩是因為當波源上正好是腹點時,會有一條腹線是以波源為起點、向外延伸的射線。如果只用
Sequence(Hyperbola(S_1, S_2, antinode(i)), i, 1, (n_a + 1) / 2, 1)
當波源上正好是腹點時圖形會變為下圖。還有用到繪製雙曲線的指令,格式為 Hyperbola(焦點1, 焦點2, 除了焦點外任一點),我們用 Sequence 將 antinode 串列裡的腹點依序代入,由於雙曲線左右對稱,所以只要代入右側的腹點即可。
效果較差的腹線

12. 畫出波源上的腹線
r_a = If(x(antinode((n_a + 1) / 2)) == x(S_2), Ray(S_2, u))
當波源上有腹點時才畫。另外用到繪製射線的指令,格式為 Ray(起點, 射線方向的向量)。再用線對稱畫出另一邊的腹線
r_a' = Reflect(r_a, a)
效果較好的腹線

13. 畫出大部分的節線
nodeline = If(x(node(n_n / 2)) != x(S_2)Sequence(Hyperbola(S_1, S_2, node(i)), i, 1, n_n / 2, 1), Sequence(Hyperbola(S_1, S_2, node(i)), i, 1, n_n / 2 - 1, 1))

14. 畫出波源上的節線
r_n = If(x(node(n_n / 2)) == x(S_2), Ray(S_2, u))
r_n' = Reflect(r_n, a)
效果較好的節線

15. 畫出波峰波前
crest = Sequence(Circle(S_1, λ*i), i, 1, n_n)
crest’ = Sequence(Circle(S_2, λ*i), i, 1, n_n)

16. 畫出波谷波前
trough = Sequence(Circle(S_1, λ*(i - 0.5)), i, 1, n_n)
trough’ = Sequence(Circle(S_2, λ*(i - 0.5)), i, 1, n_n)

17. 新增控制是否顯示波前的核取方塊
front = Checkbox({crest, crest’, trough, trough’})
核取方塊的指令格式為 Check({物件1, 物件2, …}),其實 Checkbox 代表布林值,打鈎時為 true 顯示物件,沒打鈎時為 false 隱藏物件。
同相位干涉範例(顯示波前)

同相位干涉範例(不顯示波前)

結論

  雖然使用工具列及滑鼠就能畫出許多有用的圖,雖然用指令繪圖比較麻煩,但是有一些效果只有用指令才能做到,值得花時間學習指令的用法。另外還有一個必須克服的麻煩,就是在搜尋資料時通常英文的資料遠比中文的資料還多,尤其是像這類由國外開發的軟體更是如此。感謝各位能夠看到最後。

相關指令的官方說明書


  1. 點     https://wiki.geogebra.org/en/Point_Command 
  2. 中心點           https://wiki.geogebra.org/en/Midpoint_Command 
  3. 垂直線           https://wiki.geogebra.org/en/PerpendicularLine 
  4. 數值滑桿        https://wiki.geogebra.org/en/Slider_Command 
  5. 向量               https://wiki.geogebra.org/en/Vector_Command 
  6. 線對稱           https://wiki.geogebra.org/en/Reflect_Command 
  7. 串列               https://wiki.geogebra.org/en/Sequence_Command 
  8. 雙曲線           https://wiki.geogebra.org/en/Hyperbola_Command 
  9. 核取方塊       https://wiki.geogebra.org/en/Checkbox_Command 

沒有留言:

張貼留言