您可以使用三种基本方法在 MATLAB 中创建动画:
1.更新图形对象的属性并在屏幕上显示更新。这一技术对于在图形大部分保持不变的情况下创建动画非常有用。例如,重复设置 XData
和
YData
属性以在图形中移动对象。
2.将变换应用于对象。当您想要同时对一组对象的位置和方向进行操作时,此技术非常有用。将一些对象归组为某一变换对象的子级。使用
hgtransform
创建变换对象。设置变换对象的
Matrix 属性,调整其所有子级的位置。
3.创建一个影片。如果您有一个复杂的动画无法实时快速绘制,或想要存储动画以再次播放时,影片就非常有用。使用
getframe
和
movie
函数创建一个影片。
在某些情况下,直到代码完成后 MATLAB 才会更新屏幕。使用 drawnow 命令,可以在动画过程中显示整个屏幕的更新。
要优化性能,可考虑以下技术:
• 使用 animatedline
函数创建流化数据的线条动画。
• 更新现有对象的属性,不创建新的图形对象。
• 设置坐标轴范围(XLim
、
YLim
、
ZLim
)或将与之关联的模式属性改为手动模式(
XLimMode、 YLimMode
、
ZLimMode),以避免 MATLAB 在每次屏幕更新时重新计算值。当您设置坐标轴范围时,与之关联的模式属性会更改成手动模式。
• 尽量避免在循环中创建图例或其他注释。可以在循环之后添加注释。
1.在曲线中移动标记
此示例演示如何通过更新标记属性以沿着线条跟踪标记。绘制一个正弦波并在线条开始处绘制红色标记。将坐标轴范围模式设置为手动,以避免在动画循环中重新计算范围。通过在循环中更新
XData 和
YData 属性,实现沿着线条移动标记。使用
drawnow 或
drawnow
limitrate 命令在屏幕上显示更新。
drawnow limitrate 的速度最快,但它可能不会在屏幕上绘制每一帧。使用圆点表示法设置属性。
x = linspace(0,10,1000);
y = sin(x);
plot(x,y)
hold on
p = plot(x(1),y(1),'o','MarkerFaceColor','red');
hold off
axis manual
for k = 2:length(x)
p.XData = x(k);
p.YData = y(k);
drawnow
end
动画演示标记沿着线条移动:


2.沿着线条移动一组对象
此示例演示如何使用变换沿着线条移动一组对象。
绘制一条正弦波,将坐标轴范围模式设置为手动,以避免在动画循环中重新计算范围。创建一个变换对象并将父级设置为当前坐标区。在线条初始处绘制标记和文本注释。使用
num2str 函数将该点处的 y 值转换为文本。通过将两个对象的父级设置为变换对象,将两个对象归为一组。
x = linspace(-6,6,1000);
y = sin(x);
plot(x,y)
axis manual
ax = gca;
h = hgtransform('Parent',ax);
hold on
plot(x(1),y(1),'o','Parent',h);
hold off
t = text(x(1),y(1),num2str(y(1)),'Parent',h,...
'VerticalAlignment','top','FontSize',14);

通过更新变换对象的 Matrix 属性,将标记和文本沿线条移动到每个后续点。使用线条中后接点和第一个点的 x 和 y 值确定变换矩阵。更新文本以匹配随着线条移动时的 y 值。使用
drawnow 显示每次迭代后的屏幕更新。
for k = 2:length(x)
m = makehgtform('translate',x(k)-x(1),y(k)-y(1),0);
h.Matrix = m;
t.String = num2str(y(k));
drawnow
end
动画显示标记和文本沿着线条一起移动。
如果有很多数据,您可以使用 drawnow limitrate
代替
drawnow 以实现更快的动画。但是,drawnow limitrate
可能不会在屏幕上绘制每个更新。
3.对图形对象进行动画处理
此示例演示如何通过更新三角形的数据属性实现三角形沿着圆形内部循环的动画效果。绘制圆形并设置坐标轴范围,使数据单位在两个方向上保持一致。
theta = linspace(-pi,pi);
xc = cos(theta);
yc = -sin(theta);
plot(xc,yc);
axis equal
使用 area 函数绘制一个平坦三角形。然后使用圆形的 (x,y) 坐标改变三角形其中一个顶点的值。改变循环中的值,创建一个动画。使用
drawnow
或
drawnow limitrate 命令在每次迭代后显示更新。drawnow limitrate
的速度最快,但它可能不会在屏幕上绘制每一帧。
theta = linspace(-pi,pi);
xc = cos(theta);
yc = -sin(theta);
plot(xc,yc);
axis equal
xt = [-1 0 1 -1];
yt = [0 0 0 0];
hold on
t = area(xt,yt); % initial flat triangle
hold off
for j = 1:length(theta)-10
xt(2) = xc(j); % determine new vertex value
yt(2) = yc(j);
t.XData = xt; % update data properties
t.YData = yt;
drawnow % display updates
end
4.线条动画
此示例演示如何创建由两条不断变长的线条组成的动画。animatedline 函数帮助您优化线条动画。它可以向线条添加新的点而不用重新定义现有点。
4.1 创建线条并添加点
创建两条不同颜色的动画线条。然后在循环中向线条添加点。在循环之前设置坐标轴范围,从而避免每次循环时重新计算范围。使用
drawnow
或
drawnow limitrate 命令在添加新点之后在屏幕上显示更新。
a1 = animatedline('Color',[0 .7 .7]);
a2 = animatedline('Color',[0 .5 .5]);
axis([0 20 -1 1])
x = linspace(0,20,10000);
for k = 1:length(x)
% first line
xk = x(k);
ysin = sin(xk);
addpoints(a1,xk,ysin);
% second line
ycos = cos(xk);
addpoints(a2,xk,ycos);
% update screen
drawnow limitrate
end
动画显示两个线条随着数据增加不断变长。
4.2 查询线条上的点
查询第一个动画线条上的点。
[x,y] = getpoints(a1);
x 和
y
是包含定义正弦波的值的向量。