1. 程式人生 > >MATLAB GUI中利用定時器製作動畫

MATLAB GUI中利用定時器製作動畫

MATLAB中提供了一些動態顯示圖形的例子,例如vibes、truss等,但他們的程式結構都和由GUIDE產生的M檔案的結構不同。truss中用 while迴圈來更新圖形視窗,pause函式來控制更新的速度。這樣的結構是不適合放在某一個子函式中來執行的,否則程式在執行該子函式時無法響應使用者 的其它操作,只能一開始就設定終止條件,等待動畫的自然結束。

MATLAB中的定時器timer可以定時觸發,週期性地執行指定的函式,我們可以據此來實現繪圖的自動更新,而不會影響整個GUI對使用者其它操作的響應。
比如我們要讓一個曲面隨時間週期性地變形,類似vibes中的情形,按下“開始”按鈕後,曲面開始週期振動,同時我們可以調整振幅大小、週期的長短。所不同的是我們一切都在子函式中完成。

在GUIDE中建立介面元素後,在“開始”按鈕的callback中建立一個定時器timer物件object
handles.timer = timer('Period',0.05,'ExecutionMode','FixedRate',
... 'TimerFcn',{@PlotUpdate,handles});
Period 是觸發的週期,這裡設定為0.05s,ExecutionMode是執行的方式,可以有三種選擇,對於不需要精確控制時序的動畫的影響不大, TimerFcn指定觸發時所執行函式的控制代碼,在這裡我們建立一個函式PlotUpdate來執行繪圖命令,handles作為引數傳遞到 PlotUpdate中去。

注意PlotUpdate的定義:
function PlotUpdate(obj,events,handles)
前 兩個引數是必不可少的,最後的handles才是使用者傳遞的資料。在這個函式中你基本上可以無視前兩個引數,按照曲面的運動趨勢產生新的頂點座標,然後用 set命令將新的座標賦給曲面(面片patch)物件的Vertices屬性。drawnow更新就可以了。你可以用曲面物件的UserData屬性存放 當前振動的幅值相位等引數。

然後在“停止”按鈕的callback中stop(handles.timer)停止定時器,就可以停止自動繪圖了。
在“增大振幅”按鈕的callback中對振幅引數作修改。
排除了一些小問題後,你的曲面終於可以動起來了,按“增大振幅”等也沒有影響圖形的運動,真的是“一點影響都沒有”啊!

問題出在哪裡呢?原來,當定時器第一次觸發時,使用者指定的引數被傳遞到響應函式中執行,以後每一次觸發,都是使用的這同一組引數,並不會隨著程式的執行而更新。好了,現在可以在
“增大振幅”中重新賦一次引數
set(handles.timer,'TimerFcn',{@PlotUpdate,handles});
怎麼樣,達到你的要求了吧!在MATLAB Help的index中輸入timer,可以察看詳細的說明。