05-2 橢圓內的光線反射(光線依序反射)

有順序地呈現路徑
上次所做的作品,是把近200次的光線反射的路徑全部顯示出來。
雖然說光的行走速度很快,快到這200次的反射對人而言就是瞬間的事情,不過我們還是會想要依序呈現光線的路徑。
步驟0 利用上次製作橢圓反射的檔案
可以直接複製上次的檔案,或者就按照步驟,依序製造光線反射的元素。
不過在此處,我們除了不顯示B,C,D欄的元素之外,向量也都不先要製作出來(不要製造或刪除原本的E欄元素)。
此處所用的範本,是保留A2:D50
在此處製作 橢圓上的光線反射(試算表製作)
步驟1 製作數值滑桿
在主繪圖區找一個閒置區域,製作數值滑桿
,設定如下:
名稱:t 類型:數值 最小:1 最大:50 增量:0.05
若你在前一步製作時,是複製到第200列,則最大值改成200
先讓t維持在t=1。
接著,對著數值滑桿t,按下右鍵點選屬性,在滑桿頁籤之中的「動畫」,
將重複改成「遞增」或者「遞增(一次)」

步驟2 利用分點公式製作出會隨時間移動的向量
在指令列輸入
E2 = Vector(A1, (1 - (t-1)) A1 + ( t-1 ) A2)
其中,(1 - (t-1)) A1 + ( t-1 ) A2,就是一個從A1往A2方向移動的點,隨著t變大,該點就越來越遠離A1。
這樣製作後,當t從1變大到2時,就會看到向量由A1射向A2。
當然,當t超過2的時候,就會發現這個向量射過頭了。
步驟3 利用Max,Min函數來控制向量的範圍
在指令列輸入
E2 = Vector(A1, (1 - Min(Max(t - 1, 0), 1)) A1 + Min(Max(t - 1, 0), 1) A2)
其中 Min(Max(t - 1, 0), 1) 會有以下效果:
當t<1時,這裡會是0 ;當t = 1.7時,這裡會是0.7;當t>1時,這裡會是1 。
步驟4 製作第二條可變動的向量
在指令列輸入
E3 = Vector(A2, (1 - Min(Max(t - 2, 0), 1)) A2 + Min(Max(t - 2, 0), 1) A3)
當t<1時,E3是零向量 ;當t = 2.7時,E3是0.7倍的向量(A2A3);當t>2時,E3是完整的向量(A2A3) 。
到這一步,看似可以直接開始複製了,但很可惜,複製之後,你會看到其他條向量會同時跑出來,而非依序跑出。
這是因為E2中的t-1 、E3中的t-2,它們之中的1和2,不會隨著複製而一起變大。
這裡就只好靠一個把戲來處理這件事。
步驟5 製作E4~E50
(1) 輸入F2=1 以及 F3=2
(2) 在試算表中,將F2,F3一起用框住,再向下拉到F50,使得F4 = 3、F5 = 4、F6 = 5、......、F50 = 49
(3) 將E2 改成 E2 = Vector(A1, (1 - Min(Max(t - F2, 0), 1)) A1 + Min(Max(t - F2, 0), 1) A2)
E3 改成 E3 = Vector(A2, (1 - Min(Max(t - F3, 0), 1)) A2 + Min(Max(t - F3, 0), 1) A3)
(4) 在試算表中,將E2,E3一起用框住,再向下拉到E50,這樣就能做出49條依序出現的向量(光線)了。
接著手動拉動數值滑桿t或者將其「開始動畫」,即可看到光線前進的樣子。

進階調整:等速處理
當你開始動畫的時候,也許可以觀察到,光線行走的樣子有點不協調。這個不協調感是來自於光線行走的速度不一致所導致的。
這是因為t變大的速度是等速的,也就是說,不論向量的長短,向量從零向量成長到完整的向量,所耗費的時間是一樣的,所以便造成了光線(向量)行走速度不一致的問題。
這裡接下來會使用兩種方法來處理速度不一致的問題。
進階步驟6 方法1:調整數值滑感的速度
不論n是哪個正整數,數值滑桿t從n-1到n的速度都是一樣的,但向量En的長度卻隨n不同而有所改變。
那麼,我們調整t從n-1到n的速度,讓它隨著n(或向量En的長度)而變,就可以製造等速的效果。
(1) 輸入 G2 = Segment(A1, If(F2 ≤ t < F2 + 1, A2, A1))
G3 = Segment(A2, If(F3 ≤ t < F3 + 1, A3, A2))
(2) 在試算表中,將G2,G3一起用框住,再向下拉到G50,使得G4~G50都是同樣的設置,這樣就能做出49條特殊線段了。記得將G欄的物件都隱藏(不要顯示物件)。
這些線段,同時也是數值(線段長度),而這樣設置所產生的效果,便是當n-1 ≤ t < n時,Gn的數值為An-1和An的距離,即是完整的向量En之長度;當n-1 > t或t ≥ n時,Gn便是0。
(3) 輸入 sp = Max(G2:G50)
(4) 進入數值滑桿t的屬性,滑桿頁籤中的「動畫」,將速度改為0.7/sp
這裡的sp所顯示的數值,便是當下正在成長的向量,其完整的長度。而我們就用這個數值,來調整t從n-1到n的速度。這樣當數值滑桿t開始動畫時,光線(向量)行走的速度就會是一致的。
不過,如果你是按住方向鍵調整數值滑桿t來製造動畫效果,或者你要匯出GIF動畫,那這招就不管用了。

若要匯出GIF檔,必須要使用下面的方法2

進階步驟6 方法2:調整數值滑感t的意義
因為匯出動態GIF時,輸出的動畫張數和速度,與t的總長以及t的增量有關,與動畫速度完全無關。所以使用上個方法,匯出後仍會產生不等速的狀況。若要調整,就必須把t的意義作個改變。
之前的t,(t的整數部分)所代表的是現在走到第幾個向量,而現在,我們要把t改成光線目前已經走的路徑長度。
(1) 輸入 F2 = Segment(A1, A2)
F3 = Segment(A2, A3)
接著在試算表中,將F2,F3一起用框住,再向下拉到F50,使得F4~F50都是同樣的設置,這樣就能做出49條線段了。記得將F欄的物件都隱藏(不要顯示物件)。
(2) 輸入 G1 = Polyline(A$1:A1)
G2 = Polyline(A$1:A2)
G3 = Polyline(A$1:A3)
接著在試算表中,將G2,G3一起用框住,再向下拉到G50,使得G4~G50都是同樣的設置,這樣就能做出50條折線了。記得將G欄的物件都隱藏(不要顯示物件)。
這些線段與折線,同時也是數值(線段長度或折線總長度)。
Fn代表的是第n條向量的完整長度,這會用來調整比例。
Gn代表的是光線要走了多長的路徑之後,才會開始跑第n+1條向量。
(3) 對著數值滑桿t按下右鍵,選擇屬性,將其最大值改為G50,增量改成0.5。
增量的值越小,動畫就會越細緻,但輸出GIF時,所要輸出的張數就會越多,檔案就越大,整個GIF動畫也會更久;反之亦然。
既然我們已經改變了t所代表的意義,那向量En的定義勢必也要重新改寫。
(3) 輸入 E2 = Vector(A1, (1 - Min( Max( (t - G1) / F2, 0), 1))*A1 + Min( Max( (t - G1) / F2, 0), 1)*A2)
E3 = Vector(A2, (1 - Min( Max( (t - G2) / F3, 0), 1))*A2 + Min( Max( (t - G2) / F3, 0), 1)*A3)
接著在試算表中,將E2,E3一起用框住,再向下拉到E50,使得E4~E50都是同樣的設置,這樣就能做出49條依序出現的向量(光線)了。
在此處舉例說明一下,當t介於G2~G3時,(t - G2) / F3也會介於0~1之間,這時就會看到光線從A2走到A3。
如此,便成功地將每條向量(光線)行走的速度調成一致的了。
這時,不論是將t開始動畫、用鍵盤手動將t增量,或者是匯出GIF檔案,都會是等速的狀態。