Hey , MATLAB官方举办的迷你黑客大赛距离结束只有负的好几天了:
有没有参与活动并获得MATLAB官方限量版蓝色大裤衩的?(今年还是杯子T恤啥的做礼物,下面这个是特别奖来着)
本次活动涌现出一批非常有意思的动画代码,想要查看代码运行效果,可以简单的将参赛代码和以下这几行代码放在同一个文件夹然后运行下面这几行代码:
for i = 1:96
drawframe(i)
drawnow
pause(.1)
end
竞赛地址:
https://www.mathworks.com/matlabcentral/contests/2024-matlab-mini-hack.html
接下来就来看看本次大赛有哪些惊为天人的作品:
作品展示
Timothy / Refraction
https://www.mathworks.com/matlabcentral/communitycontests/contests/8/entries/16382
function drawframe(f)
persistent S Q
% Shorteners & convenience functions
l=@linspace;
v=@(x)x./vecnorm(x);
C=@circshift;
cc=@(x)C(x,[-f,-f]*4);
r=@(x)x/2+fftshift(x)/2;
F=@ifft2;
R=@reshape;
B=@erf;
Y=@sqrt;
P=@randn;
J=@meshgrid;
% Make sand and rocks
rng(2,'v4');
N=768; % Multiple of 96 for smooth transition
q=l(-1,1,N+1);
q=q(1:N);
[q1,q2]=J(q);
k=exp(6i*P(N))./(q.^2+q'.^2+2e-6); % Complex spatial noise
k1=B(abs(F(k))*.5)*0.6-.36; % Rocks
n=hann(N)*hann(N)'; % K-space smoother
k2=abs(F(k.*n.^300))*3+P(N)/200; % Sand
k2=C(k2+sin(q*30*pi)/20,[-1,-1]*30*-1)/20-.2; % Adding ripples & offsets to sand
[k,ki]=max(cc(cat(3,r(k1),r(k2))),[],3); % Combining & indices for coloration
% Sky function: image will be refracted through interface
[x,y,z]=sphere(100);
s=v([1;1;1]);
g=.5-B((Y(sum(((cat(3,x,y,z)-permute(s,[3,2,1])).^2),3))-.5)*5)/2; % Sky & sun
g=g+B(l(-1.5,1,101)'*3)/2+.5; % Adding horizon
[A,E]=J(l(-pi,pi,101),l(-pi/2,pi/2,101)); % Associated grid for interpolation
% Angle span
ags=l(0,2*pi,97);
% Camera positions, targets & up-vectors
p=sin(ags(1:end-1))/40;
cy=[p-.8;-p-.8;-cos(2*ags(1:end-1))/15+.05];
cu=C([-p;p;ones(1,96)],[0,5])*1.3;
ct=C(cy.*[1;1;1.4],[0,-5])+[.2;.2;0];
c=cy(:,f); % Current camera position
% Water surface spectrum generation function
d=@(a,b,c,h)ifftshift(n.^10.*exp(6i*P(N)+h*1i)./((q+a).^2+(q+b)'.^2+c));
wt=cc(r(real(F(d(.01,.01,5e-5,ags(f)*3)*.3+d(.02,.06,1e-3,9*ags(f))/3))/5+.4)); % Water surface
% % % Now start computing refractions
% Surf normals of water -> used for refraction
[x,y,z]=surfnorm(q1,q2,wt);
M=[x(:),y(:),z(:)]; % Normals
X=[q1(:),q2(:),wt(:)]; % Face centers
% Refraction: Camera to surface
ry=v(X'-c)'; % Camera to surface vectors
I=dot(M,ry,2);
I(I<0)=0; % Values <0 would be pointing wrong way
t=Y(1-1.1.^2*(1-I.^2)).*M+1.1*(ry-I.*M); % Refracted ray vectors
G=imag(t(:,3))~=0; % Beyond total reflection
t=real(t);
[Z,L,~]=cart2sph(t(:,1),t(:,2),t(:,3)); % Az & El. of vectors on water surface
L=R(interp2(A,E,g,Z,L,'cubic',0),[N,N]); % Interpolation into sky map
L(G)=0;
% Refraction: Sun to sand
I=M(:,3); % Sediment normal is ostensibly normal so this is a shortcut
t=real(v((Y(1-0.95.^2*(1-I.^2)).*M+0.95*([0,0,1]-I.*M))')'); % Refracted ray vectors
dxy=t(:,1:2).*(-.2-X(:,3))./t(:,3); % Ray intersection offsets
qp=[q1(:),q2(:)];
% More than 10 neighbors is preferable but times out in online execution
[~,D]=knnsearch(qp+dxy,qp,'K',10); % Search for 10 closest intersections
V=sum(exp(-1e5*(D.^2)),2)*1.3; % Exponential distance gives caustic value.
% Avoid lighting objects: lambertian scattering approx. for sediment
% surface
[sx,sy,sz]=surfnorm(q1,q2,k);
vc=sx*s(1)+sy*s(2)+sz*s(3);
% Lambertian scattering for surface in non-refracted regions
cwv=v(X'-c)';
[sx,sy,sz]=surfnorm(q1,q2,wt);
wc=R(sx(:).*cwv(:,1)+sy(:).*cwv(:,2)+sz(:).*cwv(:,3),[N,N]);
% Now create coloring for sediment
o=ones(N,N);
c1=cat(3,1,.9,.8).*o; % Sand
c2=flip(c1,3)/3; % rock
cA=o.*cat(3,0,.6,1)/2; % Ambient color;
m=ki-1; % mask
cl=(c1.*m+(1-m).*c2).*vc*1.5.*B(R(V,[N,N])/10)*2; % Color-map
% Create coloring for watersased on refraction of sunlight & ambient
mp=flipud(sky);
mp(1,:)=[0,.6,1]/2;
L(L<.5)=1.5*wc(L<.5);
L(L<.5)=.5;
L(L>1.5)=1.5;
W=ind2rgb(round(255*rescale(L)),mp);
% Need to fade to blue so get distances...
w=B(R(Y(sum((c-[q1(:),q2(:),k(:)]').^2)),[N,N])*2-2)/2+.5;
cl=w.*cA+(1-w).*cl;
W=w.*cA+(1-w).*W;
qn=-((q+1)'.^2+(q+1).^2).^2/50;
% Plotting
if f==1
S=surf(q,q',k,cl);
hold;
Q=surf(q,q',wt+qn,W);
shading flat;
=axis equal off
set(gcf,'color',[0,.6,1]/2);
camproj p
camva(65);
else
S.CData=cl;
Q.CData=W;
S.ZData=k;
Q.ZData=wt+qn;
end
campos(c);
camtarget(ct(:,f));
camup(cu(:,f));
end
Vasilis Bellos / Spooky Halloween
https://www.mathworks.com/matlabcentral/communitycontests/contests/8/entries/16391
function drawframe(f)
persistent M A T H W O R K S
% Function shorteners
P=@linspace;
u=@arrayfun;
m=@material;
p=@squeeze;
k=@makehgtform;
i=@find;
n=@numel;
if f==1
% Capillary wave parameters
% s=.072; % water surface tension (N/m)
% r=1025; % saltwater density (kg/m^3)
% r=1e3; % freshwater density (kg/m^3) (saves a character)
% a=.03; % ripple amplitude (m)
% T=1; % ripple period (s)
% w=2*pi/T; % angular frequency (rad/s)
% Dispersion
% k1=(w^2*r/s)^(1/3); % wavenumber (rad/m)
% L=2*pi/k1; % wavelength (m)
% c=L/T; % wave celerity (m/s)
% ph=pi/2; % initial phase (rad)
% Fs=24; % Sampling frequency (96/4)
T=1/24:1/24:4; % Time vector
% Define the spatial domain (requires fine spatial discretisation for the ripples & adjusted periodicity to facilitate the seamless loop)
S=4; % Controls the spatial discretisation & the movement speed between frames
M=P(-1.5,1.5,S*96+1); % x
A=M; % P(-1.5,1.5,S*96+1); % y
% Define the initial coordinates for each pumpkin
% W=-1.25:.25:1.5; % xc
W=(-5:6)/4; % xc
O=repmat([0,-.5,.5],1,4); % yc
% % Corrected values
% [~,ind]=u(@(i)min(abs(M-xc(i))),1:n(xc)); W=M(ind);
% [~,ind]=u(@(i)min(abs(A-xy(i))),1:n(xy)); O=A(ind);
% Calculate the water surface elevation
H=C(T,M,A,W,O,n,P,p,i);
% Plotting
axes(Po=[-.5,-.5,2,2],Vis=0,Ne='a')
axis([M([1,end]),A([1,end]),-.2,.2],'equal')
% Water surface
R=surf(M,A,p(H(f,:,:))',EdgeC='n',FaceC='k',FaceA=.8);
% Camera
view(3)
campos([-9 -9 9]) % Tim's trick to save 3 chars
camva(6)
% Lighting
camlight; % This helps discern some the pumpkin details
light(St='l',Po=[2,2,1],Col='g') % Back light
lighting g
% Pumpkins
K=u(@(i)E(P),1:n(W));
% Duplicate
K(n(K)+1:2*n(K))=copyobj(K,gca);
% m(R,'shiny') % Water material
m('shiny') % Water material
m(K,[.45,.7,.25]) % Pumpkin material
end
% Updating frames
% Water surface
R.ZData=p(circshift(H(f,:,:),S*f,2))';
% Pumpkins
% Add advection
c=[diff(M(1:2))*S*f 0 0]; % Center
% Add rotation
r=P(0,4*pi,2*(n(T)+1));
% x-offset
o=diff(M([1,end]));
for j=1:n(K)
try
s=c+[W(j),O(j),H(f,i(M>=W(j),1),i(A>=O(j),1))];
catch
s=c-[o,0,0]+[W(j-n(W)),O(j-n(O)),H(f,i(M>=W(j-n(W)),1),i(A>=O(j-n(O)),1))];
end
set(K(j),'M',k(Translate=s,Zrotate=r(f)*(-1)^j)); % Some direction variation
end
end
% Capillary wave calculation function
function e=C(t,x,y,xc,yc,n,l,q,d)
% Windowing for damping in time
g=[l(0,1,n(t)/8),l(1,0,n(t)*7/8)]; % Quick ramp-up and then gradual decay
[X,Y]=meshgrid(x,y);
for j=1:n(xc)
for i=1:n(t)
e(i,:,:,j)=.03*g(i)*sin(2*pi*t(i)-82*sqrt((X-xc(j)).^2+(Y-yc(j)).^2)+pi/2);
r=.2*t(i);
x1=abs(x-xc(j))<r;
y1=abs(y-yc(j))<r;
% Mask
m=x1.*y1';
% 3D Hanning window mask to simulate ripple propagation & damping in space
m(m==1)=ones(n(d(x1==1)),n(d(y1==1)))'.*(hann(n(d(x1==1))).*hann(n(d(y1==1)))')';
e(i,:,:,j)=q(e(i,:,:,j))'.*m';
end
end
e=sum(e,4);
end
% Pumpkin drawing function
function P=E(l)
r=@repmat;
C=@cos;
S=@sin;
f=@flip;
z=@size;
% n=100;
n=200;
F=.18;
p=pi;
% Body
[X,Y,Z]=sphere(n);
R=(1-(1-mod(0:.1:n/10,2)).^2/12);
X=R.*X;Y=R.*Y;Z=Z.*R;
% Draw the face for the mask
% Mouth
x=[-5:5,f(-5:5)]*.12;
a=[.25 -.5 -.4 -.8 -.65];
b=[.25 -.1 0 -.4 -.25];
y=[a -.95 f(a) b -.5 f(b)]*.6+.5;
% Right eye
x1=[-.42 -.06 -.06 -.42];
y1=[.6 .5 .5 .9];
% Left eye
% x2=abs(x1);
% y2=y1;
% Apply the face mask
M % Changing this to nested massively lowers the character count
H(1)=surf(X*F,Y*F,(.8+(-l(1,-1,n+1)'.^4)*.3).*Z*F,FaceC=[1,.4,.1],EdgeC='n');
% Stem
s=[1.5 1 repelem(.7, 6)].*[r([.1 .06],1,n/20) .1]';
[t,q]=meshgrid(0:p/15:p/2,l(0,p,n/10+1));
H(2)=surf(r(-(.4-C(q).*s).*C(t)+.4,2,1)*F,[-S(q).*s;S(q).*s]*F,r((.5-C(q).*s).*S(t)+.55,2,1)*F,FaceC='#008000',EdgeC='n');
P=hgtransform;
set(H,'Pa',P);
% x-rotation
% function e(X,Y,Z,t)
function e(t) % Nested
% Rotation matrices
Rx=[1 0 0;0 C(t) -S(t);0 S(t) C(t)];
% Ry=[cos(t(2)) 0 sin(t(2));0 1 0;-sin(t(2)) 0 cos(t(2))];
% Rz=[cos(t(3)) -sin(t(3)) 0;sin(t(3)) cos(t(3)) 0;0 0 1];
for i=1:z(X,1)
for j=1:z(X,2)
% r=Rx*Ry*Rz*[X(i,j);Y(i,j);Z(i,j)];
d=Rx*[X(i,j);Y(i,j);Z(i,j)];
X(i,j)=d(1);
Y(i,j)=d(2);
Z(i,j)=d(3);
end
end
end
% Masking function
% function [X,Y,Z]=M(X,Y,Z,x,y,x1,y1,x2,y2)
function M % Nested
% Surface is in the form of
% -1 -1 . . . -1 -1
% . . . . . . .
% . . . . . . .
% 1 1 . . . 1 1
% Easy enough to mask w/ inpolygon (mask projected onto pumpkin)
i=@inpolygon;
% Rotate to align ribs with face
% [X,Y,Z]=e(X,Y,Z,-pi/2);
e(-p/2);
% Mask
m=ones(z(Z));
% mask((i(X,Y,x,y)|i(X,Y,x1,y1)|i(X,Y,x2,y2))&Z>=0)=NaN;
m((i(X,Y,x,y)|i(X,Y,x1,y1)|i(X,Y,abs(x1),y1))&Z>=0)=NaN;
Z=Z.*m;
% Rotate back
% [X,Y,Z]=e(X,Y,Z.*m,pi/2);
e(p/2);
end
end
Matteo / Trapped particles++
https://www.mathworks.com/matlabcentral/communitycontests/contests/8/entries/16395
% This demo features a simple particle system, where particles are emanated
% from a point source located at the origin and follow trajectories
% described by Brownian motion while being constrained to move inside the
% 3D unit ball. Each particle is assigned its own dynamic properties and
% deforms and changes its color according to its position and lifetime.
% When a particle collides with the unit sphere, a "lightning" that
% connects that particle with the origin is drawn.
% Additionally, the plot in the current axes is captured and
% post-processing effects are applied to it (chromatic aberration, blooming).
function drawframe(f)
persistent O
% Global parameters to fine-tune visual output:
n=75; % number of particles
F=96; % number of frames
col0=[0.2 0.6 1]; % color of particles (at the origin)
col1=[1 0.6 0.2]; % color of particles (on the unit sphere)
step=0.1; % distance travelled by particle at each time step
fov=120; % camera field-of-view
outsize=[320 320]; % size of output frames
% Rename frequently occurring functions with long names to save characters:
tpf=@transformPointsForward;
r=@rescale;
g=@imgaussfilt;
m=@(a,b)mod(a-1,b)+1;
% Do not recalculate animation frames that have been already created!
if size(O,4)==F
imshow(O(:,:,:,f),Border="tight");
return
end
% Start by rendering animation from frame 41 to have a better thumbnail:
f=m(f+40,F);
% Precalculate data for animation:
% Imploding factor (used to make animation loop smoothly):
rho=g([ones(F-20,1);zeros(20,1)],10,FilterSize=[61 1]);
% Calculate coordinates of the particles at each frame by applying
% Brownian motion:
rng twister;
P=randn(F,n,3)*step;
P=imgaussfilt3(P,4,FilterSize=[255 1 1],Padding="circular");
P=rho.*cumsum(P);
% Constrain the particles to lie inside the unit ball:
R=vecnorm(P,2,3).*ones(1,1,3);
out=R>1;
P(out)=P(out)./R(out);
% Generate transformation matrices to make particles wobble:
M3=0.2*rescale(rand(1,1,n),1/2,2).*(eye(3)+(randn(3,3,n)*0.2 .*blkdiag(ones(2),0)) );
M3=imgaussfilt3(M3,[1e-2 1e-2 1],'Padding','circular');
M=affinetform3d;
for i=1:n
M(i)=affinetform3d(blkdiag(M3(:,:,i),1));
end
% Generate the texture image for the particles:
tex=r(fspecial('gaussian',32,8/6))+0.3*r(fspecial('gaussian',32,32/6));
tex=imadjust(tex,[0 0.6]);
% Set figure background to black:
figure(1);
set(gcf,'Pos',[0 0 outsize],'Color',col0/10);
% Remove axes and set camera properties:
cla;
axis equal off;
axis([-1 1 -1 1 -1 1]);
campos([0 0 cscd(fov/2)]);
camup([0 1 0]);
camva(fov);
camproj perspective;
set(gca,YDir="normal",Units="normalized",Position=[0 0 1 1],Clipping="off");
% For each particle that touches the unit sphere,draw a "lightning"
% emanating from the origin and reaching that particle:
rng shuffle twister;
q=0.02*randn(20,n,3);
q([1 end],:,:)=0;
l=linspace(0,1,20)'.*P(f,:,:)+q;
l(:,~out(f,:,1),:)=[];
line(l(:,:,1),l(:,:,2),l(:,:,3),'LineW',1.5,'Color',[col1 0.2]);
% In object space,each particle is represented as one quad with its
% vertices sitting on the corners of the unit square of the xy-plane:
[X0,Y0,Z0]=meshgrid([-1 1],[-1 1],0);
% Get the xyz-coordinates of the unit sphere:
[U0,V0,W0]=sphere(64);
% Render settings for particles:
preset={'EdgeC','none','FaceL','none','FaceA','texturemap','AlphaDataM','none'};
% Loop to draw particles:
for k=1:n
% Take the next matrix and apply the corresponding distortion to the unit square:
q=m(k+f,n);
[X,Y,Z]=tpf(M(q),X0,Y0,Z0);
% Assign color to each particle such that particles that are
% close to the origin are more blue and those that are closer to the
% unit sphere are reddish.
col=interp1([0;1],[col0;col1],min(R(f,k),1).^3 );
% Assign alpha value to each particle such that particles that are
% far from the observer tend to fade away:
alpha=r(P(f,k,3),0.1,1,InputMin=-1,InputMax=1);
% Draw the current particle:
surface(X+P(f,k,1),Y+P(f,k,2),Z+P(f,k,3),'FaceC',col,'AlphaData',tex*alpha,preset{:});
end
% Slightly rotate the unit sphere:
RT=rigidtform3d(5*sin(2*pi*f/F.*[1 1 1]+[0 pi/3 pi/4]),[0 0 0]);
[U,V,W]=tpf(RT,U0,V0,W0);
surface(U,W,V,'FaceC','none','EdgeC',col0,'EdgeA',0.05,'LineW',rand*5);
% Post-Processing part...
A=im2double(frame2im(getframe(gca)));
% Simulate chromatic aberration by zooming each color channels by a
% slightly different factor:
[U,V]=meshgrid(linspace(-1,1,width(A)),linspace(-1,1,height(A)) );
D=-cat(3,U,V)*6;
for c=1:3
A(:,:,c)=imwarp(A(:,:,c),D*(c-1),'linear');
end
% Apply monochromatic Gaussian noise (only for uncompressed video):
% A=max(min(A+randn(size(A,1:2))*3/255,1),0);
% Apply "blooming" to the image:
B=rgb2gray(A);
B=imadjust(B,[0.1 1]);
B=g(B,32,FilterSize=193,Padding="replicate");
B=r(B);
A=A+r(B);
% Restore original frame number:
f=m(f-40,F);
% Display post-processed image and store it in a persistent variable:
imshow(A,Border="tight");
O(:,:,:,f)=A;
end
Kaustubh / Never Gonna Give You Up
https://www.mathworks.com/matlabcentral/communitycontests/contests/8/entries/16403
这个放代码没啥意义,这是真正意义上的迷你黑客,本次活动要求提交一个音频来配合MATLAB制作的动画生成有声视频,这位参赛者把视频的数据藏进了音频数据中:
Jenny Bosten / Lake view to the Nort
https://www.mathworks.com/matlabcentral/communitycontests/contests/8/entries/16404
function drawframe(f)
persistent I1 l
if f==1
%Declare functions to save space
u=@linspace;
e=@rescale;
n=@normpdf;
h=@flipud;
z=@zeros;
l=@repelem;
M=@repmat;
d=@rand;
b=@randi;
q=1000;
st=30; %number of striations
cb=4; %number of colorbands (note if this increases > 3, more RGBs will be needed
%makes a matrix of stars, initially these are 2x4 rectangles as every
%other pixel will be taken later
m=l((d(q/4,q/2)/.5+.5).*floor(b(3*q/2,q/4,q/2)/(3*q/2)),4,2);
m(m~=0)=1;
%vector of values as basis for drawing image
X=u(-1,1,q);
[th1, r1] = cart2pol(X,X');
th=u(pi,2*pi,st*2);
%matrix of coords to draw into
[y,x]=meshgrid(X);
k1=erf(abs(ifft2(exp(6i*randn(q))./(X.^2+X'.^2+9e-5)))); %rock texture from Tim!
a1=z(q);
a2=a1+1;
a2(x<(.3*(3*-y.^2+3*k1(1,:))+.8))=0;
M3=M(.55*k1.*a2,1,1,3);
M3(:,:,2)=M3(:,:,2)*1.2;
%y offsets of the striations - in an arc
yo=z(st,cb,96);
el=-[sin(th(1:st).') sin(th(st+1:2*st).') ]-.5;
yo(:,:,1)=[el-.5 el-1.4];
%medium offsets for the first 2 striations in each colour band
yo(1:4,:,1)=[z(4,2)-.3 z(4,2)-1.2];
%yo: pregenerate Y offset jitter to return to baseline within 96 frames (to
%avoid jumps between the segments of the movie stitched together by
%contestMovieGenerator
%ic: pre-generate increments in x position of striations to go back to starting position
%over 96 frames
ic=z(st,cb,96);
ic(:,:,1)=1.5*(sort(d(st,cb))-.5);
ic(1:2,1:cb,1)=z(2,cb);
ic(3:4,1:cb,1)=z(2,cb)+(d(2,cb)-.5);
for p=1:47
ic(:,:,p+1)=ic(:,:,p)+(d(st,cb)-.5)/80;
yo(1:4,:,p+1)=yo(1:4,:,p)+.15.*(d(4,cb)-.5);
yo(5:end,:,p+1)=yo(5:end,:,p)+.1.*(d(st-4,cb)-.5);
end
for p=1:48
ic(:,:,p+48)=ic(:,:,49-p);
yo(:,:,p+48)=yo(:,:,49-p);
end
%x offsets of 3 main colour bands
o=[-.7 .7 -.7 .7];
%Gaussian standard deviations of striation bands
wg=.008+(z(st,cb));
wg(1:2,:)=.5*ones(2,cb); %large standard deviations for 2 bands in each colour
wg(3:4,:)=.2*ones(2,cb);
%start and end RGB values per colour band
R2=[1 .49 .45 .84 .74 .66
.83 .07 .30 .66 .71 .64
.70 .89 .82 .47 .74 .29];
R2(4,:)=R2(3,:);
%standard deviation of striations in the Y
yg=(d(st,cb)+.3)./3;
%large stanard deviations for the first 2 striations in each colour
%band
yg(1:4,:)=z(4,cb)+.5;
%opacity of each colour band
ap=[.9 .9 .7 .7];
%angles of striations in each colour gradient
an=[u(-.25,0,st)
u(0,.25,st)];
an=[an;an];
%striation jitter in angle
aj=(d(st,1)-.5)*.08;
% decides whether striations will be increments or decrements in
% intensity
mu=round(d(st,cb)+.2)*2-1;
%first 2 in each band are always increments
mu(1:2,:)=ones(2,cb);
mu(3:4,:)=-ones(2,cb);
m6=e(n(x,-.3,.8),0,1); %these matrices the position of the colour bands (Gaussian filter)
m7=e(n(x,.5,.8),0,1);
x2=h(x+.4); %these matrices control the position of the colour gradients behind the aurora bands
x3=h(x+1);
I1=z(q,q,3,48); %declare large image matrix
ps=u(.5,.8,10)
for fg=1:48 %make 48 frames (animation changes every 2 frames)
fm=z(q,q,3);
%This is done for each frame
for i1=1:cb
a=a1;
for j=1:st
%rotate the x and y matrices to achieve striations at an angle.
%Includes jitter.
y1=y*cos(an(i1,j)+aj(j))+x*sin(an(i1,j)+aj(j));
x1=y*sin(an(i1,j)+aj(j))+x*cos(an(i1,j)+aj(j));
%this is the line that creates 24 striation layers on each frame
%and adds them to the current matrix for the frame. The y1 part
%does the striation in the x direction. The x1 part puts a Gaussian
%envelope in the vertical Y direction, also with jitter. The wg
%part scales the intensity of the striation inversely to the
%standard deviation. Adjusting the .^7 parameter can change the
%results.
a=a+mu(j,i1)*(wg(j,i1).^ps(randi(10))).*e(n(y1,ic(j,i1,2*fg)+o(i1),wg(j,i1)),0,.2).*e(n(-x1,yo(j,i1,2*fg)+.3,yg(j,i1)),0,.2);
end
%compiles the matrix for each colour band in a cell array, applies a
%vertical mask to create the vertical gradient to black (well, rotated
%vertical)
p1{i1}=a;
%Creates an RGB matrix for one of the colour bands as a straight
%gradient in the Y direction
mm=m7;
xx=x3;
for j=1:3
if i1<=2
mm=m6;
xx=x2;
end
%combines aurora Gaussian mask with color gradient matrices with RGB applied, different
%for the upper and lower aurora bands
b1(:,:,j)=mm.*(xx.*R2(i1,j)+(1-xx).*R2(i1,j+3));
end
%combines the RGB matrix with the striations to create striated colour
%matrices. Saves one for each of the 3 colour bands in a cell array
fm=fm+b1.*M(e(p1{i1},-.1,ap(i1)),1,1,3);
end
fm(M3>0)=M3(M3>0);%add mountain
%Creates star twinkles
m1=m.*(d(q)*.5+.3);
m1(M3(:,:,1)>0)=a1(M3(:,:,1)>0);%remove any stars from inside mountain
m1=[m1(1:2:end,:);h(m1(1:2:end,:))]; %reflect stars
%combines the 3 RGB images into one RGB matrix
fm1=fm(1:2:end,:,:);
fm2=h(fm1).*.5; %reflects and darkens the main image
for k=1:q/2
fm2(k,:,:)=circshift(fm2(k,:,:),b(15),2); %creates ripples
end
I1(:,:,:,fg)=M(m1,1,1,3)+e([fm1;fm2].*e(-r1,0,1),0,1); %creates the image by combining the reflected and unreflected elements and the stars. Rescales.
end
end
b1=l(1:48,1,2);
image(I1(:,:,:,b1(f))) %presents the RGB image, every other frame to slow down
camva(4.8)
end
Kaustubh / The Matrix : Laboratory
https://www.mathworks.com/matlabcentral/communitycontests/contests/8/entries/16389
function drawframe(f)
persistent text_str offsets ycoor xcoor
numChars = 48;
numColumns = 200;
if f==1
figure;
set(gca,'Position',[0 0 1 1])
% Generate random characters within the specified range
randomUnicodeCodes = randi([33, 126], numChars, numColumns);
text_str = cellstr(char(randomUnicodeCodes(:)));
% offsets the start of animation for a given column
offsets = randi([0,95],numColumns,1);
xcoor = randi([0,600],numColumns,1);
ycoor = randi([-300,0],numColumns,1);
end
im = zeros(600,600,3);
textSize = 18;
ydelta = 1.2 * textSize;
trailLength = 32;
% Precompute row and column indices
[cIdx, rIdx] = meshgrid(1:numColumns, 1:numChars);
cIdx = cIdx(:);
rIdx = rIdx(:);
% Calculate position matrix
position = [xcoor(cIdx), ycoor(cIdx) + rIdx * ydelta];
% Calculate color matrix
progress = mod(offsets(cIdx) + f, 96);
inTrail = (2 * rIdx <= progress) & (2 * rIdx > progress - trailLength);
clr = zeros(numChars * numColumns, 3);
clr(inTrail, 2) = 1 - (progress(inTrail) - 2 * rIdx(inTrail)) / trailLength;
clr(inTrail, 1) = clr(inTrail, 2) / 2;
clr(inTrail, 3) = clr(inTrail, 1) / 2;
% Condition for on-screen positions
onScreenIdx = (position(:,1) >= 1 & position(:,1) <= 600 & ...
position(:,2) >= 1 & position(:,2) <= 600);
% Condition for non-black colors
nonBlackIdx = any(clr ~= 0, 2);
% Combine conditions
validIdx = onScreenIdx & nonBlackIdx;
% Filter position, text, and color arrays
filteredPosition = position(validIdx, :);
filteredText = text_str(validIdx);
filteredClr = clr(validIdx, :);
% Insert only the valid text
im = insertText(im, filteredPosition, filteredText, FontSize=textSize, ...
BoxOpacity=0, TextColor=filteredClr);
% the character at the beginning of the trail
for c=1:numColumns
im = insertText(im,[xcoor(c) ycoor(c)+mod(offsets(c) + f, 96)/2*ydelta], text_str(c+f), FontSize=textSize, ...
BoxOpacity=0, TextColor=[0.5 1 0.3]);
end
imshow(im)
end
Zhaoxu Liu / slandarer / Dragon in the deep sea
https://www.mathworks.com/matlabcentral/communitycontests/contests/8/entries/16319
function drawframe(f)
persistent M V R T D rT dH N
if f == 1
V=[ -.016,.822; -.074,.809; -.114,.781; -.147,.738; -.149,.687; -.150,.630;
-.157,.554; -.166,.482; -.176,.425; -.208,.368; -.237,.298; -.284,.216;
-.317,.143; -.338,.091; -.362,.037;-.382,-.006;-.420,-.051;-.460,-.084;
-.477,-.110;-.430,-.103;-.387,-.084;-.352,-.065;-.317,-.060;-.300,-.082;
-.331,-.139;-.359,-.201;-.385,-.262;-.415,-.342;-.451,-.418;-.494,-.510;
-.533,-.599;-.569,-.675;-.607,-.753;-.647,-.829;-.689,-.932;-.699,-.988;
-.639,-.905;-.581,-.809;-.534,-.717;-.489,-.642;-.442,-.543;-.393,-.447;
-.339,-.362;-.295,-.296;-.251,-.251;-.206,-.241;-.183,-.281;-.175,-.350;
-.156,-.434;-.136,-.521;-.128,-.594;-.103,-.677;-.083,-.739;-.067,-.813;-.039,-.852];
V=[0,.82;V;V(end:-1:1,:).*[-1,1];0,.82];
V=V-mean(V,1);
F=1:size(V,1);
Y=V(:,2);
Y=(Y-min(Y))./(max(Y)-min(Y));
N=60;
R=sin(linspace(pi/4,5*pi/6,N))./1.2;
R=[R',R'];R(1,:)=[1,1];
R(5,:)=[2,.6];
R(10,:)=[3.7,.4];
R(15,:)=[1.8,.6];
T=[zeros(N,1),ones(N,1)];
M=zeros(N,2);
D=M;
rT=@(Mat,t)Mat*[cos(t),sin(t);-sin(t),cos(t)];
C=[68,231,197;211,102,88;38,52,95]./255;
C1=C(2,:)+Y.*(C(1,:)-C(2,:));
C2=C(3,:)+Y.*(C(1,:)-C(3,:));
hold on
set(gca,'Color','k','DataAspectRatio',[1,1,1],'Position',[0,0,1,1],'YTick',[]);
axis([-5,5,-5,5])
FV='FaceVertexCData';
FC={FV,C1,'FaceAlpha',.7};
dH(1)=patch('Faces',F,'Vertices',V-[2,0],FV,C1,'FaceColor','interp','EdgeColor','none','FaceAlpha',.95);
for i=2:N
dH(i)=patch('Faces',F,'Vertices',V.*R(i,:)-[2,i./2.5-.3],FV,C2,'FaceColor','interp','EdgeColor','none',FC{3:4});
end
set(dH(5),FC{:})
set(dH(10),FC{:})
set(dH(15),FC{:})
for i=N:-1:1,uistack(dH(i),'top');end
for i=1:N
M(i,:)=mean(get(dH(i),'Vertices'),1);
end
D=diff(M(:,2));
else
t=f/96*4*pi;r=10*(1-cos(t));
Pos=[r*cos(t).*2*((f>48)-.5),-r*sin(t).*1.5] + [2,0];
Dir=Pos-M(1,:);
Dir=Dir./norm(Dir);
T=(T(1:end,:)+[Dir;T(1:end-1,:)])./2;
T=T./(vecnorm(T')');
theta=atan2(T(:,2),T(:,1))-pi/2;
M(1,:)=M(1,:)+(Pos-M(1,:))./80;
M(2:end,:)=M(1,:)+[cumsum(D.*T(2:end,1)),cumsum(D.*T(2:end,2))];
for ii=1:N
set(dH(ii),'Vertices',rT(V.*R(ii,:),theta(ii))+M(ii,:))
end
end
end
Malik / Moonlit Night
https://www.mathworks.com/matlabcentral/communitycontests/contests/8/entries/16414
% This entry is a remix of the previous two entries from last years:
% 1) 'Midnattsol' created by Jenny Boston
% https://www.mathworks.com/matlabcentral/communitycontests/contests/6/entries/12937
% 2) 'the mountains are calling' created by Jr
% https://www.mathworks.com/matlabcentral/communitycontests/contests/4/entries/3246
% Thanks to both of them. While remixing, I learned a lot.
% I will explain the changes I've made throughout the code.
function drawframe(f)
% Modified the RGB triplets to create a moonlit night sky view:
% Black-Navy-Blue-White
g1 = [0 0 0; 10 24 46; 30 60 100; 90 130 180; 180 210 240; 240 240 255];
g2 = [0 0 0; 5 15 30; 15 30 60; 80 100 160; 150 180 220; 240 240 255];
tf = 96; % Total number of frames
z = linspace(1, 6, 100);
d = [linspace(10, 30, tf / 2), linspace(30, 10, tf / 2)];
x(:, :, 1) = interp1(1:6, g1, z);
x(:, :, 2) = interp1(1:6, g2, z);
x = permute(x, [3, 1, 2]);
x = permute(interp1([1, tf], x, 1:2:tf), [2, 3, 1]) ./ 255;
x = cat(3, x, x(:, :, end:-1:1));
a = 1000;
X = linspace(-255, 255, a);
% Removed the linearly generated vectors 'q' & 'm' used for creating
% the sunset & sunrise view in the original entry.
% Moon effect
% Changed [t, r] = cart2pol(X - q(f), 100 + X' - 100 * cos(m(f)))
% to make the moon static.
[t, r] = cart2pol(X, 100 + X');
[x_i, y_i] = find(r < 15);
[x_i2, y_i2] = find(r < 5);
b = x(:, :, f);
j = [0.9 0.9 1]; % Light gray for the moon glow
colormap([j; flipud(b)]);
r(r < 14) = 0.9;
% To keep the mountains static throughout the animation, I added
% 'rng default' in the createMountains function. Therefore, I added
% 'rng shuffle' here to preserve randomness in the river current.
rng shuffle
for k = 1:300
% Adjusted some parameters
y(k, :) = circshift(r(min(x_i), :), randi(30) - 15);
y(k, y_i2 + round(randi(round(d(f))) - d(f) / 2)) = 0.9;
end
imagesc([r(100:600, :); y]);
axis equal;
axis off;
xlim([100 900]);
% Draw Mountains
mountains = createMountains();
hold on;
for i = length(mountains):-1:1
mountainColor = i / 8 * [30 60 100] / 255;
fill(mountains{i}(:, 1), mountains{i}(:, 2), mountainColor, 'EdgeColor', 'none');
end
hold off;
camva(5.9);
end
% Mountain Range
function mountains = createMountains()
% Set the random number generator to default so that the sequence
% remains the same across frames, ensuring the mountain range stays fixed.
rng default
c = 900; % Maximum x-coordinate
n = 800;
m = 0.8;
mountains = cell(8, 1); % Store mountain data
% Set the height range for the mountains: the base is at y = 500
% and the peak can rise up to y = 370. Set the peak to a low value and
% the foot to a high value because of 'circshift'.
peak = 370;
foot = 500;
% Create 8 mountains
for i = 8:-1:1
y_mountain = peak + i / (8 + 3) * (foot - peak); % Height between peak and foot
a = 160 * m^(i - 1);
u = c * (1 - (i - 1) / 8);
x_mountain = linspace(100, c, n);
p = y_mountain / 700 * 4 * pi;
t = x_mountain * 2 * pi / u;
q = sin(p + t) + sin(p + 0.3 * t);
r_mountain = y_mountain + q * a + cumsum(sqrt(0.4 * a) * randn(1, n)) + 3.2^(i - 1);
% Normalize r_mountain to be between the peak and foot
r_mountain = foot - (foot - peak) * (r_mountain - min(r_mountain)) / ...
(max(r_mountain) - min(r_mountain));
v = [x_mountain' r_mountain'; c foot; 0 foot];
mountains{i} = v; % Store the mountain polygon
end
end
William Dean / Trefoil Spring
https://www.mathworks.com/matlabcentral/communitycontests/contests/8/entries/16407
function drawframe(f)
% draws the surface of a 'spring' stretched along the path of a trefoil
% knot with a compression wave travelling through it
persistent N n H t x y z X Y Z u v w R nT F CM U MC L C S D p
% setup
if f == 1
%% helper functions
F = @cellfun;
CM = @cell2mat;
MC = @mat2cell;
L = @linspace;
C = @cos;
S = @sin;
U = 'UniformOutput';
D = {'XData','YData','ZData','CData'};
p = 2*pi;
%% figure/axes
% set axes props
set(gca,'Visible','off','Units','Normalized','InnerPosition',[0 0 1 1],'XLim',[-4 4],'YLim',[-4.4 3.6],'ZLim',[-4 4],'NextPlot','Add');
pbaspect([1 1 1]);daspect([1 1 1]);
% set figure background color
set(gcf,'Color',[0 0 0]);
% lighting
lighting gouraud;
camlight headlight;
%% tube/spiral properties
% number of circles used to define the tube surface
N = 6720;
% number of points to create each circle cross-section
n = 50;
% radius of the central rube, defines the distance of the spiral
% from the central path
R = .5;
% Number of spiral turns around the central tube
nT = 48;
% parameter for the trefoil knot curve
t = L(0, p, N);
% trefoil knot parametric equations
x = S(t) + 2 * S(2 * t);
y = C(t) - 2 * C(2 * t);
z = -S(3 * t);
% tube surface
H = surf(D{1},[],D{2},[],D{3},[],D{4},[],'EdgeColor','none','FaceAlpha',1);
end
%% set up compression wave
% index shift for this frame
I = mod((f - 1) * (N / 96), N); % Shift by fixed amount per frame
% modify t with cosine shaped compression effect, centered on mod((f-1)/96,95)*2*pi, intensity 0.4
tM = cumsum(1-.4*C(t-mod((f-1)/96,95)*p));
tM = tM / max(tM) * p;
% shift the compressed t
tS = [I+1:N,1:I];
tSh = tM(tS);
% interpolate x, y, and z using the compressed, shifted t values
Q = @(a) interp1(t,a(tS),tSh,'pchip');
xC = Q(x); yC = Q(y); zC = Q(z);
%% create the tube and the spiral
% anonymous func to set last column equal to first column
W = @(a) a(:,[1:N-1,1]);
% get trefoil tube surface (X,Y,Z) and spiral path (u,v,w) coordinates
[X,Y,Z,u,v,w] = ST(xC,yC,zC,R);
% match spiral endpoints
u = W(u); v = W(v); w = W(w);
% create another tube that follows the spiral path
[X,Y,Z,~,~,~] = ST(u,v,w,.1);
% match endpoints
X = W(X); Y = W(Y); Z = W(Z);
% reorder the circle points to correct overtwisting
% -> for each circle, i, rotate circle i+1 until distance between
% points minimized
for i = 1:N-1
j = i+1;
[~,l] = min(sqrt((X(:,j)-X(1,i)).^2+(Y(:,j)-Y(1,i)).^2+(Z(:,j)-Z(1,i)).^2));
k = [l:n,1:l-1];
X(:,j) = X(k,j); Y(:,j) = Y(k,j); Z(:,j) = Z(k,j);
end
% sometimes need the swap below if the spiral tube radius is very small
% X(:,1) = X(:,end);
% Y(:,1) = Y(:,end);
% Z(:,1) = Z(:,end);
% make sure the last point of each circle is identical to the first point
X(n,:) = X(1,:);
Y(n,:) = Y(1,:);
Z(n,:) = Z(1,:);
%% update surface
% update tube surface coordinates
set(H,D{1},X,D{2},Y,D{3},Z,D{4},repmat(L(0,1,N),n,1));
% shift the colormap to move colors along the spiral
M = hsv;
Ci = round((f/96)*256);
colormap(M([Ci+1:end,1:Ci],:));
drawnow
function [TX,TY,TZ,SX,SY,SZ] = ST(PX,PY,PZ,CR)
% returns surface coordinates for a tube (TX, TY, & TZ) traveling along the path
% defined by PX, PY, and PZ. Also returns coordinates for the path of a
% spiral (SX, SY, & SZ) traveling along the outside of the tube.
c = @cross;
g = @norm;
d = @diff;
% points along the path
P = [PX',PY',PZ'];
% cell array of normalized tangent vectors at each point along the path
tN = F(@(a) a/g(a),MC([d(P([1:N,1],1)) d(P([1:N,2],2)) d(P([1:N,3],3))],ones(N,1),3),U,0);
% find two vectors normal to each tangent to form a basis for each circle
N1 = F(@(a) c(a,[1 0 0]),tN,U,0);
N1 = F(@(a) a/g(a),N1,U,0);
N2 = F(@(a,b) c(a,b),tN,N1,U,0);
% generate circle points around each point on the path
T = L(0, p, n);
% coordinates for each circle
cPt = F(@(a,b) CR*(a'*C(T)+b'*S(T))',N1,N2,U,0);
% make sure the endpoints exactly match
cPt = F(@(a) a([1:end-1,1],:),cPt,U,0);
% cell array of tube surface points
K = F(@(a,b) a+b,MC(P,ones(N,1),3),cPt,U,0);
% matrices of tube surface points
TX = CM(F(@(a) a(:,1),K,U,0)');
TY = CM(F(@(a) a(:,2),K,U,0)');
TZ = CM(F(@(a) a(:,3),K,U,0)');
% spiral angles
A = p * nT * (1:N) / (N-1);
% spiral points
SP = CM(F(@(a,b,i) [P(i,1)+CR*C(A(i))*a(1)+CR*S(A(i))*b(1);P(i,2)+CR*C(A(i))*a(2)+CR*S(A(i))*b(2);P(i,3)+CR*C(A(i))*a(3)+CR*S(A(i))*b(3)],N1',N2',arrayfun(@(i) i,1:N,U,0),U,0));
SX = SP(1,:);
SY = SP(2,:);
SZ = SP(3,:);
end
end
后言
这期参赛人数和提交作品数量少了很多,但是精品率明显提高,MATLAB官方代码竞赛已经举办多期,由图片到动图再到视频制作,每一年的挑战性都在慢慢增大,大家可以蹲一下明年的竞赛看看会是什么形式,万一能拿到纪念品还是很有意义的: