MATLAB程序设计入门篇动画制作张智星清大资工系补充内容:方炜台大生机系MATLAB程式設計入門篇:動畫製作•6-1MATLAB动画简介•6-2以电影方式产生动画(a).电影动画之范例一(b).电影动画之范例二(c).电影动画之范例三•6-3以对象方式产生动画(a).曲线的动画(b).曲线的EraseMode(c).对象动画之范例MATLAB程式設計入門篇:動畫製作6-1MATLAB动画简介MATLAB产生动画的方式有两种:电影方式:以影像的方式预存多个画面,再将这些画面快速的呈现在屏幕上,就可以得到动画的效果。此种方式类似于电影的原理,可以产生很缤纷亮丽的动画,但是其缺点为每个画面都必需事先备妥,无法进行及时成像(Real-timeRendering),而且每个画面,以至于整套动画,都必需占用相当大的内存空间。物件方式:在MATLAB的「握把式图形」(HandleGraphics,详见本书第七章)概念下,所有的曲线或曲面均可被视为一个对象,MATLAB可以很快的抹去旧曲线,并产生相似但不同的新曲线,此时就可以看到曲线随时间而变化的效果。使用对象方式(即握把式图形)所产生的动画,可以呈现实时的变化,也不需要太高的内存需求,但其缺点是较难产生太复杂的动画。MATLAB程式設計入門篇:動畫製作6-2以电影方式产生动画以电影方式来产生动画,可由下列两个步骤来达成:使用getframe指令来抓取图形做为电影的画面,每个画面都是以一个行向量的方式,置放于整个代表电影的矩阵。使用movie指令来播放电影,并可指定播放的重复次数及每秒播放的画面数目。MATLAB程式設計入門篇:動畫製作电影动画之范例一在下例中,我们将以不同的角度来显示peaks函数,并将其结果以电影的方式来呈现动画。范例6-1:movie01.mclearM%清除电影资料矩阵Mn=50;%抓取50个画面peaks;fprintf('抓取画面中...\n');fori=1:nview([-37.5+i*360/n,30]);%改变观测角度M(i)=getframe;%抓取画面,并存入电影资料矩阵Mendfprintf('播放电影中...\n');movie(M,3);%播放电影三次MATLAB程式設計入門篇:動畫製作电影动画之范例一最后一个frame的画面MATLAB程式設計入門篇:動畫製作电影动画之范例二将peaks函数画在圆盘上,然后再变换此函数的高度,以动画呈现范例6-2:movie02.mclearM%清除电影资料矩阵Mr=linspace(0,4,30);%圆盘的半径t=linspace(0,2*pi,50);%圆盘的极坐标角度[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));fprintf('抓取画面中...\n');fori=1:nsurf(xx,yy,zz*scale(i));%画图axis([-infinf-infinf-8.58.5]);%固定图轴的范围boxonM(i)=getframe;%抓取画面,并存入电影资料矩阵Mendfprintf('播放电影中...\n');movie(M,5);%播放电影5次MATLAB程式設計入門篇:動畫製作电影动画之范例二最后一个frame的画面MATLAB程式設計入門篇:動畫製作电影动画之范例三改变影像的色盘矩阵,让影像出现「从正片变到负片」的效果范例6-3:movie03.mclearM%清除电影资料矩阵Mloadclown.matimage(X);colormap(map);%画出小丑脸n=30;%抓取30个画面scale=cos(linspace(0,2*pi,n));fprintf('抓取画面中...\n');fori=1:ncolormap(((i-1)*(1-map)+(n-i)*map)/n);%改变色盘矩阵M(i)=getframe;%抓取画面,并存入电影资料矩阵Mendfprintf('播放电影中...\n');movie(M,-5);%播放电影5次(含正向与逆向播放)MATLAB程式設計入門篇:動畫製作电影动画之范例三在上述范例中,正片(如下张投影片图左)的色盘矩阵是map,而1-map则是负片(如下张投影片图右)的色盘矩阵,因此我们在抓影片时,让色盘矩阵进行渐进式的变化,因此呈现的电影就有「从正片变到负片」的效果。另外,movie(M,-5)代表电影将播放5次,但由于第二个参数是负数,所以每次播放会包含一次「正向播放」及一次「逆向播放」。MATLAB程式設計入門篇:動畫製作电影动画之范例三正片色盘矩阵是map负片色盘矩阵是1-mapMATLAB程式設計入門篇:動畫製作电影动画的其他范例MATLAB的demo程序中亦包含了数个与电影方式相关的动画,读者可以在指令窗口输入下列任一指令:xpmovievibesxpmovielogospinxpmoviecrulspinMATLAB程式設計入門篇:動畫製作6-3以对象方式产生动画以电影方式产生动画可以说是「暴力法」,因为此方法占掉了许多内存空间。另一个技巧性较高的方法则是以对象方式产生动画,此种方法不需要大量的内存,而且可以产生「实时」(Real-time)或「交互式」(Interactive)的动画。MATLAB的所有图形组件(曲线、曲面、图轴等)都是对象,您可以控制这些对象的各种性质,此种特性称为「握把式图形」(HandleGraphics),可详见第七章。握把式图形包含的层面很广,但牵涉到动画部份的基本概念并不复杂,以下我们以曲线的动画来说明。MATLAB程式設計入門篇:動畫製作曲线的动画我们可以快速地改变图形对象的性质(如颜色、坐标等),就可以达到动画的效果每一条曲线都有下列三种性质:xdata:此为一向量,代表曲线的x坐标值ydata:此为一向量,代表曲线的y坐标值EraseMode:此为一字符串,代表曲线被抹除的方式,亦即当xdata或ydata被改变时,对于旧曲线的处理方式。MATLAB程式設計入門篇:動畫製作曲线的EraseModeEraseMode对于动画的呈现相当重要,此字符串可是下列几种选择:normal:重画整个画面。xor:将旧曲线的点以xor的方式还原。background:将旧曲线的点改成背景颜色。none:保留旧曲线的点,不做任何处理。在上述四种EraseMode中,耗费时间的次序是normalxorbackgroundnonexor和background很接近,但是background会抹去其他旧曲线所扫过的其他对象(如图轴、网格线、另一条曲线等),所以较少用到,所以一般在产生动画时,最常用到的EraseMode就是xor。MATLAB程式設計入門篇:動畫製作曲线的动画有了这些概念后,产生曲线的动画就很容易了!其主要步骤有两点:产生一条曲线,其EraseMode为xor,background,或none。在for-loop之中,改变此曲线的xdata或ydata(或两者)。我们产生一条随x而衰减的正弦曲线,并让k随时间而便大(即改变正弦波的相角),使整条曲线产生舞动的效果。5)sin(xekxyMATLAB程式設計入門篇:動畫製作对象动画之范例一我们产生一条衰减的正弦曲线让k随时间而便大(即改变正弦波的相角),使整条曲线产生舞动的效果。范例6-1:movie04.mx=0:0.1:8*pi;h=plot(x,sin(x).*exp(-x/5),'EraseMode','xor');axis([-infinf-11]);%设定图轴的范围gridon%画出网格线fori=1:5000y=sin(x+i/50).*exp(-x/5);set(h,'ydata',y);%设定新的y坐标drawnow%立即作图end5)sin(xekxyMATLAB程式設計入門篇:動畫製作对象动画之范例一我们产生一条衰减的正弦曲线让k随时间而便大(即改变正弦波的相角),使整条曲线产生舞动的效果。范例6-1:movie04.mx=0:0.1:8*pi;h=plot(x,sin(x).*exp(-x/5),'EraseMode','xor');axis([-infinf-11]);%设定图轴的范围gridon%画出网格线fori=1:5000y=sin(x+i/50).*exp(-x/5);set(h,'ydata',y);%设定新的y坐标drawnow%立即作图end5)sin(xekxyMATLAB程式設計入門篇:動畫製作对象动画之范例一最后一个frame的画面MATLAB程式設計入門篇:動畫製作对象动画之范例一在上例中,我们使用set指令,总共改变曲线的y坐标5000次,并以xor的方式抹掉旧曲线。drawnow的作用是使MATLAB立刻处理set指令,若无drawnow,MATLAB会累积set指令,直到for-loop结束时再一并处理图形的变化,这时就不会看到动画的效果。如果您将上例的EraseMode改成background,则会发现曲线会“抹掉”图形中的网格线及代表图轴的直线。如果您将上例的EraseMode改成none,则旧的曲线会被保留下来,产生不同的效果。MATLAB程式設計入門篇:動畫製作对象动画之范例:MATLABMATLAB有很多对象动画之范例:lorenz:以3D动画呈现的Lorenz混沌方程式(ChaoticEquation),好像慧星在运行。truss:一座桥梁在地震时的震动方式,共有12种喔!travel:显示如何以杂乱搜寻(RandomSearch)的方式来解TravelingSalespersonProblem.fitdemo:显示如何以DownhillSimplexSearch来解决非线性曲线拟合(NonlinearCurveFitting)的问题。spinner:常见的屏幕保护程序。xphide:试试您的眼力…。MATLAB程式設計入門篇:動畫製作对象动画之范例:Simulink若您有安装Simulink,可试试下列动态系统仿真加上动画呈现:onecart:传统的弹簧加上砝码的动态系统。dblcart1:一条弹簧加上两个砝码的动态系统。simppend:简单的单摆系统。dblpend1:两截的摆动系统。dblpend2:更复杂的摆动系统。penddemo:倒单摆系统。MATLAB程式設計入門篇:動畫製作对象动画之范例:模糊工具箱如果您有安装FuzzyLogicToolbox,可以试试由张老师开发的各项模拟及动画展示:fcmdemo:FuzzyC-meansClustering。juggler:用板子接皮球。invkine:两截机器手臂的InverseKinematics。slcp1:倒单摆,杆子长度随时间而变,您可以控制所欲到达的位置。slcpp1:双倒单摆,其中一个杆子的长度随时间而变,您可以控制所欲到达的位置。slbb:跷跷板加上滚球系统,您可以控制球的最后位置。sltbu:倒车入库系统MATLAB程式設計入門篇:動畫製作以对象方式产生动画,呈现一个小圆(半径为1)在一个大圆(半径为3)的圆周外部滚动的动画。functionmymovie02closealltheta=0:0.1:2*pi;r1=3;x1=r1*cos(theta);y1=r1*sin(theta);plot(x1,y1),axisimage%大圆r2=1;center=(r1+r2)*[1,0];x2=r2*cos(theta);y2=r2*sin(theta);h=line(center(1)+x2,