MATLAB | 官方举办的创意视频大赛 | 第四期迷你黑客大赛赛情回顾

文摘   2024-11-04 22:25   英国  

Hey 各位好久不见,近期是MATLAB官方mini hack 大赛时期,该大赛还有一周就要结束,参与可能获得MATLAB官方纪念品以及亚马逊礼品卡,本期活动要求提交2000字符以内的代码,通过输入不同的参数生成多张图片,图片会被合成为一个长达12秒的视频,大家还可以添加适合的音乐来配合视频。

可惜最近实在有些忙比较难参与进活动,但是还有一周大家还是有机会拿到纪念品和奖金的!

这是我去年参加该活动获得的奖品,大概长这样:

质量还是不错的(杯子很厚实)

想要查看代码运行效果,可以简单的将参赛代码和以下这几行代码放在同一个文件夹然后运行下面这几行代码:

for i = 1:96
    drawframe(i)
    drawnow
    pause(.1)
end

竞赛地址:

  • https://www.mathworks.com/matlabcentral/contests/2024-matlab-mini-hack.html

接下来就来看看本次大赛前几周有哪些惊为天人的作品:

作品展示

Tim / Manta Ray

https://www.mathworks.com/matlabcentral/communitycontests/contests/8/entries/16252

function drawframe(f)
l=@linspace;
N=255;
[z,y,x]=cylinder(ones(1,N),N-1);
zt=y.*(1-x)/33;
xt=z.*(1-x)/20;
yt=-x-.2;
x=(x-.5)*3;
z=z./abs(z).*(1-y.^6).*(1-(x/1.5).^6)/20;  % Compress & taper in z
g=@(x,y)exp(-x.^2*y);
z(z>0)=z(z>0)+.1*erf(3*g(x(z>0)*1.4,15).*erf(exp((y(z>0)-.6)*3)).*(1-y(z>0).^12));
y=y.*(((erf(-y*2)+1)/2).*cos(abs(x)+1)+1.2)/2;
y=y.*(cos(x*2)+1.5)/3;
y=(y+.05).*(1-(x/max(x(:))).^16);
w=(erf((y-.5)*10)+1)/2;
z=z-w.*erf(exp(-x.^2*50))/10;
y=y+w.*erf(10*exp(-x.^2*30))/4;
n=nan(1,N);
x=[x;n;xt];
y=[y;n;yt];
z=[z;n;zt];


% Right - now let's make the caustics / light patterns. Let's make actual
% caustics; e.g. make a rippled surface and use Snell's law to bend rays.
N=96;
cx=l(-1,1,N);
cxu=l(-1,1,N*4);
[cx2,cy2]=meshgrid(cxu*2,cxu*2);
ag=l(0,2*pi,97);

% Now for some other animation details
xs=3;
ys=2;
agf=l(0,4*pi,97);
ags=sin(agf)+1e-6;
rgs=sin(ag)/4;
egs=-cos(agf)/3;

clsf=(rescale(-z).*cat(3,.8,.6,.5));
cls2=(rescale(-z).*cat(3,0,.5,.8));

cm=min(abyss.*linspace(0.4,1.5,256)',1).^.7;
rng(3,'twister');
RR=rand(10,1);
rp = 2*pi*RR;
n=f;
bck=sum(sin(l(0,13,300).*RR*10-2*ag(n)+rp)/40)+l(-.8,1.2,300)';
b=ags(n);
r=xs/b;
zc=z-((x.^2+.1).*sin(y*5+agf(n)+.4)/5);    
[zo,xo,yo]=sph2cart(x/xs*b+rgs(n),y/ys*b+egs(n),(zc+r));
[zb,xb,yb]=sph2cart(rgs(n),egs(n),r);
zo=zo-zb+ags(n)/4;
xo=(xo-xb)+.3*rgs(mod(n-1+45,96)+1);
yo=yo-yb;

% Update ripples
pzr=exp(2i*pi*rand(N));
H=real(ifft2(circshift(fftshift(exp(1i*ag(n)*2*4)*pzr./(cx.^2'+cx.^2+4e-3)),[4,4])))/2e3;
k=hann(9);
H=repmat(circshift(ifft2(fft2(k*k',N,N).*fft2(H)),[-1*(n-1),0]),4,4);
[a,b,c]=surfnorm(cx2,cy2,H);
d=cat(3,a,b,c);

% Incident angle
u=.8;
I=cat(3,0,0,1);
T=sqrt(1-min(u.^2*(1-c.^2),1)).*d+u*(I-c.*d);

% Calculate ray / plane intersections...
t=(H-3)./T(:,:,3);
xf=cx2+T(:,:,1).*t; 
yf=cy2+T(:,:,2).*t;

% Let's get our distances...
[IDX,D]=knnsearch([xf(:),yf(:)],[x(:),y(:)],'k',30);

clr=reshape(sum(exp(-D*30),2),size(x));
clr(z<0)=max(clr(:)*.7);
cpz=[-3,-4,3];
cdst=sqrt(sum((cpz(:)-[xo(:),yo(:),zo(:)]').^2));
wt=reshape(erf((cdst-5.8)*2)/2+.5,size(zo));
surf(xo,yo,zo,(cls2.*wt+clsf.*(1-wt))+(clr-10)/15,'EdgeC','none','SpecularS',0);
hold on;
[xp,zp]=meshgrid(-10:1:10);
yp=ones(size(xp))*5;
xp=xp.*l(4,.5,21)';
surf(xp/2,yp/2,zp/2-3,bck,'FaceC','texturemap','EdgeC','none','AmbientS',1);
colormap(cm);
caxis([-.6,1.4]);
hold off;
light('position',[-1,1,3]);
axis equal
camproj p
campos(cpz)
camtarget([0,0,0]);
camva(20);
set(gcf,'color',[0,.5,.7]);
axis off
end

Eric Ludlam / Hungry Gecko eats Bugs

https://www.mathworks.com/matlabcentral/communitycontests/contests/8/entries/16298

function drawframe(f)

    % Compute a position on the path of our critter
    AF=@(t)[ sinpi(t) sinpi(t)*cospi(t)*2 ]*10;
    Q=f/96*2;
    A=AF(Q);

    persistent LH S BP fpv

    if f==1
        % Segments of our creature - defaults just to get started
        S=ones(18,2)*-10;
        S(:,2)=-18:-1;
    end
    
    % Follow Radii - distances between spine segments
    %FR = [.6
    %      1.2
    %      1.2
    %      1.2
    %      1.2
    %      1.2
    %      1.2
    %      .6
    %      .6
    %      .6
    %      .6
    %      .6
    %      .6
    %      .6
    %      .6
    %      .6
    %      .6
    %      .6];
    B=[.6 1.2];
    FR=B('122222211111111111'-'0')';

    % Body Radii - Sizes of body at that spine segment
    BR=[.7
        1
        .5
        1
        1
        1
        (1:-.1:.2)'
        .2
        .2
        .1];

    % Leg Data
    LS=[4 7];% Segments where legs attached

    % Following Vectors
    FV=0;

    function DF()do follow
    % Follow the anchor point (point 1) by making sure
    % all parts of the spine are the correct length and follow
    % the previous nodes
        FV=dn(S(1,:),S(2,:));
        for k=2:size(S,1)
            FV(k,:)=dn(S(k-1,:),S(k,:));
            S(k,:)=FV(k,:)*FR(k-1)+S(k-1,:);
        end
    end

    function verts=SP(seg, LR)side points
    % Compute pts on the left & right side of a body segment.
    % Useful for eyes, legs, fins, etc
        FV(:,3)=0;% 3 dimensions
        si=[seg-1 seg];% segment indices so there is a direction
        c=cross(FV(si,:),repmat([0 0 1],2,1));% Find the 2 pts
        c=c./vecnorm(c,2,2).*BR(si);% normalize the adjust by the body radii
        c=c*LR;% LR is length from center as a ratio of body size.

        % Final vertices are on the left & right, and offset around the segment
        verts=[c(2,1:2);-c(2,1:2)]+S(seg,:);
    end

    if f==1
        DF();
        
        % Get lizard to walk around the back half of our walking shape
        % so when the video loops it appears seamless.
        for a=linspace(1.5,2,10)
            S(1,:)=AF(a);
            DF();
        end

        % Setup history of the feet/legs
        LH=[SP(LS(1),2)
            SP(LS(2),2)];

        % Footprints vector init to initialized histor
        fpv=LH;
        fpv(:,3)=1;
    end

    S(1,:)=A;% Move anchor point for critter

    DF();% Make critter move to new point.

    %% DRAWING

    %% Footprints
    fpv(:,3)=fpv(:,3)*.9;
    fpv(fpv(:,3)<.1,:)=[]; % Clear out old footprints.
    scatter(fpv(:,1),fpv(:,2),42,[.2 .4 .6],'*','AlphaData',fpv(:,3),'MarkerEdgeAlpha','flat');
    hold on
    
    %% LEGS
    % Origin for each body segment attached to legs
    o1=S(LS(1),1:2);
    o2=S(LS(2),1:2);
    O=[o1
       o1
       o2
       o2];

    % New target locations by calling side points fcn
    T=[SP(LS(1)-1,4)
       SP(LS(2)-1,2)];

    % Compute how far away we are for each historical foot
    d=vecnorm(LH-O,2,2);

    % Update any feet that can stay where they are to be historical posn
    % ie - the foot doesn't move, but leg stretches to keep foot there.
    H=d<3.1;
    T(H,:)=LH(H,:);

    % Update footprint history with any newly moved feet
    NOTE: IK seems to have rounding errors so footprints don't always
    % line up where the legs go.  Close enough for the illusion to work.
    tmp=T(~H,:);
    tmp(:,3)=1;
    fpv=[tmp
         fpv];

    % Upate history of where our feet are
    LH=T;

    % Compute geometry to draw derpy legs
    % IK is an inverse kinematic algorithm (see fcn below)
    V=[];
    D=[-1
       1
       1
       -1];
    for j=1:4
        V=[V%#ok
           nan nan
           IK(S(LS(floor((j+1)/2)),:),T(j,:),D(j))]; 
    end

    % Plot the legs under everything else
    plot(V(:,1),V(:,2),'col','#03ac13','linew',8);
    % Gecko feet with big toes
    plot(V(4:4:end,1),V(4:4:end,2),'*','col','#03ac13','linew',3,'markers',14);

    %% Bug to Eat!
    % After legs but below the body so our critter can eat it.
    bp=AF(mod(floor((Q+.2)*2)/2+.25,2));
    text(bp(1),bp(2),'🕷','fontsi',24,'hor','cent','rot',360*rand);

    % %% Audio Generator
    % % Whenever a foot moves, make a footfall sound.
    % if any(~H([1 3]))
    %     AS.event(1,0);
    % end
    % if any(~H([2 4]))
    %     AS.event(2,0);
    % end
    % % Nom Nom the bug when the bug moves to next location.
    % if ~isempty(BP) && any(BP~=bp)
    %     AS.event(3,0);
    % end
    % BP=bp;

    %% Body Graphics as polyshape
    % Create a bunch of polyshape buffers based on convex hulls of
    % Adjacent points in the spine
    ps=polyshape;
    for i=1:18
        ps(i)=polybuffer(S(i,:),'point',BR(i));
        if i>1
            pseg(i-1)=convhull(union(ps(i-1:i))); %#ok
        end
    end

    plot(union(pseg),'EdgeC','#028a0f','FaceColor','#3cb043','FaceA',1,'linewi',4);

    %% Racing Stripe
    plot(S(:,1),S(:,2),'-.','col','#028a0f','linew',6);
    
    %% Eye Graphic
    EV=SP(2,.8);
    plot(EV(:,1),EV(:,2),'.','col','#7c4700','markers',25);

    % Setup Axes
    axis([-12 12 -12 12])
    set(gca,'pos',[0 0 1 1],'vis','off');

    hold off
end

function S = IK(A, D, S)%Inverse kinematic
% Do some inverse kinematics to position the feet of the lizard.
% I found an algorithm here, and trimmed it down to exclude all the special cases
% which our foot history algorithm prevents us from hitting.  I also
% folded all the known constants (like leg lengths) making this very short.
% https://motion.cs.illinois.edu/RoboticSystems/InverseKinematics.html

    XD=D-A;

    %L1=2; % inner leg segment length
    %L2=1; % outer leg segment length

    % c2 is the cos of q2, where q2 is the angle at the elbow
    % i.e. c2 is a length on a unit circle
    %c2=(norm(XD)^2-L1^2-L2^2)/(2*(L2*L1));
    c2=(norm(XD)^2-5)/4;
    
    % Assume no corner cases will be encountered in the lizard.
    q2=S*real(acos(c2));
    %q1=atan2(XD(2),XD(1))-atan2(L2*sin(q2),L1+L2*cos(q2));
    q1=atan2(XD(2),XD(1))-atan2(sin(q2),2+cos(q2));
    P1=2*[cos(q1),sin(q1)];
    S=[0 0
       P1
       P1+[cos(q2+q1),sin(q2+q1)]]+A;
end

function N=dn(p,t)
% Compute the normalized vector representing normal from POS toward TGT
    d=t-p;
    N=d./vecnorm(d,2,2);
end

Timothy / Yurgen

https://www.mathworks.com/matlabcentral/communitycontests/contests/8/entries/16341

% Yurgen is a dragon in the WingFeather Saga by Andrew Peterson. A highly
% recommended book series for young & old readers. An animated adaptation can be
% viewed for free through Angel Studios.
%
% This dragon was inspired in part from Slandarer's marvelous submission
% Dragon in the deep sea
% (https://www.mathworks.com/matlabcentral/communitycontests/contests/8/entries/16319)

function drawframe(f)
nsg = 55;               % Number of dragon segments
l=@linspace;
c=@circshift;
r=@interp1;
ll=l(-1,1,nsg);
tl=(erf(ll*5-1)+1).*l(2,0,nsg);
sd=tl./tl+2*exp(-(ll+.7).^2*100);
tp=erf(-ll*5+3)/2+.5;

% Basic segment creation
rd=.8:.05:1.1;
[x,y,z]=cylinder([0,rd,rd(end-2),0],24);
z(end-1,:)=z(end-3,:)+.05;

% Path & orientation vectors
t=l(0,2*pi,100)';
g=[sin(t),cos(t),sin(2*t+5)/2];
d=cumsum([0;sqrt(sum(diff(g).^2,2))]);
df=l(0,d(end),97);
df(end)=[];
gp=8*r(d,g,df);
d1=gp-c(gp,1);
d2=d1-c(d1,-1);
d1=d1/2+c(d1,-1)/2;
d2=-d2;
v=@(x)x./vecnorm(x')';
d1=v(d1);
d2=v(d2);
d3=cross(d1,d2);
dN=l(0,df(end)*.75,nsg);

% Dragon head
[q,w,e]=cylinder([0,.7,ones(1,15)],24);
lm=l(.7,2,17)';
q(5:9,:)=q(5:9,:)*.8;
w(5:9,:)=w(5:9,:)*.9;
w=erf(w.*lm/2-.8)*2+1.8;
t=zeros(1,25);
t(1:2:25)=.1;
t=t.*(erf((l(-1,1,17)-.5)*4)/2+.5)'+1;
q=.7*q.*lm.*t.^6;
w=w.*t.^6;
e=4*e.*t.^2;
q(10,[4,10])=0;
q(2,[3,11])=0;


    n=f;
    rr=@(v)r(df,c(v,n-1),dN);
    id1=rr(d1);
    id2=rr(d2);
    id3=rr(d3);
    igp=rr(gp);
    xf=[];
    yf=[];
    zf=[];
    for m = 1:nsg
        rmat = [id3(m,:);id2(m,:);id1(m,:)];

        rd=ones(1,25);
        r2=rd;
        r3=rd;
        rd(2:2:end)=.9;
        r2([7,19])=[tl(m)+1.1,tl(m)+1];
        r3([15,7,23])=sd(m);
        sc=ones(10,1);
        sc(1:2:end)=1;
        xn=x.*rd.*sc.*r2.*r3*tp(m);
        zn=y.*rd.*sc.*r2.*r3*tp(m);
        yn=2*z.*rd.*r2;

        b=.85*[xn(:),zn(:),yn(:)]*rmat+igp(m,:);
        rs=@(v,q)reshape(v,size(q));
        xf=[xf;rs(b(:,1),x)];
        yf=[yf;rs(b(:,2),x)];
        zf=[zf;rs(b(:,3),x)];
        
        if m==1
            b=[q(:),w(:)-1,e(:)-2]*rmat+igp(m,:);    
            ch=bsxfun(@power,(cat(3,.4,.6,.8).*w./w),l(1,0,17)'.^.3);
            ch(9:10,3:4,:)=cat(3,1,0,.4).*ones(2);
            ch(9:10,9:10,:)=cat(3,1,0,.4).*ones(2);
            surf(rs(b(:,1),w),rs(b(:,2),w),rs(b(:,3),w),ch,'AmbientS',.3);
            hold on;
         end
    end
    sd2=sd.*ones(10,1);
    tl2=tl.*ones(10,1)+1;
    a=xf./xf;
    a(:,[7,15,19,23])=([sd2(:).*tl2(:),sd2(:),tl2(:),sd2(:)]<1.1);
    b=imdilate(1-a,ones(1,3));
    b=b./b;
    a=a./a;
    cf=permute(r([0,1]',[1,.9,.9;1,.2,.3],l(0,1,550)'),[1,3,2]);
    c2=cat(3,.4,.6,.8).*ones(550,25);
    surf(xf.*b,yf.*b,zf.*b,cf.*ones(1,25),'AmbientS',.8,'SpecularS',1,'DiffuseS',1);
    surf(xf.*a,yf.*a,zf.*a,c2,'AmbientS',.3,'DiffuseS',1);
    shading flat
    hold off;
    axis equal off
    light('position',[0,0,1]);
    camproj p
    campos([-1,-1,0]*40)
    camva(15);
    camtarget([0,0,.5]);
    set(gcf,'color',[0.05,0,.1]);
end

Jenny Bosten / Then and now

https://www.mathworks.com/matlabcentral/communitycontests/contests/8/entries/16199

function drawframe(f)
persistent q m ic u e n X o wg R yg yo ap an aj r m1 b2 a1 d1 x y mu x2 x3 M d x4 O
if f==1
    u=@linspace;
    e=@rescale;
    n=@normpdf;
    r=@randperm;
    M=@repmat;
    O=@round;
    d=@rand;
    q=600;
    m=(d(q)/.5+.5).*floor(randi(3*q,q)/(3*q));
    m(m~=0)=1;
    ic(:,:,1)=.7*(d(24,3)-.5);
    for p=2:48
        ic(:,:,p)=ic(:,:,p-1)+(d(24,3)-.5)/80;
    end
    for p=1:48
        ic(:,:,p+48)=ic(:,:,49-p);
    end
    X=u(-1,1,q);
    o=[-.5 .1 .6];
    w=.018*(d(24,3).^2);
    wg(:,1)=w(r(24));
    wg(:,2)=w(r(24));
    wg(:,3)=w(r(24));
    wg(1:2,:)=.33*ones(2,3);
    R=[.77 .97 .12 1 .16 .59.12 .97 .18 .98 .36 .90.18 .99 .75 .78 .5 .97];
    yg=(d(24,3)+.3)./2.5;
    yg(1:2,:)=[1.6 1 11.2 1 1];
    yo=d(24,3,1)-.2;
    yo(1:2,:,1)=[-.2 .1 .2;-.2 .1 .2];
    for p=2:48
        yo(1:2,:,p)=yo(1:2,:,p-1)+.15.*(d(2,3)-.5);
        yo(3:end,:,p)=yo(3:end,:,p-1)+.1.*(d(22,3)-.5);
    end
    for p=1:48
        yo(1:2,:,p+48)=yo(1:2,:,49-p);
        yo(3:end,:,p+48)=yo(3:end,:,49-p)+.1.*(d(22,3)-.5);
    end
    ap=[.9 .9 .9];
    an=[.25 .3 .35];
    aj=d(24,1)*.08;
    a1=zeros(q);
    [y,x]=meshgrid(X,X);
    mu=O(d(24,3)+.3)*2-1;
    mu(1:2,:)=ones(2,3);
    x2=x;
    x3=x;
    x4=x;
    u1=[19 47 61 84 91 119 133 168 188 220 232 277 299 348 356 389 403 463]+50;%x positions of stonehenge vertical blocks
    u2=[18 4767 108130 174;202 375]+50;
    v=0;
    ds=1;
    us=0;
    vi=0;
    si=0;
    ss=0;
    s0=1;
    sh=0;
    for h=1:q
        v=v+randn/4;
        if ismember(h,u1)
            if ds==1
                us=1;
                ds=0;
                vi=0;
            else
                us=0;
                ds=1;
                vi=1;
            end
        end
        if us==1
            si=si+randn/4;
            if vi==0
                exs=d(1)*60;
                vi=1;
            else
                exs=60;
            end
        else
            if vi==1
                exs=d(1)*60;
                vi=0;
            else
                exs=0;
                si=0;
            end
        end
        x2(:,h)=circshift(x(:,h),randi(2)+O(v),1);
        x3(:,h)=circshift(x(:,h),-O(exs)+O(v)+O(si),1);
    end
    co=0;
    os=[3 3 3 7];
    for my=1:4
        for l=u2(my,1)+2:u2(my,2)
            if l==u2(my,1)+2
                q1=min(find(x3(100:end,l)>.75));
            end
            co=co-randn/8;
            x4(q1-12+100+os(my)-2-O(co):q1+100+os(my),l)=99;
        end
    end
end
    for i=1:3
        a=a1;
        for j=1:24
            y1=y*cos(an(i)+aj(j))+x*sin(an(i)+aj(j));
            x1=y*sin(an(i)+aj(j))+x*cos(an(i)+aj(j));
            a=a+mu(j,i)*(wg(j,i).^.7).*e(n(y1,ic(j,i,f)+o(i),wg(j,i)),0,1).*e(n(x1,yo(j,i,f),yg(j,i)),0,.5);
        end
        p1{i}=a.*e((x+3).^.5,.2,1);
        for gy=1:3
            b1(:,:,gy)=x.*R(i,gy)+.05-(x-.6).*R(i,gy+3);
        end
        b2{i}=b1.*M(e(p1{i},-.1,ap(i)),1,1,3);
    end
    m1=m.*(d(q)*.5+.3);
    fm=M(m1,1,1,3)+b2{1}+b2{2}+b2{3};
    fm(M(x2,1,1,3)>.75)=0;
    fm(M(x3,1,1,3)>.75)=0;
    fm(M(x4,1,1,3)>98)=0;
    image(fm)
    camva(4.5)
end

Tim / Moon elevator

https://www.mathworks.com/matlabcentral/communitycontests/contests/8/entries/16215

function drawframe(f)

% This is supposed to be the view out of a window moving
% upward in the night sky. We will start with the window and 
% create the clouds in the background,
persistent clr3 x d B
E='EdgeC';
F='FaceC';
l=@linspace;
if f==1
    % Make a torus (for circular window)
    N=200;
    a=l(0,2*pi,N);
    b=cos(a');
    z=sin(a')*2.5;
    x=b.*cos(a)+7*cos(a);
    y=b.*sin(a)+7*sin(a);
    [c,d]=meshgrid(l(-1,1,N)*8);
    surf(x,erf(z/2)*2,y,F,[1,1,1],E,'none','DiffuseS',1,'AmbientS',.2);
    hold on;

    % Make the wall of the elevator
    surf(c,.2*c.^2,d,E,'none',F,[1,.7,.5]);

    % Make the window - make it black so we know where to add the scenery
    [x,y,z]=sphere;
    surf(x*6,y*6,z*6,F,'k','SpecularS',0);
    hold off;

    % Add a bit of color, pretty it, etc.
    light('color',[1,.8,.2])
    axis equal off
    view([00]);
    camva(5);    
    G=gcf;
    G.Position(3:4)=[600,600];  % Size for subsequent frames

    % Get the image which will be used later as picture foreground
    V=getframe(G);
    B=V.cdata;
    
    % Now our 3D noise. This will be similar to rolling fog, but larger.
    % Multiple of 96 for seemless loop.
    rng(1,'twister');    
    x=l(-1,1,480);
    b=length(x);
    d=x(1:3:end)/3;         % This is the distance vector away from camera
    c=length(d);
    r=ifftshift(sqrt((x).^2+d'.^2+permute(x.^2,[1,3,2])));

    % Not going to do any looping noise permutations in this one. It looks
    % cool but slows things down, so will use a static noise realization.
    enz=exp(2i*pi*randn(c, b, b))./max(r.^2.4,1e-5);
    dt=5*abs(ifftn(enz));
    h=.055*4;
    ap=dt>h;

    % Add glint from vertical direction but needs to be symmetric so the
    % integrator will need to be fourier (vs. rolling fog's cumsum)
    flt_cum=zeros(1,size(ap, 3));
    flt_cum(1:100)=1;
    flt_cum(101:150)=l(1,0,50);
    flt_cum=fft(flt_cum);

    % Thresholding, making alpha, etc.
    c_alp=real(ifft(fft(ap,[],3).*permute(flt_cum,[132]),[],3));
    CLS=(1.1-erf(c_alp/5)).*ap.*dt;
    CLS(CLS>h)=h;
    clr3=flip(CLS,3);
end

% Now, adding perspective. This is going to be done using a pin-hole camera
% model. This can be approximated by scaling things vs. range; this will be
% done using interpn. Re-scaling vs. range is done here:
[d2,d1,d3]=meshgrid(x,d,x);
scl=rescale(l(1,0,160)'.^2,.3,2);
clr4=interpn(d1,d2,d3,circshift(clr3, [0-5*(f-1)*0-5*(f-1)]),d1,d2.*scl,d3.*scl,'nearest',0);

% It looks really ugly to have massive pixels at close range, so this
% is a range-dependent 2D filter applied to each page of the noise
% function.
rflt=-erf((ifftshift(squeeze(sqrt(d2(1,:,:).^2 + d3(1,:,:).^2)))-permute(linspace(.8,.3,160).^2, [132]))*50)+1;
rflt=rflt./(max(rflt,[],[1,2])+eps);
fclr=abs(ifft2(fft2(permute(clr4,[2,3,1])).*rflt));

% Now apply the alpha channel to compress the volume into a 2D image
ffclr=flip(fclr,3);
alpha=ffclr;
As=alpha(:,:,1);
Ic=ffclr(:,:,1);
for nn=2:160
    Ap=As;
    As=Ap+alpha(:,:,nn).*(1-Ap);
    Ic=(Ic.*Ap + ffclr(:,:,nn).*alpha(:,:,nn).*(1-Ap))./(eps+As);
end

% Finally, combine the foreground and imagery outside the window...
A=uint8(255*repmat(imresize(flipud(min(Ic*10,1)'),size(B(:,:,1))),[1,1,3]));
A(B~=0)=B(B~=0);
imshow(A);
end

Jr / 2/3 - Shai Hulud

https://www.mathworks.com/matlabcentral/communitycontests/contests/8/entries/16174

%Hi everyone, last year I made some fun animation sequences and I thought I would repeat this idea :)

%2/3 - Shai Hulud

function drawframe(f)
c=1200;
n=800;
hold on;

%Shai-Hulud is a sacred term that is usually spoken with a tone of awe, fear, or respect:

text(370,280+f,'●','color','k','Fontsi',260);
text(380,250+f,'🌣','color','w','Fontsi',220);
text(500,245+f,'🌣','color','w','Fontsi',120);

%Dunes:

for i=6:-1:1
    y=i/(20)*n;
    u=c*(1-(i-1)/20);
    x=linspace(0,c,n);
    p=y/n*12;
    t=x*6/u;
    q=0.8*sin(f*p/18+t)+0.8*sin(f*p/13+.3*t);
    r=y+q*160*.8^(i-1);+3^(i-1);
    v=[
    x' r';
    c 0;
    0 0];
    fill(v(:,1),v(:,2),i/6*[.8 .8 .8],'EdgeColor','n');
end
axis equal off;

ylim([0,n])
end

Kaustubh / Can It Run Doom?

https://www.mathworks.com/matlabcentral/communitycontests/contests/8/entries/16360

% This code pays homage to the legacy of DOOM,
% a game known for its impact on gaming history & its adaptability.
% and for being adapted to run on virtually any device imaginable.
% Also, I'm new to MATLAB so my code could be much better

function drawframe(f)

    % function handles to reduce code length
    L=@size;
    r=@repmat;
    g=@meshgrid;
    n=@randn;
    b=@abs;
    
    % SOME USEFUL FUNCTIONS

    % surf plot
    s=@(X,Y,Z,C)surf(X,Y,Z,C,EdgeColor="none");

    % creates the maze pattern for the door
    m=@(A,B,D)occupancyMatrix(mapMaze(A,B,MapSize=L(D),MapResolution=1));

    % tiles a 64x32 texture on a 2D matrix X
    t=@(T,X)r(T,L(X)./[64 32]);


    % to prevent rerender every frame
    persistent o D
    if isempty(o)
        hold on;


        % DEFINE GEOMETRY AND TEXTURES
        
        % Floor Geometry
        [X,Y,Z]=c(-14,17.99,.01,52);
        q=b(X)<2&Y>12;
        Z(q)=fix(Y(q)/2)-5;
        Z(Y>24&Y>23+b(X/2))=7.1;
        
        % Floor Texture
        [j,i]=g(mod(1:512,32),mod(1:832,64));
        S=24-b(i-24)==b(j-16)|48<i&i<65&j==16|16<i&i<33&~j;
        S=(.1+.1*S).*(1-circshift(S,-2,2));

        s(X,Y,Z,.1+r(S,[1,1,3])+r(peaks(64)/50,13,8,3)+n(L(Z))/50);
        

        % Wall Texture 64x32
        T=.6+zeros(64,32);
        [j,i]=g(1:32,1:64);
        T(i>29)=.6+cos(i(i>29))/4;
        T(i>36&i<43)=.6;
        q=mod(j+4,32)<9;
        T(q)=T(q).*(.7-cos(.6*j(q))/5);
        T(i>48)=.5;
        T(i>56)=.4+cos(.6*i(i>56)-8)/5;
        T=r(T+n(L(T))/50,[1 1 3])/2;

        
        % Side wall geometry
        [Y,Z]=c(0,51.99,0,19.99);
        X=30-Y/2;
        X(Y<48)=6;
        X(Y<36)=10-4*(Y(Y<36)-29)/7;
        X(Y<29)=10;
        X(Y<28)=38-Y(Y<28);
        X(Y<24)=14;
        C=t(T,X);       % Side wall texture
        s(X,Y,Z,C);   % on right
        s(-X,Y,Z,C);  % on left
        

        % Stairs, platform wall and back wall
        [X,Z]=c(0,11.99,.01,20);
        Y=23+X/2
        Y(X<2)=11.97+2*fix(Z(X<2));
        Y(Z>7)=52.3;
        C=t(T,X);    % Wall texture
        
        % Stairs front texture
        S=ones(96,32);
        [j,i]=g(1:32,mod(1:96,16));
        q=mod(i+3,16)<4;
        S(q)=S(q)*.8;
        S(i==7)=S(i==7)/.8;
        S(i>7)=S(i>7).*(1+cos(.4*j(i>7))/6);
        C(1:96,1:32,:)=(reshape([28*S 22*S 18*S],96,32,3)+n(96,32))/72;
        
        s(X,Y-.2,Z,C);    % on right
        s(-X,Y-.2,Z,C);   % on left
        

        % Top wall
        [X,Z]=c(-12,11.99,12,15.99);
        s(X,max(24,23+b(X/2))-.2,Z,t(T,X)); 
        

        % Door
        [X,D,Y,C]=c(-4,4,0,8);
        C=C+.25-(m(8,8,X)+m(3,1,X))/9+n(129)/50% Door texture

        o=s(X,Y,D,C);     % Front door - the one that opens
        s(X,52+Y,7+D,C);  % Back door
        

        % Roof
        [X,Y]=c(-13.99,14,8.01,52);
        Z=~~Y*14.5;
        Z(Y>24&Y>23+b(X/2))=12;
        Z(Y>36)=17;
        s(X,Y,Z,r(reshape([6 7 5]/32,1,1,3),L(X))+(r(peaks(64),11,7,3)+n(L(Y)))/99);
    

        % CAMERA AND OTHER SETTINGS
        camproj('perspective');
        axis equal; 
        camva(80);

        % Black Bars at top and bottom
        a=@(s)annotation('rectangle',[0,s,1,1/6],FaceColor='k');
        a(0);
        a(5/6);
    
    end
    

    % ANIMATION LOGIC

    x=0:80;   % the camera is in motion for 80 frames

    % shows progress b/wetween 0 and 1,
    % smoothed for eased start and stop of the camera
    y=(x<17).*x.^2/2048+(16<x&x<64).*(x/8-1)/8+(63<x).*(5*x/8-17-x.^2/256)/8;
    
    % The Y-coordinate(forward) of the camera based on the progress
    Y(1:15)=-2;
    Y(16:96)=y*52-2;
    
    % The X-coordinate(right) of the camera based on Y
    X=(Y-56)/3;
    X(1:38)=(Y(1:38)-4)/3;
    X(39:78)=4-Y(39:78)/5;

    % Moving average of X to reduce jerk at turns
    Xa(:)=X(:);
    for i=30:83
        Xa(i)=sum(X(i-5:i+5))/11;
    end

    % The variable to change the target of the camera
    h=ones(96)/3;
    h(34:43)=linspace(1/3,-.2,10);
    h(44:73)=-.2;
    h(74:83)=linspace(-.2,1/3,10);

    % The Z-coordinate(up) of the camera to handle stairs
    % and wave up-down for a walking motion
    Z=2.5+max(0,min(Y(f)/2-6,7))-sin(.6*(Y(f)+2))/2;

    % Move and point the camera
    campos([Xa(f) Y(f) Z]);
    camtarget([Xa(f)+h(f) Y(f)+1 Z])

    % Open the front door
    set(o,ZData=D+f/4); 

end

% returns a meshgrid, height matrix & color matrix (for surf)
% for the required dimension
function [X,Y,Z,C]=c(x1,x2,y1,y2)
    [X,Y]=meshgrid(x1:1/16:x2,y1:1/16:y2);
    C=zeros([size(X),3]);
    Z=C(:,:,1);
end

Jenny Bosten / The third dimension

https://www.mathworks.com/matlabcentral/communitycontests/contests/8/entries/16357

function drawframe(f)
persistent f1
if f==1
f1=figure('Position',[0 0 1000 1000])
end
p=@pol2cart;
o=@rotate;
an=linspace(0,360,97);
%inner and outer star radii
r_out=1;
r_out2=0.95;
r_out3=0.80;
r_in=.5;
r_in2=.45;
r_in3=.3;
ar=5;
th=[(-pi/2:2*pi/(2*ar):2*pi-pi/2)+pi/2].'; %star angles
c4=cat(3,.94,.83,.16); %star colour
am=ones(1,ar);
ro=r_out*am; %star layers to create curvature
roa=r_out2*am;
rob=r_out3*am;
ri=r_in*am;
ria=r_in2*am;
rib=r_in3*am;
r=[];
ra=[];
rb=[]; 
for i=1:ar %star radii vertices
    r=[r ro(i) ri(i)];
    ra=[ra roa(i) ria(i)];
    rb=[rb rob(i) rib(i)];
end
r1=[r r_out].';
r1a=[ra r_out2].';
r1b=[rb r_out3].';
[Z,Y]=p(th,r1); %star vertices Carterian
[Za,Ya]=p(th,r1a);
[Zb,Yb]=p(th,r1b);
o_s=ones(length(Z),1);

X1=-.05*o_s; %depth coordinates for layers
X2=+.05*o_s;
x1a=.15;
x2a=-.15;
x1b=.20;
x2b=-.20;
x1c=.20;
x2c=-.20;

v_s=zeros(length(Z),1);
%star layers to make surfaces
X_s=[v_s+x2c v_s+x2b v_s+x2a X1 X2 v_s+x1a v_s+x1b v_s+x1c];
Z_s=[v_s Zb Za Z Z Za Zb v_s];
Y_s=[v_s Yb Ya Y Y Ya Yb v_s];
P(1)=surf(X_s,Y_s,Z_s+1,0.*X_s+c4);%star surface
hold on

[Xs,Ys,Zs]=sphere(50);% for eyes
P(2)=surf(.15*Xs/2+0.2,.15*Ys./3+.15,.15*Zs+.15+1,0.*Ys+0*c4); 
P(3)=surf(.15*Xs/2+0.2,.15*Ys./3-.15,.15*Zs+.15+1,0.*Ys+0*c4);

%rotate star on each frame through z plane
o(P(1),[0 0 1],an(f),[0 0 0]);
o(P(2),[0 0 1],an(f),[0 0 0]);
o(P(3),[0 0 1],an(f),[0 0 0]);

%for mushroom
a=500;
%spheres for hat and head
[Xs,Ys,Zs]=sphere(a);
[Xh,Yh,Zh]=sphere(a);

%mushroom colours and grass
c4=cat(3,.89,.225,.32);
c3=cat(3,.96,.84,.54);
c5=cat(3,.18,.87,.03);

X=linspace(-1,1,a+1);
[x,y]=meshgrid(X,X');
xp=[.5 -.5 0];
yp=[-.3 -.3 .7];
m=ones(a+1,a+1,3); %pattern matrix for mushroom spots
m2=m.*c4;
for k=1:3
[t,r]=cart2pol(X+xp(k),X'+yp(k));
r=repmat(r,1,1,3);
m2(r<0.4)=m(r<0.4);
end

%this was a bit of a fudge to try to create a curve on the lower edge of
%the hat
inc=linspace(0.01,0.3,30);
for k=1:30
Zs(Zs>0.6+inc(k))=Zs(Zs>0.6+inc(k)).*Zs(Zs>0.6+inc(k)).^inc(k);
end
Zs=Zs.*-1;
%mushroom spheres for hat, eyes and face
P(2)=surf(1*Xs,1*Ys,1*Zs-1.5,m2);
P(4)=surf(.6*Xh,.6*Yh,.5*Zh-.8-1.5,0.*Ys+c3);
P(5)=surf(.06*Xh+.27*2,.06*Yh-.16,.14*Zh-.9-1.5,0.*Ys+0*c3);
P(6)=surf(.06*Xh+.27*2,.06*Yh+.16,.14*Zh-.9-1.5,0.*Ys+0*c3);
y = [-4 4 -4-4 4 4 ; -4 4 -4-4 4 4 ];
x = [-4 -4 -4-4 -4 -4-2 -2 -2-2 -2 -2];
z = [-1 -1 -1-4 -4 -4;-1 -1 -1-4 -4 -4];
%grass
P(7)=surf(x,y,z,0.*z+c5);
shading interp
light
view([90 0])
lightangle(-60,30);
lighting gouraud
material shiny
material([.6.6.83])
axis equal
axis off
set(gcf,'Color',[.30 .54 .82])
camva(4.6)
xlim([-4 1])
ylim([-4 4])
zlim([-4 3])
hold off
end

相关推荐

此外推荐一下Tim大佬在比赛开始前分享在MATLAB官网 Tips & Tricks 模块的文章:Walkthrough: making Little Nemo's airship in Matlab

非常详细的讲解了怎么构建一个飞行艇的模型,怎样使用erf函数进行平滑:

  • https://www.mathworks.com/matlabcentral/discussions/tips/875587-walkthrough-making-little-nemo-s-airship-in-matlab

后言

活动还有一周,大家现在参与还是有机会获得奖品的!而且一般来说官方还会抽取幸运奖,趁着没结束挑战一下叭!


slandarer随笔
slandarer个人公众号,目前主要更新MATLAB相关内容。
 最新文章