計算機程式設計 Computer Programming 99-1 連豊力 台大電機系 本投影片內容乃是增修參考書籍作者張智星教授之教學資料 大綱 6-1 MATLAB 動畫簡介 6-2 以電影方式產生動畫 6-3 以物件方式產生動畫 2
6-1 MATLAB 動畫簡介 MATLAB 產生動畫的方式有兩種 : 電影方式 : 以影像的方式預存多個畫面, 再將這些畫面快速的呈現在螢幕上, 就可以得到動畫的效果 此種方式類似於電影的原理, 可以產生很繽紛亮麗的動畫, 但是其缺點為每個畫面都必需事先備妥, 無法進行即時成像 (Real-time Rendering) 而且每個畫面, 以至於整套動畫, 都必需佔用相當大的記憶體空間 3 6-1 MATLAB 動畫簡介 MATLAB 產生動畫的方式有兩種 : 物件方式 : 在 MATLAB 的 握把式圖形 的概念下, 所有的曲線或曲面均可被視為一個物件, MATLAB 可以很快的抹去舊曲線, 並產生相似但不同的新曲線, 此時就可以看到曲線隨時間而變化的效果 使用物件方式 ( 即握把式圖形 ) 所產生的動畫, 可以呈現即時的變化, 也不需要太高的記憶體需求, 但其缺點是較難產生太複雜的動畫 4
6-2 以電影方式產生動畫 以電影方式來產生動畫, 可由下列兩個步驟來達成 : 使用 getframe 指令來抓取圖形做為電影的畫面, 每個畫面都是以一個行向量的方式, 置放於整個代表電影的矩陣 使用 movie 指令來播放電影, 並可指定播放的重複次數及每秒播放的畫面數目 5 電影動畫之範例一 在下例中, 我們將以不同的角度來顯示 peaks 函數, 並將其結果以電影的方式來呈現動畫 範例 6-1: movie01.m clear M n = ; peaks; % 清除電影資料矩陣 M % 抓取 個畫面 for i = 1:n view([-37.5+i*360/n, 30]); M(i) = getframe; end % 改變觀測角度 % 抓取畫面, 並存入電影資料矩陣 M movie( M, 3 ); % 播放電影三次 6
電影動畫之範例一 1 1 1 2 2 2 3 3 3 1 2 3 4 0 1 2 3 4 0 1 2 3 4 0 1 1 1 2 2 2 3 3 3 1 2 3 4 0 1 2 3 4 0 1 2 3 4 0 7 電影動畫之範例二 將 peaks 函數畫在圓盤上, 然後再變換此函數的高度, 以動畫呈現 範例 6-2: movie02.m clear M % 清除電影資料矩陣 M r = linspace(0, 4, 30); % 圓盤的半徑 t = linspace(0, 2*pi, ); % 圓盤的極座標角度 [rr, tt] = meshgrid(r, t); xx = rr.*cos(tt); % 產生圓盤上的 x 座標 yy = rr.*sin(tt); % 產生圓盤上的 y 座標 zz = peaks(xx,yy); % 產生 peaks 在極座標的資料 n = 30; % 抓取 30 個畫面 scale = cos(linspace(0, 2*pi, n)); for k = 1:n surf( xx, yy, zz*scale(k) ); % 畫圖 axis( [-inf inf -inf inf -8.5 8.5] ); % 固定圖軸的範圍 box on M(k) = getframe; % 抓取畫面, 並存入電影資料矩陣 M end figure(2); movie(m, 5); % 播放電影 5 次 8
電影動畫之範例二 1 1 1 2 2 2 3 3 3 1 2 3 4 0 1 2 3 4 0 1 2 3 4 0 1 1 1 2 2 2 3 3 3 1 2 3 4 0 1 2 3 4 0 1 2 3 4 0 9 電影動畫之範例三 改變影像的色盤矩陣, 讓影像出現 從正片變到負片 的效果 範例 6-3: movie03.m clear M % 清除電影資料矩陣 M load clown.mat image(x); colormap(map); n = 30; % 畫出小丑臉 % 抓取 30 個畫面 scale = cos(linspace(0, 2*pi, n)); for i = 1:n colormap(((i-1)*(1-map)+(n-i)*map)/n); M(i) = getframe; % 改變色盤矩陣 % 抓取畫面, 並存入電影資料矩陣 M end movie(m, -5); % 播放電影 5 次 ( 含正向與逆向播放 ) 10
電影動畫之範例三 在上述範例中, 正片 ( 如下張投影片圖左 ) 的色盤矩陣是 map, 而 1-map 則是負片 ( 如下張投影片圖右 ) 的色盤矩陣, 因此我們在抓影片時, 讓色盤矩陣進行漸進式的變化, 因此呈現的電影就有 從正片變到負片 的效果 另外,movie(M, -5) 代表電影將播放 5 次, 但由於第二個參數是負數, 所以每次播放會包含一次 正向播放 及一次 逆向播放 11 電影動畫之範例三 正片 負片 色盤矩陣是 map 色盤矩陣是 1-map 12
6-3 以物件方式產生動畫 以電影方式產生動畫可以說是 暴力法, 因為此方法佔掉了許多記憶體空間 另一個技巧性較高的方法則是以物件方式產生動畫, 此種方法不需要大量的記憶體, 而且可以產生 即時 (Real-time) 或 互動式 (Interactive) 的動畫 13 6-3 以物件方式產生動畫 MATLAB 的所有圖形元件 ( 曲線 曲面 圖軸等 ) 都是物件, 您可以控制這些物件的各種性質, 此種特性稱為 握把式圖形 (Handle Graphics) 握把式圖形包含的層面很廣, 但牽涉到動畫部份的基本概念並不複雜, 以下我們以曲線的動畫來說明 14
曲線的動畫 我們可以快速地改變圖形物件的性質 ( 如顏色 座標等 ), 就可以達到動畫的效果 每一條曲線都有下列三種性質 : xdata: 此為一向量, 代表曲線的 x 座標值 ydata: 此為一向量, 代表曲線的 y 座標值 EraseMode: 此為一字串, 代表曲線被抹除的方式, 亦即當 xdata 或 ydata 被改變時, 對於舊曲線的處理方式 15 曲線的 EraseMode EraseMode 對於動畫的呈現相當重要, 此字串可是下列幾種選擇 : normal: 重畫整個畫面 xor: 將舊曲線的點以 xor ( 互斥 ) 的方式還原 background: 將舊曲線的點改成背景顏色 none: 保留舊曲線的點, 不做任何處理 16
曲線的 EraseMode 在上述四種 EraseMode 中, 耗費時間的次序是 normal > xor > background > none xor 和 background 很接近, 但是 background 會抹去其他舊曲線所掃過的其他物件 ( 如圖軸 格線 另一條曲線等 ), 所以較少用到, 所以一般在產生動畫時, 最常用到的 EraseMode 就是 xor 17 曲線的動畫 有了這些概念後, 產生曲線的動畫就很容易了! 其主要步驟有兩點 : 產生一條曲線, 其 EraseMode 為 xor,background, 或 none 在 for-loop 之中, 改變此曲線的 xdata 或 ydata( 或兩者 ) 我們產生一條隨 x 而衰減的正弦曲線, y = sin( x + 並讓 k 隨時間而變大 ( 即改變正弦波的相角 ), 使整條曲線產生舞動的效果 k) e 18 x 5
物件動畫之範例一 我們產生一條衰減的正弦曲線 讓 k 隨時間而便大 ( 即改變正弦波的相角 ), 使整條曲線產生舞動的效果 範例 6-1: movie04.m x = 0:0.1:8*pi; h = plot( x, sin(x).*exp(-x/5), 'EraseMode', 'xor' ); y = sin( x + k) e x 5 axis( [-inf inf -1 1] ); grid on % 設定圖軸的範圍 % 畫出格線 for i = 1:00 y = sin(x+i/).*exp(-x/5); set(h, 'ydata', y); drawnow % 設定新的 y 座標 % 立即作圖 end 19 物件動畫之範例一 1 1 1 0.8 0.8 0.8 0.6 0.6 0.6 0.4 0.4 0.4 0.2 0.2 0.2 0 0 0-0.2-0.2-0.2-0.4-0.4-0.4-0.6-0.6-0.6-0.8-0.8-0.8-1 0 5 10 15 20 25-1 0 5 10 15 20 25-1 0 5 10 15 20 25 1 1 1 0.8 0.8 0.8 0.6 0.6 0.6 0.4 0.4 0.4 0.2 0.2 0.2 0 0 0-0.2-0.2-0.2-0.4-0.4-0.4-0.6-0.6-0.6-0.8-0.8-0.8-1 0 5 10 15 20 25-1 0 5 10 15 20 25-1 0 5 10 15 20 25 20
物件動畫之範例一 在上例中, 我們使用 set 指令, 總共改變曲線的 y 座標 00 次, 並以 xor 的方式抹掉舊曲線 drawnow 的作用是使 MATLAB 立刻處理 set 指令, 若無 drawnow,matlab 會累積 set 指令, 直到 for-loop 結束時再一併處理圖形的變化, 這時就不會看到動畫的效果 21 物件動畫之範例一 如果您將上例的 EraseMode 改成 background, 則會發現曲線會 抹掉 圖形中的格線及代表圖軸的直線 如果您將上例的 EraseMode 改成 none, 則舊的曲線會被保留下來, 產生不同的效果 22
物件動畫之範例 : MATLAB MATLAB 有很多物件動畫之範例 : lorenz: 以 3D 動畫呈現的 Lorenz 混沌方程式 (Chaotic Equation), 好像慧星在運行 truss: 一座橋樑在地震時的震動方式, 共有 12 種喔! travel: 顯示如何以雜亂搜尋 (Random Search) 的方式來解 Traveling Salesperson Problem fitdemo: 顯示如何以 Downhill Simplex Search 來解決非線性曲線擬合 (Nonlinear Curve Fitting) 的問題 23 物件動畫之範例 : Simulink 若您有安裝 Simulink, 可試試下列動態系統模擬加上動畫呈現 : onecart: 傳統的彈簧加上砝碼的動態系統 dblcart1: 一條彈簧加上兩個砝碼的動態系統 simppend: 簡單的單擺系統 dblpend1: 兩截的擺動系統 dblpend2: 更複雜的擺動系統 penddemo: 倒單擺系統 24
物件動畫之範例 : 模糊工具箱 如果您有安裝 Fuzzy Logic Toolbox, 可以試試由張老師開發的各項模擬及動畫展示 : fcmdemo: Fuzzy C-means Clustering juggler: 用板子接皮球 invkine: 兩截機器手臂的 Inverse Kinematics slcp1: 倒單擺, 桿子長度隨時間而變, 您可以控制所欲到達的位置 slcpp1: 雙倒單擺, 其中一個桿子的長度隨時間而變, 您可以控制所欲到達的位置 slbb: 蹺蹺板加上滾球系統, 您可以控制球的最後位置 sltbu: 倒車入庫系統 25 Chap 6: 作業七 主題 : 1. 小圓滾大圓動畫 2. 方程式動畫 1. 小圓滾大圓動畫 : 以物件方式產生動畫, 呈現一個小圓 ( 半徑為 1) 在一個大圓 ( 半徑為 3) 的圓周外部滾動的動畫 2. 方程式動畫 : 以物件的方式產生動畫, 呈現下列方程式 : y = cos 2 (x+k)*exp(-x/5) 讓 k 隨時間而變大, 來顯示此方程式的動畫 26
Chap 6 作業 close all; clear all; theta = 0:0.1:(2*pi+0.1); r1 = 3; x1 = r1*cos(theta); y1 = r1*sin(theta); 建議程式碼 plot(x1, y1), axis image % 大圓 r2 = 1; center = (r1+r2)*[1, 0]; x2 = r2*cos(theta); y2 = r2*sin(theta); h = line(center(1)+x2, center(2)+y2, 'EraseMode', 'xor', 'color', 'r'); % 小圓 axis([-5 5-5 5]); % 設定圖軸的範圍 n = 5; % 轉 5 圈 theta1 = 0:0.005:n*2*pi; for i = 1:length(theta1); center = (r1+r2)*[cos(theta1(i)), sin(theta1(i))]; set(h, 'xdata', center(1)+x2, 'ydata', center(2)+y2); % 設定小圓的 x, y 座標 drawnow % 立即作圖 27 end Chap 6 作業 clear all; close all; 建議程式碼 x = 0:0.1:8*pi; k = 0; h = plot(x, cos(x+k).*cos(x+k).*exp(-x/5), 'EraseMode', 'xor'); axis([-inf inf -1 1]); % 設定圖軸的範圍 grid on % 畫出格線 for k = 1:0.01: y = cos(x+k).*cos(x+k).*exp(-x/5); set(h, 'ydata', y); % 設定新的 y 座標 drawnow % 立即作圖 end 28
Chap 6: 作業七 日期 :10/26, 2010 繳交方式 : 請將上面問題的程式碼, 說明與結果, 複製到 PPT 的檔案中, 檔案名稱命名為 : 您的學號 _hw7.ppt, 例如 :b98921010_hw7.ppt 建議格式如後所示 請用您 e-mail 將您的檔案用附加檔的方式, e-mail 到 991computer@gmail.com, 郵件中, 請包含下列資訊 : 主旨欄 : 計算機程式設計 : 作業七 副本欄 : 您的 e-mail 內容欄 : 姓名 系級 學號 29