用Matlab制作莫尔条纹光栅动画
这篇文章介绍了一种利用MATLAB制作莫尔条纹(莫尔条纹是一种基于光学现象的视觉艺术)动画的方法。其核心原理是通过将动态图像分解为静态碎片,并利用光栅遮挡原理将其重新拼接成动态效果。文章详细描述了以下步骤:
原理:基于心理学中的连续性原则与闭合原则,在动态图像中利用破碎的信息构建整体视觉感受。
预期动画准备:设置 animation周期 T=6,并通过循环绘制齿轮图形并保存结果为GIF格式。
底片绘制:通过逐帧打印并拼接图像生成底片矩阵文件(cdata_N),并展示最终效果。
光栅动画:加载生成的底片文件并在MATLAB中叠加透明度后显示动态效果。
文章还提供完整代码示例和结果展示图块供参考和学习。(约150字)
利用matlab制作光栅动画(莫尔条纹动画)
- 1原理
- 2 预期动画准备
- 3 底片绘制
- 4 光栅动画
光栅动画是一种通过透明光栅快速在底片上移动的方式,从而呈现底片仿佛在运动的效果.这种动画方法无需依赖电子媒体或其他GIF图像,仅需准备一个预先准备好的底片,并印有透明塑料片上的光栅图案.即可体验到动态图像的效果(此外电子版的PPT同样适用)。
本文旨在探讨光栅动画的生成原理,并借助该原理通过matlab编程实现光栅动画。
1原理
其基本原理涉及视觉心理学领域中的知觉连续性和闭合性规律。这些原理使观众能够在大脑中重建不完整或断裂的信息片段。例如,在下图中可以看到这一现象。

基于破碎的信息,在加入光栅遮挡后能够自然地构思出这一对齿轮系统。
随后,在计算机图形学中,光栅动画的其本质是通过将原有信息逐步拼接成不同的画面片段,并根据系统控制面板的变化来动态地呈现这些片段。当系统切换至不同光栅扫描线位置时,在每一处都会展示特定的画面细节。通过收集这些按顺序变化的画面片段并进行适当处理后,则能够最终形成完整的影像底片。
通常情况下,一般光栅动画具有单一色彩(单一色彩便于视觉解析)。这一特点源于较短的动画周期(更小的光栅间距有助于视觉解析)。其呈现方式简洁明了,并主要采用粗线绘制或大片区域填充(遵循闭合原则)。
2 预期动画准备
在这里仍然采用第一节中的双齿轮动画进行演示,并重点展示预期的动画效果。在设置运动参数时,默认将运动周期设定为T=6(建议避免过大设置),因为如果设置过小,则难以获得理想的效果。
clear
close all
figure('Color','white')
N=17;
T=6;
for k=1:T
clf
dt=2*pi/N/T*k;
%第一个齿轮
hold on
for j=1:N
theta=2*pi/N*j;
R=1.1;
plot([-1,-1+R*cos(theta+dt)],[0,R*sin(theta+dt)],'k','linewidth',5)
end
rectangle('Position',[-1.9,-0.9,1.8,1.8],'Curvature',1,'LineWidth',8)
hold off
%第二个齿轮
hold on
for j=1:N
theta=2*pi/N*j;
R=1.1;
dth=2*pi/N/2;
plot([1,1-R*cos(theta+dth+dt)],[0,R*sin(theta+dth+dt)],'k','linewidth',5)
end
rectangle('Position',[0.1,-0.9,1.8,1.8],'Curvature',1,'LineWidth',8)
hold off
xlim([-3,3])
ylim([-2,2])
axis off
axis equal
pause(0.2)
%绘制动图
cdata = print('-RGBImage','-r100'); %保存Figure上的图像
frame.cdata=cdata;
frame.colormap=[];
imind=frame2im(frame);
[imind,cm]=rgb2ind(imind,2);
if k==1
imwrite(imind,cm,'test.gif','gif', 'Loopcount',inf,'DelayTime',0.2);
else
imwrite(imind,cm,'test.gif','gif','WriteMode','append','DelayTime',0.2);
end
end
效果图如下:

3 底片绘制
底片的绘制与其相关参数——动画周期和光栅宽度——密切相关。在之前的参数配置中, 我们将动画周期设定了6个单位, 因此整个底片绘制过程经历了6次独立的画面更新步骤。关于光栅宽度的具体设定, 我们将其赋值为了1像素宽, 也就是说每个相邻缝隙之间的距离都保持一致。
代码如下:
%绘制底片
close all
figure('Color','white')
N=17;
T=6;
for k=1:T
clf
dt=2*pi/N/T*k;
%第一个齿轮
hold on
for j=1:N
theta=2*pi/N*j;
R=1.1;
plot([-1,-1+R*cos(theta+dt)],[0,R*sin(theta+dt)],'k','linewidth',5)
end
rectangle('Position',[-1.9,-0.9,1.8,1.8],'Curvature',1,'LineWidth',8)
hold off
%第二个齿轮
hold on
for j=1:N
theta=2*pi/N*j;
R=1.1;
dth=2*pi/N/2;
plot([1,1-R*cos(theta+dth+dt)],[0,R*sin(theta+dth+dt)],'k','linewidth',5)
end
rectangle('Position',[0.1,-0.9,1.8,1.8],'Curvature',1,'LineWidth',8)
hold off
xlim([-3,3])
ylim([-2,2])
axis off
axis equal
pause(0.2)
%绘制底片
cdata = print('-RGBImage','-r100');
Size_cdata=size(cdata);
if k==1
cdata_N=cdata;
else
%每次绘制1个像素,间隔为1*T
cdata_N(:,k:T:Size_cdata(2),:)=cdata(:,k:T:Size_cdata(2),:);
end
end
clf
imshow(cdata_N)%展示底片
save('cdata_N.mat','cdata_N')%保存,待会要用
底片绘制之后的结果如下:

4 光栅动画
随后运用这张光栅图像(在上一节中以. mat 格式存储),即可生成光栅动画图像文件。
基于之前的底片基础之上, 我会生成一个具有透明效果的PNG格式光栅, 然后将其存储在PPT文件中. 添加动态播放效果后即可使用. 当然, 在具备条件的情况下, 自行生成光栅也是一种可行的选择.
clear
clc
load('cdata_N.mat')
cdata_N=double(cdata_N);
cdata_Z=255+zeros(size(cdata_N));
%绘制光栅
cdata_Z(119:319,120:480,:)=0;
cdata_Z(119:319,120:T:480,:)=255;
imwrite(cdata_Z,'GuangShan.png','Alpha',cdata_Z(:,:,1)/255); %保存透明图像
生成的图片如下:

在matlab里也可以演示其最终效果:
%绘制变形图和光栅叠加的动图
clear
close all
figure('Color','white')
N=17;
T=6;
%处理
load('cdata_N.mat')
cdata_N=double(cdata_N);
Size_cdata=size(cdata_N);
cdata_N=[cdata_N,255*ones(Size_cdata(1),00,Size_cdata(3))];
%生成size
Size_cdata=size(cdata_N);
k=[1:120,119:-1:2];
for j=1:length(k)
t=k(j);
cdata_Z=255*ones(Size_cdata);
%绘制光栅
cdata_Z(119:319,250-t:550-t,:)=0;
cdata_Z(119:319,250-t:T:550-t,:)=255;
%imshow(cdata_Z)
%叠加
cdata_Combine =imlincomb(1,cdata_N,1,cdata_Z,-255);
imshow(cdata_Combine)
pause(0.1)
end
最终效果如下:

