• Remix
  • Share
  • New Entry

on 29 Oct 2024
  • 53
  • 341
  • 1
  • 10
  • 1810
Huge shout out to Tomoaki Takagi and his entry for the idea of utilizing the audio for images.
This version has more function, better code, and less characters.
Get your Matworks cube at mathworksmerch.com for the low-low price of $10.00!
function drawframe(f)
clf
%% Movement sequence, MS
% (1,:) Which axis x, y, z, or (pause p) to rotate around
% (2,:) Which row to rotate 1, 2, 3, or 4 for all. Any character if pause.
% (3,:) Which direction to rotate, n if negative direction, p for positive
% Change to alter moves made. The function tries to fit all moves within 4s
% If timing issues arise all moves are executed and then a pause untill the
% time runs out
MS=['zxzpyxzpzxyy';'444021303124';'npn0ppp0nnnp'];
%% Set figure window properties
figure(1)
lim = [-1,1]*2.4;
hold on
xlim(lim);
ylim(lim);
zlim(lim);
axis off
pbaspect([1,1,1])
view(45+180*f/96,30);
%% Timing and frame variables
% Frames per move, FPM
FPM=floor(96/size(MS,2));
AngSpd=90/FPM;
%Pause for remaining time if timing issues arise
if f>FPM*size(MS,2)
f=FPM*size(MS,2);
end
%% Get Textures encoded in audio
y=audioread("audio.wav");
y=reshape(y,[],1);
% Texture size, s
s=28;
n=s*s*3;% Number of elements in image
% Create the textures of each face
for i=1:55
I{i}=reshape(y(n*(i-1)+1:n*i),[s,s,3]);
end
%% Initiate surfaces
S=initCoords(I);
% Verticies
V=cell2mat(cellfun(@(x)reshape([x.XData,x.YData,x.ZData],4,1,3),S,...
UniformOutput=0));
V=permute(V,[3,2,1]);
%Counter to keep track of which move we are performing
c=1;
for frame = 1:f
%% Set the rotation matrix
if MS(3,c)=='n'
dir=-1;
elseif MS(3,c)=='p'
dir=1;
end
% Condition to swap to next move, nm
nm=~mod(AngSpd*frame,90);
switch MS(1,c)
% Rotation matrix, R
% Vertice data in the axis of rotation, D
case 'x'
R=[1,0,0;
0,cosd(dir*AngSpd),-sind(dir*AngSpd);
0,sind(dir*AngSpd),cosd(dir*AngSpd)];
D=V(1,:,:);
case 'y'
R=[cosd(dir*AngSpd),0,sind(dir*AngSpd);
0,1,0;
-sind(dir*AngSpd),0,cosd(dir*AngSpd)];
D=V(2,:,:);
case 'z'
R=[cosd(dir*AngSpd),-sind(dir*AngSpd),0;
sind(dir*AngSpd),cosd(dir*AngSpd),0;
0,0,1];
D=V(3,:,:);
case 'p' %pause
if nm
c=c+1;
end
continue
end
%% Find the indices for the faces to rotate
D=squeeze(D)';
% Index of faces to include in rotation, F
if MS(2,c)=='1'
F=find(sum(D>=.5-10^-5,1)==4);
elseif MS(2,c)=='2'
F=find(sum(D<=.5+10^-5&D>=-.5-10^-5,1)==4);
elseif MS(2,c)=='3'
F=find(sum(D<=-.5+10^-5,1)==4);
elseif MS(2,c)=='4'
F=1:size(S,2);
end
%% Perform the rotation for each of the four vertices in a face
V(:,F,:)=pagemtimes(R,V(:,F,:));
if nm
c=c+1;
end
end
%% Update the surface coordinate data
V=permute(V,[3,2,1]);
% We need to update the data in all nodes or the camera rotation effect
% will not persist, Otherwise i would just have updated the data of
% relevant faces
for i=1:162
S{i}.XData=reshape(V(1:4,i,1),2,2);
S{i}.YData=reshape(V(1:4,i,2),2,2);
S{i}.ZData=reshape(V(1:4,i,3),2,2);
end
%% Draw
drawnow
%% Prevent ears from bleeding
if f==96
%P C1 C2 C3 F2 G2
freq=[0 65.41 130.81 261.63 174.61 196];
y=[];
for i=[2 3 4 1 2 3 4 3 2 3 4 1 2 3 4 6]
y=[y,.5*sin(2*pi*freq(i)*(0:1/(44100):1))];
end
audiowrite('audio.wav',y,44100)
end
end
function [S] = initCoords(I)
% shorthand some matrixes to save some characters
a=[0,0;0,0];
b=[2,3;2,3];
c=[0,0;1,1];
% Unfortunately we need to create every surface by itself if we want to
% texture them individually and not have any morphing geometry during plot
% We loop across:
% The 3 coordinate axes, C
% The 6 planes of the cube, p (inside planes count to not make it hollow)
% The 3 columns on each side of the cube, i
% The 3 rows on each side of the cube, j
t=1;%Counter for selection of textures
v=1;%Counter for keeping track of loop iteration
for C=1:3
for p=0:5
for i=0:2
for j=0:2
d=0;
if p==0||p==5 % First or last plane -> Textures!
T=I{t};
t=t+1;
else
% Plane inside the cube, we texture these black.
% To be able to "select" plane faces easily, we
% separate them slightly from eachother with a delta, d
if mod(p,2)
d=-10^-4;
else
d=+10^-4;
end
T=I{end};
end
pl=round(p/2);
%Determine coordinates based on axis and plane
switch C
case 1 %x
x=a+pl+d;
y=[3,3;2,2]-i;
z=b-j;
case 2 %y
x=c+i;
y=a+pl+d;
z=b-j;
case 3 %z
x=c+i;
y=[1,0;1,0]+j;
z=a+pl+d;
end
% Create, texture, and store the individual surface objects
% Unfortunately we need seperate surfaces as we do not want
% them to stay connected to stationary faces when rotating.
S{v}=surf(x-1.5,y-1.5,z-1.5,T,FaceColor='texturemap');
v=v+1;
end
end
end
end
end
Movie
Audio
Remix Tree