背景介绍:
Sugar 的系列推文演示算法的时候用了 MATLAB 的动画。
最近研究体温计也是要通过数据分析来确定温度补偿算法,数据分析的第一步就是数据动态图形化展示。以前也有不少私信 Sugar 问 MATLAB 图画是怎么做的,其实非常简单。
本篇 Sugar 就把 MATLAB 做动画的方法写出来,喜欢的照做一遍立刻就会。
关键三步
1、图像句柄(可以是 plot、animatedline 等)
3、往图像里加数据(可以是handle.XData()、addpoints())
2、drawnow
本文的核心亮点就是这关键三步,要是没有这个总结那就跟 MATLAB 文档基本没区别了。学东西就是看官方文档,然后自己总结,所谓“把书读薄”就是这个意思。
看不懂总结?没关系,下面 Sugar 精心摘了很多个代码简单、易于理解、重点突出的小例子,照做一遍不但能理解 Sugar 的总结,还能掌握得牢、理解得深。
二维线动画
参考链接:
1、创建动画线条:https://ww2.mathworks.cn/help/matlab/ref/animatedline.html
2、清除动画线条中的点:https://ww2.mathworks.cn/help/matlab/ref/clearpoints.html
【例 1】 代码如下:
theta = linspace(0,2*pi,1000);h = animatedline();axis([0,2*pi,-1,1]) for t = theta addpoints(h,t,sin(t)); drawnow;end
解读:
1、 linespace 函数
用法:linspace(x1,x2,N)
功能:linspace是Matlab中的一个指令,用于产生x1,x2之间的N点行矢量。其中x1、x2、N分别为起始值、中止值、元素个数。若缺省N,默认点数为100。
X=linspace(1,100)# 将产生从1到100步长为1的数组。类似于在命令窗口中输入:X=[1:1:100]
2、下面的【例 4】到【例 8】详解了一类方法的各种效果。
3、动画函数的语法如下图:
4、查询线条中的点
[ ] = getpoints(h);
5、删除线条中的点
clearpoints(h)drawnow
【例 2】 代码如下:
t = linspace(0,2*pi,10000);y = exp(sin(t));h = plot(t,y);for k = 1:0.01:10 y = exp(sin(t.*k)); h.YData = y; drawnowend
【例 3】 代码如下:
a1 = animatedline('Color',[0 .7 .7]);a2 = animatedline('Color',[0 .5 .5]); 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 limitrateend
这个例子运行时看上去速度很快
【例 4】 代码如下:
h = animatedline;axis([0,4*pi,-1,1]) x = linspace(0,4*pi,1000);y = sin(x);for k = 1:length(x) addpoints(h,x(k),y(k)); drawnowend
要加快渲染速度,可在每次遍历循环时向线条中添加多个点或使用 drawnow limitrate。
【例 5】改变线条颜色和线宽
x = [1 2];y = [1 2];h = animatedline(x,y,'Color','r','LineWidth',3);
【例 6】设置最大点数
h = animatedline('MaximumNumPoints',100);axis([0,4*pi,-1,1]) x = linspace(0,4*pi,1000);y = sin(x);for k = 1:length(x) addpoints(h,x(k),y(k)); drawnowend
动画的效果就是指定点数的线条在沿给定规律运动。将动画线条中的点数限制为 100 个。通过循环一次向线条中添加一个点。当线条包含 100 个点时,向线条添加新点会删除最旧的点。
【例 7】批量添加点以快速产生动画
h = animatedline;axis([0,4*pi,-1,1]) numpoints = 100000;x = linspace(0,4*pi,numpoints);y = sin(x);for k = 1:100:numpoints-99 xvec = x(k:k+99); yvec = y(k:k+99); addpoints(h,xvec,yvec) drawnowend
通过循环向动画线条中添加 100,000 个点。由于点的数目很大,因此每次通过循环向线条中添加一个点可能很慢。改为每次通过循环向线条中添加 100 个点以产生更快的动画。
【例 8】使用 tic 和 toc 控制动画速度
h = animatedline;axis([0,4*pi,-1,1])numpoints = 10000;x = linspace(0,4*pi,numpoints);y = sin(x);a = tic; % start timerfor k = 1:numpoints addpoints(h,x(k),y(k)) b = toc(a); % check timer if b > (1/30) drawnow % update screen every 1/30 seconds a = tic; % reset timer after updating endenddrawnow % draw final frame
在屏幕上绘制更新之前先运行动画循环的多个迭代,以此来控制动画速度。在 drawnow 太慢或 drawnow limitrate 太快时可以使用此技术。
例如,每 1/30 秒更新一次屏幕。使用 tic 和 toc 命令可跟踪屏幕更新间经过的时间。
二维面动画
【例 1】 代码如下:
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 ont = area(xt,yt); % initial flat trianglehold offfor 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 limitrate % display updatesend
三维线动画
【例 1】 代码如下
load wind[100,20:2:50,5); ] = meshgrid( verts = stream3(x,y,z,u,v,w,sx,sy,sz);sl = streamline(verts); view(-10.5,18)daspect([2 2 0.125])axis tight;set(gca,'BoxStyle','full','Box','on') iverts = interpstreamspeed(x,y,z,u,v,w,verts,0.01);set(gca,'SortMethod','childorder');streamparticles(iverts,15,... 'Animate',10,... 'ParticleAlignment','on',... 'MarkerEdgeColor','none',... 'MarkerFaceColor','red',... 'Marker','o');
三维面动画
【例 1】 代码如下:
theta = 0:pi/40:pi; % polar anglephi = 0:pi/20:2*pi; % azimuth angle [phi,theta] = meshgrid(phi,theta); % define the grid degree = 6;order = 1;amplitude = 0.5;radius = 5; Ymn = legendre(degree,cos(theta(:,1)));Ymn = Ymn(order+1,:)';yy = Ymn; for kk = 2: size(theta,1) yy = [yy Ymn];end yy = yy.*cos(order*phi); order = max(max(abs(yy)));rho = radius + amplitude*yy/order; r = rho.*sin(theta); % convert to Cartesian coordinatesx = r.*cos(phi);y = r.*sin(phi);z = rho.*cos(theta); figures = surf(x,y,z); light % add a lightlighting gouraud % preferred lighting for a curved surfaceaxis equal off % set axis equal and remove axisview(40,30) % set viewpointcamzoom(1.5) % zoom into scene scale = [linspace(0,1,20) linspace(1,-1,40)]; % surface scaling (0 to 1 to -1) for ii = 1:length(scale) rho = radius + scale(ii)*amplitude*yy/order; r = rho.*sin(theta); x = r.*cos(phi); y = r.*sin(phi); z = rho.*cos(theta); s.XData = x; % replace surface x values s.YData = y; % replace surface y values s.ZData = z; % replace surface z values pause(0.05) % pause to control animation speedend
关注作者
欢迎扫码关注我的公众号MultiMCU EDU。
提示:在公众号“关于我”页面可加作者微信好友。
喜欢本文求点赞,有打赏我会更有动力。
本文源自微信公众号:MultiMCU EDU,不代表用户或本站观点,如有侵权,请联系nick.zong@aspencore.com 删除!