- /
- 
        Spooky Halloween
        on 1 Nov 2024
        
        
 
    - 30
- 270
- 0
- 3
- 2000
 Cite your audio source here (if applicable): 
drawframe(1);
 Write your drawframe function below
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


 

 
             
            