3

Producing animated gifs from MATLAB Flipbook Mini Hack entries

 7 months ago
source link: https://blogs.mathworks.com/matlab/2024/02/16/producing-animated-gifs-from-matlab-flipbook-mini-hack-entries/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

Producing animated gifs from MATLAB Flipbook Mini Hack entries » The MATLAB Blog

On Valentine's day, the MathWorks linkedIn channel posted this animated gif
dbc1ee461bf1d391edf5ce670d36353132993b22.gif
The obvious question was duly asked "Where's the MATLAB code for this?" Turns out, I was uniquely placed to answer this as it was one of my entries for the MATLAB Flipbook Mini Hack contest that occurred in late 2023. The full credit, however, has to go to Zhaoxu Liu / slandarer who wrote the original entry called Particle Heart 2. My version of the code was a lightly edited 'remix' that simply made the heart rotate more quickly, causing it to do a full revolution for every loop of the gif. This idea of remixing was a key feature of the contest which helped make it a lot of fun. Some of the best entries got remixed a lot!
I was at dinner at the time and wasn't able to post a full reply to the questions on LinkedIn so I just posted the link to the Minihack entry. Here's the code
function drawframe(f)
global theta1 theta2 theta3 heartHdl star1Hdl star2Hdl hpnts sx1 sx2 sy1 sy2
if f==1
% 所需匿名函数
col1Func=@(n) repmat([255,158,196]./255,[n,1])+repmat([-39,-81,-56]./255,[n,1]).*repmat(rand([n,1]),[1,3]);
col2Func=@(n) repmat([118,156,216]./255,[n,1])+repmat([137,99,39].*.1./255,[n,1]).*repmat(rand([n,1]),[1,3]);
szFunc=@(n) rand([n,1]).*15+8;
hold on
% 计算爱心点位置并绘制爱心
n=120;
x=linspace(-3,3,n);
y=linspace(-3,3,n);
z=linspace(-3,3,n);
[X,Y,Z]=ndgrid(x,y,z);
F=((-(X.^2).*(Z.^3)-(9/80).*(Y.^2).*(Z.^3))+((X.^2)+(9/4).*(Y.^2)+(Z.^2)-1).^3);
FV=isosurface(F,0);
hpnts=FV.vertices;
hpnts=(hpnts-repmat(mean(hpnts),[size(hpnts,1),1])).*repmat([.75,.7,.7],[size(hpnts,1),1]);
hpnts=hpnts+rand(size(hpnts)).*.7;
heartHdl=scatter3(hpnts(:,1),hpnts(:,2),hpnts(:,3),'.','SizeData',5,'CData',col1Func(size(hpnts,1)));
% 计算星星位置并绘制星星
sx1=rand([2e3,1]).*120-60;
sy1=rand([2e3,1]).*120-60;
sz1=ones(size(sx1)).*-30;
star1Hdl=scatter3(sx1,sy1,sz1,'.','SizeData',szFunc(length(sx1)),'CData',col2Func(size(sx1,1)),'LineWidth',1);
sx2=rand([2e3,1]).*120-60;
sy2=rand([2e3,1]).*120-60;
sz2=rand([2e3,1]).*120-20;
star2Hdl=scatter3(sx2,sy2,sz2,'.','SizeData',szFunc(length(sx2)),'CData',[1,1,1]);
% 坐标区域修饰
ax=gca;
ax.XLim=[-30,30];
ax.YLim=[-30,30];
ax.ZLim=[-40,30];
ax.Projection='perspective';
% ax.DataAspectRatio=[1,1,1];
view(-42,14);
ax.Color=[0,0,0];
ax.XColor='none';
ax.YColor='none';
ax.ZColor='none';
set(ax,'LooseInset',[0,0,0,0]);
set(ax,'Position',[-1/5,-1/5,1+2/5,1+2/5])
set(gcf,'Color',[0,0,0]);
% text(0,0,20,'slandarer','Color','w','HorizontalAlignment','center')
% 旋转爱心和星星
theta1=0;theta2=0;theta3=0;
theta1=theta1-pi/48;
theta2=theta2-0.003;
theta3=theta3-0.02;
set(heartHdl,'XData',hpnts(:,1).*cos(theta1)-hpnts(:,2).*sin(theta1),...
'YData',hpnts(:,1).*sin(theta1)+hpnts(:,2).*cos(theta1))
set(star1Hdl,'XData',sx1.*cos(theta2)-sy1.*sin(theta2),...
'YData',sx1.*sin(theta2)+sy1.*cos(theta2))
set(star2Hdl,'XData',sx2.*cos(theta3)-sy2.*sin(theta3),...
'YData',sx2.*sin(theta3)+sy2.*cos(theta3))
It's a function that draws a single frame. The software behind the website then called this function in a loop with the frame number going from 1 to 48 and inserted a delay such that the resulting animation would last 2 seconds before starting again. However, if you just had MATLAB then this function only produces a static frame.
drawframe(1);
animatingFlickbook_2.png
How do you use this to produce the animated gif was the follow up question? I reached out to the team who built the Minihack website and asked them how they did it. How can I reproduce the exact same animated gifs using MATLAB and the drawframe() functions found on the website? They sent me the code below
function animateFrames()
animFilename = 'animation.gif'; % Output file name
firstFrame = true;
framesPerSecond = 24;
delayTime = 1/framesPerSecond;
% Create the gif
for frame = 1:48
drawframe(frame);
fig = gcf();
fig.Units = 'pixels';
fig.Position(3:4) = [300,300];
im = getframe(fig);
[A,map] = rgb2ind(im.cdata,256);
if firstFrame
firstFrame = false;
imwrite(A,map,animFilename, LoopCount=Inf, DelayTime=delayTime);
imwrite(A,map,animFilename, WriteMode="append", DelayTime=delayTime);
So, create two m-files, one called animateFrames.m and the other called drawframe.m, run animateFrames()
animateFrames()
and after a few seconds, you'll have animation.gif that contains what you are looking for. At this point, I suggest you take a look at the gallery and find something to animate yourself. These flowers, also from Zhaoxu Liu / slandarer, perhaps?
flowers.gif
lanterns.gif
Even though the competition only lasted 4 weeks, there are over 600 entries for you to play with. Here is a static view of a few more.
animatingFlickbook_5.png
The competition had a few restrictions. For example, all animations had exactly 48 frames that would be turned into a 2 second gif. There were also computational time limits and character limits on the drawframe() function. Now you have the code, you can go crazy and produce animated gifs of whatever complexity you like!

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK