MATLAB | 官方举办的动图绘制大赛 | 第三周赛情回顾

MATHWORKS官方举办的迷你黑客大赛第三期(MATLAB Flipbook Mini Hack)的最新进展!!

很荣幸前三周都成为了阶段性获奖者~:

  • https://ww2.mathworks.cn/matlabcentral/communitycontests/contests/6/entries/13382

  • https://ww2.mathworks.cn/matlabcentral/communitycontests/contests/6/entries/13917

  • https://ww2.mathworks.cn/matlabcentral/communitycontests/contests/6/entries/14937

下面正式开始!

本次比赛要求提交名为drawframe(f)的函数代码,生成长达2s,48帧的动态图,动图生成是依靠如下代码来做到的:

function contestAnimator()
    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);
        else
            imwrite(A,map,animFilename, WriteMode="append", DelayTime=delayTime);
        end
    end
end

闲话少叙,一起看作品!!


作品概览

我之前写的玫瑰改成的动图版:

Zhaoxu Liu / slandarer / rose bouquet

https://ww2.mathworks.cn/matlabcentral/communitycontests/contests/6/entries/14747

function drawframe(g)
if g==1
s=@sin;c=@cos;f=@surface;e=@size;
[xr,tr]=meshgrid((0:24)./24,(0:0.5:575)./575.*20.*pi+4*pi);
p=(pi/2)*exp(-tr./(8*pi));
cr=s(15*tr)/150;
u=1-(1-mod(3.6*tr,2*pi)./pi).^4./2+cr;
yr=2*(xr.^2-xr).^2.*s(p);
rr=u.*(xr.*s(p)+yr.*c(p));
hr=u.*(xr.*c(p)-yr.*s(p));
rb=0:.01:1;
tb=linspace(0,2,151);
w=rb'*((abs((1-mod(tb*5,2))))/2+.3);
xb=w.*c(tb*pi);
yb=w.*s(tb*pi);
zb=@(a)(-c(w*a*pi)+1).^.2;
Zb=zb(1.2);
cL=[.33 .33 .69;.68 .42 .63;.78 .42 .57;.96 .73 .44];
cMr=sH(hr,cL);
cMb=sH(Zb,cL.*.4+.6);
yz=72*pi/180;
rx1=pi/8;
rx2=pi/9;
Rz2=[c(yz),-s(yz),0;s(yz),c(yz),0;0,0,1];
Rz=@(n)[c(yz/n),-s(yz/n),0;s(yz/n),c(yz/n),0;0,0,1];
Rx=@(n)[1,0,0;0,c(n),-s(n);0,s(n),c(n)];
Rz1=Rz(2);Rz3=Rz(3);
Rx1=Rx(rx1);Rx2=Rx(rx2);
hold on
cp={'EdgeAlpha',0.05,'EdgeColor','none','FaceColor','interp','CData',cMr};
f(rr.*c(tr),rr.*s(tr),hr+0.35,cp{:})
[U,V,W]=rT(rr.*c(tr),rr.*s(tr),hr+0.35,Rx1);
V=V-.4;
f(U,V,W-.1,cp{:})
dS(U,V,W-.1)
for k=1:4
[U,V,W]=rT(U,V,W,Rz2);
f(U,V,W-.1,cp{:})
dS(U,V,W-.1)
end
[u1,v1,w1]=rT(xb./2.5,yb./2.5,Zb./2.5+.32,Rx2);
v1=v1-1.35;
[u2,v2,w2]=rT(u1,v1,w1,Rz1);
[u3,v3,w3]=rT(u1,v1,w1,Rz3);
[u4,v4,w4]=rT(u3,v3,w3,Rz3);
U={u1,u2,u3,u4};
V={v1,v2,v3,v4};
W={w1,w2,w3,w4};
for k=1:5
for b=1:4
[ut,vt,wt]=rT(U{b},V{b},W{b},Rz2);
U{b}=ut;V{b}=vt;W{b}=wt;
f(U{b},V{b},W{b},cp{3:7},cMb)
dS(U{b},V{b},W{b})
end
end
a=gca;axis off
a.Position=[0,0,1,1]+[-1,-1,2,2]./6;
axis equal
end
view(g*2.1,35);
function c=sH(H,cList)
X=(H-min(min(H)))./(max(max(H))-min(min(H)));
x=(0:e(cList,1)-1)./(e(cList,1)-1);
u=cList(:,1);v=cList(:,2);w=cList(:,3);
q=@interp1;
c(:,:,1)=q(x,u,X);
c(:,:,2)=q(x,v,X);
c(:,:,3)=q(x,w,X);
end
function [U,V,W]=rT(X,Y,Z,R)
U=X.*0;V=Y.*0;W=Z.*0;
for i=1:e(X,1)*e(X,2)
v=[X(i);Y(i);Z(i)];
n=R*v;U(i)=n(1);V(i)=n(2);W(i)=n(3);
end
end
function dS(X,Y,Z)
[m,n]=find(Z==min(min(Z)));
m=m(1);n=n(1);
x1=X(m,n);y1=Y(m,n);z1=Z(m,n)+.03;
x=[x1,0,(x1.*c(pi/3)-y1.*s(pi/3))./3].';
y=[y1,0,(y1.*c(pi/3)+x1.*s(pi/3))./3].';
z=[z1,-.7,-1.5].';
p=[x,y,z];
N=50;
t=(1:N)/N;
q=e(p,1)-1;
F=@factorial;
c1=F(q)./F(0:q)./F(q:-1:0);
c2=((t).^((0:q)')).*((1-t).^((q:-1:0)'));
p=(p'*(c1'.*c2))';
plot3(p(:,1),p(:,2),p(:,3),'Color',[88,130,126]./255)
end
end

由我代码remix的一个作品~

ME / Moving points on circles - color changes with y coordinate

https://ww2.mathworks.cn/matlabcentral/communitycontests/contests/6/entries/14732

function drawframe(f)
alpha0=pi/6;
K=18;
R=sqrt(3)/2;
[XMesh,YMesh]=meshgrid(1:K);
tList=linspace(0,2*pi,100);
tCos=[cos(tList).*R,nan]';
tSin=[sin(tList).*R,nan]';
tX=tCos+XMesh(:)';tX=tX(:);
tY=tSin+YMesh(:)';tY=tY(:);
figure('Units','normalized','Position',[.3,.2,.5,.65]);
plot(tX,tY,'Color',[0.2,0.2,0.2,.8],'LineWidth',1)
% -----------------------------
ax=gca;hold on;
ax.XLim=[0,K+1];
ax.YLim=[0,K+1];
ax.XColor='none';
ax.YColor='none';
ax.PlotBoxAspectRatio=[1,1,1];
ax.Position=[0,0,1,1];
% -----------------------------
dTheta=2*pi/48;
alpha=flipud(XMesh+YMesh);
thetaMesh=alpha(:).*alpha0;
% -----------------------------
for i=1:f
thetaMesh=thetaMesh+dTheta;
pntHdl.XData=cos(thetaMesh).*R+XMesh(:);
pntHdl.YData=sin(thetaMesh).*R+YMesh(:);
end
%-----------------------------
pntHdl=scatter(cos(thetaMesh).*R+XMesh(:),...
               sin(thetaMesh).*R+YMesh(:),...
               15,sin(thetaMesh).*R,'filled');
set(gca,'Color','k');
set(gcf,'Color','k');
end

Danuanping / Tablecloth

https://ww2.mathworks.cn/matlabcentral/communitycontests/contests/6/entries/14547
在这里插入图片描述

function drawframe(f)
[i,j]=meshgrid(0:1023);
s=3./(j+99);DIM=1024;
y=(j+sin((i.*i+(j-700).^2.*5)./100./DIM+2*pi/48*f).*35).*s;
P(:,:,1)=(mod(round((i+DIM).*s+y),2)+mod(round((DIM.*2-i).*s+y),2)).*110;
P(:,:,2)=(mod(round(5.*((i+DIM).*s+y)),2)+mod(round(5.*((DIM.*2-i).*s+y)),2)).*127;
P(:,:,3)=(mod(round(29.*((i+DIM).*s+y)),2)+mod(round(29.*((DIM.*2-i).*s+y)),2)).*100;
imshow(uint8(P))
end

Adam Danz / Street puddle on a rainy day in the MATropolis

https://ww2.mathworks.cn/matlabcentral/communitycontests/contests/6/entries/14762

function drawframe(f)
% Persistent variable definitions
%   CD: CData of full city reflection image
%    R: surface object for the city image in the puddle reflection
persistent CD R
if f==1
    %% Create city reflection (variable CD)
    rng default
    axes(colorm=gray,Color='k',Projection='perspective')
    hold on
    h=randg(2,5,5); % building heights
    b=bar3(h);      % buildings
    set(b,{'CData'},get(b,'ZData'),{'FaceColor'},{'interp'}) % lighter at top
    b(3).delete % remove a row of buildings
    % Set up axes and field of view
    axis equal
    clim([0,3])
    campos([3,3,0])
    camtarget([4 3 6])
    camva(90)
    camup([-1 0 0])
    % loop through the buildings to add windows
    for i=1:5
        for j=[1 2 4 5]
            s=(j<3)*.82-.41; % which side of the building will be windows be on
            c=.1:.2:h(i,j)-.2;
            d=[c;c];
            z=d(:)'+[0;0;.1;.1];
            y=i+[-.2,.2]+[-1;1;1;-1]/12;
            y=repmat(y,size(c));
            ison=logical(rand(1,numel(d))>0.4);
            patch(z(:,ison)*0+j+s,y(:,ison),z(:,ison),[.48 .46 .17]); % Lights on
            patch(z(:,~ison)*0+j+s,y(:,~ison),z(:,~ison),[.2 .2 .3]); % Lights off
        end
    end
    % Create coherent noise for clouds
    m=400;
    X=linspace(-1,1,m);
    d=hypot(X,X').^-1.7;
    fr=fftshift(fft2(rand(m)));
    sd=ifft2(ifftshift(fr.*d));
    % Scale the noise to within the clim
    cl=rescale(abs(sd),0,2);
    % Plot cloudy sky; x and y extents will be large due to perspective
    w=linspace(-20,30,m);
    surf(w,w,max(h(:))+ones(m)-.9,FaceColor='texturemap',EdgeColor='none',CData=cl);
    % capture image
    fr=getframe;
    CD=flipud(fr.cdata);   % Take a peek:  clf; imagesc(CD); set(gca,'YDir','normal')
    %% Iterate the buffer to the 48th frame so we start with the end-state
    % This will simulate the entire 48-frame animation and use the updated
    % image as a starting point so the animation cycles (because Ned keeps
    % praising animations that cycle :D)
    rng(860411,'twister')
    G=rng;
    updatebuf(CD,1);
    for i=2:48
        updatebuf(CD,0);
    end
    %% Create street terrain
    rng(790316,'twister') % This seed makes a nice puddle
    n=1000; % determines size of the final image
    X=linspace(-1,1,n); %create linear r matrix
    [~,r]=cart2pol(X,X');
    rd=rand(n);
    filt=r.^-2.5; % roughness of puddle edges -- 2.5 is great,2.0-edges are too rough
    fr=fftshift(fft2(rd));
    td=ifft2(ifftshift(fr.*filt));
    st=-rescale(abs(td),-0.2,0); % This scales from 0 to .2
    wlev=0.13;  % Water level;  0.12 and 0.13 look good
    %% Plot street terrain
    clf % clear figure
    g=rescale(imgaussfilt(rand(n),2),0,1); % street texture
    surf(1:n,1:n,st,FaceColor='texturemap',CData=g,EdgeColor='none'); % street
    hold on
    view(2)
    colormap gray
    set(gca,'Position',[0 0 1 1])
    %% Initialize puddle reflection (variable R)
    % add the city image and water level depth
    u=size(CD);
    R=surf(linspace(0,n,u(1)),linspace(0,n,u(2)),zeros(u([2,1]))+wlev,...
        FaceColor='Texturemap',EdgeColor='none',CData=CD);
    clim([0,1])
    
    %% Return random number generator state to replicate ripples
    % This must be at the end of setup
    rng(G)
end
% Update ripples and rain drops on each iteration
[xo,yo]=updatebuf(CD,0);
R.CData=updateCD(CD,xo,yo);
end
function [xo,yo]=updatebuf(CD,TF)
% Update buffers
persistent b1 b2
[r,c]=size(CD,1:2);   % reflection image size
if TF || isempty(b1)
    % Create buffers that map ripples on to the image on first call
    b1=zeros(r,c);
    b2=b1;
end
% Animation: add rain drops
% Set up some variables that won't change between iterations
d=1/36; % dampening parameter determins how quickly the ripples fade,lower values last longer
M=zeros(3); % mask
M(2:2:end)=1;
xM=[-1 0 1];
yM=[-1;0;1];
[x,y]=meshgrid(1:c,1:r);
% On each frame there is a probability of there being a new rain drop
if rand<.2 % increase threshold to increase frequency of new drops
    xp=randi(c);
    yp=randi(r);
    startX=max(1,xp-10);
    startY=max(1,yp-10);
    b2(startY:yp,startX:xp)=-randi(100);
end
% Propagate the ripples
for k=1:3
    b2=filter2(M,b1)/2 - b2;
    b2=b2 - b2*d;
    xo=min(c,max(1,x+filter2(xM,b2))); % x-offset bounded by [1,c]
    yo=min(r,max(1,y+filter2(yM,b2))); % y-offset bounded by [1,r]
    % Swap buffers
    tmp=b2;
    b2=b1;
    b1=tmp;
end
end
function I=updateCD(CD,xo,yo)
% Create the a new image by applying the buffer offsets to the old image CData
f=@(i)interp2(double(CD(:,:,i)),xo,yo);
I(:,:,1)=f(1);
I(:,:,2)=f(2);
I(:,:,3)=f(3);
I=uint8(I);
end

Tim / Light ripples

https://ww2.mathworks.cn/matlabcentral/communitycontests/contests/6/entries/14952

在这里插入图片描述

function drawframe(f)
persistent S wgt dd2
 
if f == 1
rng default
tic
% Underwater scene.
% 1) Procedural ripples from 2 years ago
N=400;
H=randn(N);
y=1:N;
r=@round;
k=zeros(N);
k(r(rand(3)*N^2))=1;
k=conv2(k,ones(29),'same')<1;
for n=1:400
    d=gradient(H);
    g=1.4*(d+1)/6;
    m=mod(r(y+randn(N).*k*4),N)+1; 
    o=mod(r(y'+(5-9*d).*k),N)+1;
    H=conv2(H-g+accumarray([o(:),m(:)],g(:),[N,N]),ones(3)/9,'same');
end
% 2) Light caustics
[x,y]=meshgrid(linspace(0,1,N));
xyzg=[x(:),y(:),x(:)*0];
xyzi=rand(N*5,3);
zscl=0.1;
xyzi=[xyzi-[0,0,1];xyzi;xyzi+[0,0,1]].*[1,1,zscl];
kdOBJ = KDTreeSearcher(xyzi);
zvl=0:.021:1;
clear distS
for n = 1:48
    [idx, dist] = knnsearch(kdOBJ,xyzg+[0,0,zvl(n)*zscl],'k',1);
    distS(:,:,n)=reshape(erf(dist.^2*150), size(x));
end
toc
rng default
% 3) Weight map between color schemes
dst = sqrt((x-.1).^2 + (y-.1).^2);
wgt = erf((1-dst*3)*3)/2+.5;
wga = erf((1-dst*1.5)*5)/2+.5;
% distS = (distS+0.8).^((wgt+0.2)/1.2)-.8;
distS = distS.*(wgt+.2)/1.2;
% 4) Color schemes
cst = distS(:,:,1);
cR = rescale(min(6*cst, 1), 0.7, 1);
cst3 = cat(3,cR.^8,cR.^2.5,cR.^0.9);
cst3B = cat(3,cR,cR.^1.1,cR.^1.8);
cnw = cst3B.*wgt + cst3.*(1-wgt); 
% x(wga<1e-2)=nan;
% y(wga<1e-2)=nan;
% imagesc(wga)
%
%%
clf
cv=.63; 
CC=[cv.^8,cv.^2.5,cv.^.9];
set(gcf,'color',CC);
% "Light" causes loop to time out, so this leverages surfnorm to calculate
% lambertian scattering from a local source
cpxyz = [.4,.4,.7]*1;
xyzl = ([x(:),y(:),0*x(:)]-cpxyz)';
xyzl = xyzl./vecnorm(xyzl);
[nx,ny,nz]=surfnorm(x,y,H/2000+randn(size(H))/6000);
dd2 = abs(reshape(sum(xyzl.*[nx(:),ny(:),nz(:)]'),[400,400]));
dd2=dd2.^.9;
S=surf(x,y,H/2000+randn(size(H))/6000,cnw.*dd2, 'SpecularStrength', 0, 'AmbientStrength', 0, 'DiffuseStrength', 1,'FaceAlpha','flat','AlphaData',wga);
shading flat
camproj p
campos([0.0, 0.0, 0.15]);
camtarget([0.5, 0.5, 0]*0.4);
camva(30);
% light('position', [.5, .5, .5], 'style', 'local');
% light('position', [.5, .5, .5], 'style', 'local','color',[1,1,1]*.3);
axis equal off
axis([-2,2,-2,2,-2,2]);
S.UserData=distS;
% lighting g
%%
end
    ags = linspace(0,2*pi,49);
% for n = 1;
    cst = S.UserData(:,:,f);
    cR = rescale(min(6*cst, 1), 0.7, 1);
    cst3 = cat(3,cR.^8,cR.^2.5,cR.^0.9);
    cst3B = cat(3,cR,cR.^1.1,cR.^1.8);
     
    cnw = cst3B.*wgt + cst3.*(1-wgt);  
    camup([0, sin(ags(f)+pi/2)*0.05, cos(ags(f)+pi/2)*0.05+1]);
    campos([0.0, 0.0, 0.15+sin(ags(f))/45]);
    
    S.CData = cnw.*dd2;
    % drawnow;
    toc
end

Jr / dandelions

https://ww2.mathworks.cn/matlabcentral/communitycontests/contests/6/entries/15037

function drawframe(f)
n=80;
h=pi*(3-5^.5);
z=linspace(1-1/n,1/(n-1),n);
t=h.*linspace(0,n,n);
r=(1-z.^2);
p=r*f/60.*cos(t*f);
q=r*f/60.*sin(t*f);
u=r*f/90.*cos(t);
v=r*f/90.*sin(t);
image(zeros(99,100,3))
hold on
plot(flip(30*(z.^2))+34,80*(-z)+110,'-','LineWidth',4,'Color',[.41 .59 .29])
plot(30*(z.^2)+45,80*(-z)+100,'-','LineWidth',4,'Color',[.41 .59 .29])
for k=1:n
plot3(17*([0 u(k)]+2),17*([0 v(k)]+1.8),170*([0 z(k)]),'*--w','markersize',.1)
plot3(17*([0 p(k)]+4.4),17*([0 q(k)]+1.2),170*([0 z(k)]),'*--w', 'markersize',.1)
end
ht=text(55,80,'🌿','color','g','FontSize',60+f/4,'Color',[.41 .59 .29]);
kt=text(27,80,'🌿','color','g','FontSize',55+f/4,'Color',[.41 .59 .29]);
kt.Rotation = 90
axis equal off %I kind of liked the stem coming out of the figure
end

Shanshan / Sticky note–upgraded version 2

https://ww2.mathworks.cn/matlabcentral/communitycontests/contests/6/entries/14982

function drawframe(f)
ax=axes('position',[0 0 1 1]);
dx=sin(f*0.15);
map=(turbo);
c=map(f*5,:);
x=[-1+dx 1 1-dx -1]*0.8^((f-1)/5);
y=[-1 -1+dx 1 1-dx]*0.8^((f-1)/5);
patch(x,y,c,'edgecolor','none')
hold on
xlim([-1 1])
ylim([-1 1])
axis equal off
end

比赛还有3天就结束啦,感兴趣的快去参加:

https://ww2.mathworks.cn/matlabcentral/communitycontests/contests/6/entries

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

slandarer

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值