- /
-
Floating Pumpkins
on 27 Oct 2024
- 34
- 415
- 1
- 7
- 1953
Cite your audio source here (if applicable):
drawframe(1);
drawframe(76);
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/Fs:1/Fs: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=P(-1.5,1.5,S*96+1); % y
% Define the initial coordinates for each pumpkin
xc=-1.25:.25:1.5;
xy=[0,-.5,.7,0,-.7,.5,0,-.5,.7,0,-.7,.5];
% 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,a,w,k1,c,ph,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='b',FaceA=.8);
% Camera
view(3)
campos([-10 -10 10])
camva(6)
% Lighting
camlight % This helps discern some the pumpkin details
light(St='l',Po=[2,2,1],Col='c') % Back light
lighting g
% Pumpkins
K=u(@(i)E(.18,P),1:n(W));
% Duplicate
K(n(K)+1:2*n(K))=copyobj(K,gca);
m(R,'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
cr=[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)
a=r((mod(j,2)+1)*f)*(-1)^j; % Some rotation angle and direction variation
if j<=n(W)
set(K(j),'M',k(Translate=cr+[W(j),O(j),H(f,i(M>=W(j),1),i(A>=O(j),1))],Zrotate=a));
else
set(K(j),'M',k(Translate=cr-[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))],Zrotate=a));
end
end
end
% Capillary wave calculation function
function e=C(t,x,y,xc,yc,a,w,k,c,p,n,l,q,d)
% Windowing for damping in time
g=[l(0,1,n(t)/8),l(1,0,n(t)*.75),l(0,0,n(t)/8)]; % Delaying the start and speeding up the end of the ripples
[X,Y]=meshgrid(x,y);
for j=1:n(xc)
for i=1:n(t)
e(i,:,:,j)=a*g(i)*sin(w*t(i)-k*sqrt((X-xc(j)).^2+(Y-yc(j)).^2)+p);
x1=abs(x-xc(j))<c*t(i)*3;
y1=abs(y-yc(j))<c*t(i)*3;
% 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(F,l)
n=200;
% 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;
c=hypot(hypot(x,y),z)+randn(n+1)*.03;
H(1)=surf(x*F,y*F,(.8+(-l(1,-1,n+1)'.^4)*.3).*z*F,c,FaceC=[1,.4,.1],EdgeC='n');
% Stem
s=[1.5 1 repelem(.7, 6)].*[repmat([.1 .06],1,round(n/20)) .1]';
[t,p]=meshgrid(0:pi/15:pi/2,l(0,pi,round(n/10)+1));
H(2)=surf(repmat(-(.4-cos(p).*s).*cos(t)+.4,2,1)*F,[-sin(p).*s;sin(p).*s]*F,repmat((.5-cos(p).*s).*sin(t)+.55,2,1)*F,FaceC='#008000',EdgeC='n');
P=hgtransform;
set(H,'Pa',P);
end