参考文献:基于Matlab的计算机图形与动画技术于万波编著清华大学出版社,2007一、动画制作方法(一)时间函数可以使用Timer函数创建计时器对象,如:Matlab提供了许多与动画制作相关的函数,能够比较容易完成动画的制作。1.Timer函数mytimer=timer('TimerFcn','fPatch','StartDelay',6);start(mytimer)关键词当前目录中的程序名称,其程序见下一页。程序运行后,6秒钟后才执行程序fPatch.m。用start()函数激活计数器对象,6秒钟后才执行程序fPatch.m。程序:fpatch.m功能:使用patch函数绘制正方体网格图与表面图。vert=[111;121;221;211;112;122;222;212];fac=[1234;2673;4378;1584;1265;5678];subplot(1,3,1)patch('faces',fac,'vertices',vert,'FaceColor','w');view(3);subplot(1,3,2)patch('faces',fac,'vertices',vert,'FaceVertexCData',hsv(6),'FaceColor','flat');view(3);subplot(1,3,3)patch('faces',fac,'vertices',vert,'FaceVertexCData',hsv(8),'FaceColor','interp');view(3);正方体网格图各面着色正方体插值着色正方体该计时器对象执行如下操作:一个计时器中可以同时对多个M文件进行不同的定时操作。如:•当使用start函数启动计时器时执行'file2';Mtimer=timer('TimerFcn','file1','StartFcn','file2','StopFcn','file3','ErrorFcn','file4')•出错时执行'file4'。•当使用stop函数终止计时器时执行'file3';•将'file1'作为基本计时器代码执行;使用clock函数可以返回当前时间。2.当前日期与时间clockans=1.0e+0032.00600.00900.01900.0200.03100.0384当前机器时间是2006年9月19日20点31分38.4秒。使用now函数将返回当天的日期值。这个时间的单位是天,转换成普通日期是2008年8月21日19点30分53秒左右(误差小于1分钟)。formatlong;nowans=7.336418131145024e+005使用datestr()函数可以将now函数返回的日期值转换成日期字符串。使用date函数可以返回dd-mmm-yy格式的当天日期。dateans=21-Aug-2008使用datenum()函数可以将日期字符串变成日期值datenum(2008,8,21)ans=733641datestr(7.336418131145024e+005)ans=21-Aug-200819:30:53函数cputime计算自当前Matlab程序启动之后到运行结束所占用的CPU时间(单位是秒)。3.计时函数t0=cputime;fpatch;cputime-t0ans=0.0156程序fpatch.m的运行时间是0.0156秒。函数etime计算两个时间向量的间隔。t1=clock;fpatch;etime(clock,t1)ans=0.0150程序fpatch.m的运行时间是0.0150秒。之所以比前面语句的计算时间少,是由于该程序已从硬盘装入等原因计算运行时间的函数还有tic函数与toc函数,前者启动一个秒表,表示计时开始;后者则停止这个秒表,并且计算运行时间。tic;plot(rand(50,5));tocElapsedtimeis0.147644seconds.pause()函数是延迟等待函数,例如,程序中如果出现pause(5),那么在执行到这句话的时候,停留5秒,然后继续。4.pause函数fori=-2*pi:0.5:2*piR=[cos(i)sin(i)0;-sin(i)cos(i)0;001];vert=[111;121;221;211;112;122;222;212];vert=vert*R;fac=[1234;2673;4378;1584;1265;5678];pause(0.1)patch('faces',fac,'vertices',vert,'FaceVertexCData',hsv(8),'FaceColor','interp');view(3)end例使用pause函数制作动画。程序是先绘制一个长方体,然后隔0.1秒又绘制出另外一个长方体,新长方体的顶点坐标经过了变换,此变换是乘以矩阵R完成的,该矩阵是绕Z轴旋转矩阵。如此下去,绘制出下一页所示的图形,从而完成了此动画。如果没有pause(0.1),那么就直接绘制出上图,没有了动画效果。如果把R=[cos(i)sin(i)0;-sin(i)cos(i)0;001];变换成R=[cos(i)0sin(i);010;-sin(i)0cos(i)];那么就是绕Y轴旋转。(二)相机与视点相机与视点的概念与动画制作密切相关。1.函数camdolly()surf(peaks)fori=0:0.05:0.5camdolly(i,0,0)pause(0.2)end表示左右移动i个单位,i为正则向左,为负则向右。camdolly函数的第3个参数表示沿视轴移动。用来移动相机位置和目标位置camdolly(0,i,0)上下移动i个单位camdolly(0,i,0,'fixtarget')只移动相机,物体不移动2.函数camorbit()与camroll()surf(peaks)axisofffori=1:36camorbit(10,0,'data',[010])pause(0.2)end函数camorbit(d1,d2)根据d1与d2的大小(单位是度)绕相机目标点旋转相机,d1表示水平旋转角度,d2表示垂直旋转角度。函数camroll操纵相机绕视轴旋转a)camroll(d)按照d指定的大小绕相机视轴旋转相机,视轴由经过相机位置和相机目标点的直线确定。b)camroll(h,d)操作由第一个句柄参数h确定的坐标系。3.函数campan()surf(peaks)axisvis3dfori=1:720campan(2,0)pause(0.01)end函数campan(dt,dp)按照dt和dp的大小绕相机旋转目标点,dt是水平旋转角度,dp是垂直旋转角度。函数campan还可以添加一个或两个参数campan(dt,dp,'s1','s2')该程序绕相机位置水平旋转了720×2=1440度,即4圈,转完后又回到原先位置,一共停留时间720×0.01=7.2秒。参数s1用来确定旋转中心,参数s2用来确定旋转轴。该函数还可以在第一个参数位置上加入坐标系句柄,决定操作哪一个坐标系,默认是操作当前坐标系。4.函数campos()surf(peaks)axisvis3doffforx=-200:10:200campos([x,0,0])drawnowendcampos该程序使相机沿x轴方向运动。axisvis3doff是取消了三维视觉功能,取消三维视觉功能后不论是campos([x,0,0]),还是campos([0,y,0]),或是campos([x,y,z])效果都是垂直屏幕表面运动,可以更清晰的观察运动的情况。该函数设置或查询相机的位置,其调用格式如下:返回相机在当前坐标系中的位置campos([x,y,z])将相机位置设置为当前坐标系中(x,y,z)处为了验证campos函数不带参数时的功能,设计如下程序:a1=campossurf(peaks)a2=camposaxisvis3doffa3=camposforx=-200:10:200campos([x,0,0])drawnowenda4=camposa1=0.50000.50009.1603a2=-203.2855-327.009086.6025a3=-194.1541-317.728683.9027a4=20000该程序中设置了4个campos,返回了相机的4个位置,分别是:其中a1的值是相机默认位置,a4是程序运行完成后的相机位置。5.函数camtarget()surf(peaks)fori=1:100camtarget([i,0,0])pause(0.01)endcamtarget该程序使相机目标点(物体)沿x轴移动。该函数设置或查询相机目标点的位置,调用格式为:返回相机目标点在当前坐标系中的位置camtarget([x,y,z])将相机目标点位置设置为当前坐标系中(x,y,z)处改为camtarget([0,i,0])沿y轴移动改为camtarget([0,0,i])沿z轴移动6.函数camva()与camzoom()uicontrol('Style','pushbutton','String','In',...'Position',[20206020],'Callback','ifcamva=1;return;else;camva(camva-1);end');uicontrol('Style','pushbutton','String','Out',...'Position',[100206020],'Callback','ifcamva=179;return;else;camva(camva+1);end');camva函数camva()的调用格式是:返回当前坐标系设置的相机视角camva(a)将当前坐标系的相机视角设置为a,单位是度camzoom(f)函数camzoom()的调用格式是:根据f的值对场景进行缩放。下面程序制作了两个按钮用来控制视角的改变。返回相机视角设置相机新的视角7.函数view()view(az,el)和view([az,el])该函数指定视点方向,其调用格式为:设置三维图的视角。方位角az为从y轴的负轴开始绕z轴水平旋转的角度。正值表示视点逆时针旋转。el为仰角。az与el的单位为度。view(2)设置为默认二维视图,az=0,el=90view(3)设置为默认三维视图,az=-37.5,el=30视角函数[X,Y]=meshgrid(-10:0.5:10);Z=X.^2/36-Y.^2/25+sin(X+Y)*2;x=X(1,:);y=Y(:,1);i=find(y0.1&y3.2);j=find(x-3.6&x3.5);Z(i,j)=nan;subplot(2,2,1);surf(X,Y,Z);xlabel('x'),ylabel('y'),zlabel('z');subplot(2,2,2);surf(X,Y,Z);xlabel('x'),ylabel('y'),zlabel('z');view(-30,60);subplot(2,2,3);surf(X,Y,Z);xlabel('x'),ylabel('y'),zlabel('z');view(2);subplot(2,2,4);surf(X,Y,Z);xlabel('x'),ylabel('y'),zlabel('z');view(30,-60);例使用函数view()从不同角度观察图形。上述程序运行后结果如下图所示,4个图形分别是不同视角下显示的同一个曲面。1.程序动画从计算机图形学上看,动画就是绘制的图形发生变化。这个变化不能太快,也不能太慢,要被人的视觉接受。在程序执行时,能够使图形变化达到视觉要求。例程序动画制作。下面程序就完成了一个动画。[X,Y]=meshgrid(-10:1:10);Z=X.^2/36-Y.^2/25;h=mesh(Z)fori=1:10:360rotate