Skip to content

Commit d914186

Browse files
authored
Try these examples in MATLAB to create animations!
1 parent a91f1e8 commit d914186

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

62 files changed

+6786
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
animateFrames();
2+
function animateFrames()
3+
animFilename = 'A_Pythagorean_Treehouse.gif'; % Output file name
4+
firstFrame = true;
5+
framesPerSecond = 24;
6+
delayTime = 1/framesPerSecond;
7+
8+
% Create the gif
9+
for frame = 1:48
10+
drawframe(frame);
11+
fig = gcf();
12+
fig.Units = 'pixels';
13+
fig.Position(3:4) = [300,300];
14+
im = getframe(fig);
15+
[A,map] = rgb2ind(im.cdata,256);
16+
17+
if firstFrame
18+
firstFrame = false;
19+
imwrite(A,map,animFilename, 'LoopCount', Inf, 'DelayTime', delayTime);
20+
else
21+
imwrite(A,map,animFilename, 'WriteMode', 'append', 'DelayTime', delayTime);
22+
end
23+
end
24+
end
25+
function drawframe(f)
26+
theta = interp1([0 48],[0 pi/2],f);
27+
28+
clf
29+
hgt = hgtransform(Parent=gca);
30+
31+
c = 1;
32+
maxdepth = 6;
33+
pythag_seg(hgt,c,theta,maxdepth);
34+
35+
x = c*[0 0 1 1];
36+
y = c*[0 1 1 0];
37+
cmap = parula(maxdepth+1);
38+
p = patch(x,y,cmap(1,:));
39+
40+
axis equal
41+
axis([-4 4.5 0 7.5])
42+
axis off
43+
set(gcf,Color='white')
44+
45+
end
46+
47+
function pythag_seg(hgtp,c,theta,maxdepth,depth)
48+
49+
if nargin < 5
50+
depth = 1;
51+
end
52+
53+
depth = depth + 1;
54+
if depth > maxdepth
55+
return
56+
end
57+
58+
hgtc1 = hgtransform(Parent=hgtp);
59+
hgtc2 = hgtransform(Parent=hgtp);
60+
61+
x = c*[0 0 1 1];
62+
y = c*[0 1 1 0];
63+
64+
cmap = parula(maxdepth+1);
65+
color = cmap(depth+1,:);
66+
patch(x,y,color,EdgeColor='black',Parent=hgtc1);
67+
patch(x,y,color,EdgeColor='black',Parent=hgtc2);
68+
69+
a = c*cos(theta);
70+
b = c*sin(theta);
71+
72+
Txy = makehgtform('translate',0,c,0);
73+
Rz = makehgtform('zrotate',theta);
74+
S = makehgtform('scale',a/c);
75+
set(hgtc1,Matrix=Txy*Rz*S);
76+
77+
Txy = makehgtform('translate',a*cos(theta),c+a*sin(theta),0);
78+
Rz = makehgtform('zrotate',theta-pi/2);
79+
S = makehgtform('scale',b/c);
80+
set(hgtc2,Matrix=Txy*Rz*S);
81+
82+
pythag_seg(hgtc1,c,theta,maxdepth,depth)
83+
pythag_seg(hgtc2,c,theta,maxdepth,depth)
84+
85+
end
86+
87+
88+
89+
90+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,188 @@
1+
animateFrames();
2+
function animateFrames()
3+
animFilename = 'Around_the_Word.gif'; % Output file name
4+
firstFrame = true;
5+
framesPerSecond = 24;
6+
delayTime = 1/framesPerSecond;
7+
8+
% Create the gif
9+
for frame = 1:48
10+
drawframe(frame);
11+
fig = gcf();
12+
fig.Units = 'pixels';
13+
fig.Position(3:4) = [300,300];
14+
im = getframe(fig);
15+
[A,map] = rgb2ind(im.cdata,256);
16+
17+
if firstFrame
18+
firstFrame = false;
19+
imwrite(A,map,animFilename, 'LoopCount', Inf, 'DelayTime', delayTime);
20+
else
21+
imwrite(A,map,animFilename, 'WriteMode', 'append', 'DelayTime', delayTime);
22+
end
23+
end
24+
end
25+
function drawframe(f)
26+
% Rotation
27+
rx=f/48*pi;
28+
29+
% Shorteners
30+
q=@triangulation;
31+
j=@polyshape;
32+
K='KeepCollinearPoints';
33+
34+
% Transforms
35+
persistent WX EX
36+
37+
if f==1
38+
%% WORD SHAPE
39+
% Basic idea - draw a word using a text object in a wide
40+
% figure, screen-cap it, then contourit.
41+
f=figure('Color','w','Vis','of','Pos',[ 100 100 3000 300 ]);
42+
ax=axes(f,'Vis','off');
43+
t=text(ax,15,15,'MATLAB','Units','pixel',...
44+
'FontSize',30,'FontWeight','bold','FontUnits','Pix',...
45+
'VerticalA','baseline');
46+
F=getframe(ax,t.Extent);
47+
close(f)
48+
V=contourc(double(flipud(F.cdata(:,:,1))),[50 50])';
49+
% Convert contour matrix into polyshape verts
50+
idx=1;
51+
while idx<size(V,1)
52+
n=V(idx,2);
53+
V(idx,:)=nan;
54+
idx=idx+1+n;
55+
end
56+
% Center and scale to unit height
57+
V=(V-min(V))/max(V,[],'all');
58+
% Convert to polyshape so we get a clean triangulation
59+
W1=j(V(2:end,:),K,true);
60+
W1=XP(W1.polybuffer(.006));
61+
62+
%% Create the WordSphere
63+
64+
% Constants
65+
R1=1.3; % radius of inner/outer part of sphere.
66+
R2=1.5;
67+
SP=.8; % Span of the word
68+
69+
T=q(W1);
70+
71+
% Aspects of the triangulation.
72+
V=T.Points; % Get improved V
73+
F=T.ConnectivityList;
74+
E=T.freeBoundary;
75+
76+
% Constants for this shape when computing connecting edges
77+
R=1:size(E,1); % All the boundary edges.
78+
L2=size(V,1); % Layer 2 starts here.
79+
80+
% New triangulation faces
81+
NF=[F; F+L2; % top and bottom
82+
E(R,[2 1 2])+[0 0 L2]; % edges connecting top/bottom
83+
E(R,[1 1 2])+[0 L2 L2];
84+
];
85+
86+
x=max(V);
87+
T=V(:,1)/x(1)*SP; % Stretch around part of theta
88+
89+
zV=(V(:,2)-x(2)/2);
90+
P=zV*.2/R1/max(zV);
91+
92+
%% Cheap Earth (do this before patches due to newplot)
93+
axes(CreateFcn='earthmap');
94+
EX=hgtransform;
95+
set(findobj('type','surface'),'parent',EX);
96+
97+
%% Word Sphere (or 2 half spheres)
98+
WX=hgtransform;
99+
for o=[0 1]
100+
V2=[cospi(T+o).*cospi(P),sinpi(T+o).*cospi(P),sinpi(P)];
101+
102+
WT=q(NF,[V2.*[R1 R1 1]
103+
V2.*[R2 R2 1]]);
104+
105+
patch(WX,'Vertices',WT.Points,'Faces',WT.ConnectivityList,...
106+
'FaceC','#0076a8','FaceA',1,'FaceL','n',...
107+
'FaceVertexCData',[T;T],...
108+
'EdgeC','n');
109+
110+
patch(WX,'Vertices',WT.Points,'Faces',WT.featureEdges(pi/4.5),...
111+
'FaceVertexCData',[],'FaceC','none','EdgeC','#fff00f','LineW',1);
112+
end
113+
clim(clim);
114+
115+
% Prettify
116+
set(gcf,'Color','k');
117+
daspect([1 1 1]);
118+
view([220 5])
119+
axis([-1.5 1.5 -1.5 1.5 -1.1 1.1],'off')
120+
camzoom(1.7)
121+
end
122+
123+
WX.Matrix=makehgtform('zrotate',-rx+pi/3);
124+
EX.Matrix=makehgtform('zrotate',rx*2);
125+
126+
%% HELPER FCNS
127+
% The below fcns add verticies into a polyshape so that the resolution along
128+
% long edges is high enough so we can bend those edges around the sphere.
129+
function ps=XP(psIn)
130+
% Make all long straight edges in the polyshape be made of many short
131+
% segments.
132+
133+
% Get the regions
134+
r=regions(psIn);
135+
% New polyshape should keep all the extra pts we'll be adding.
136+
ps=j();
137+
% Loop over all the regions
138+
139+
for i=1:numel(r)
140+
[x,y]=boundary(r(i),1); % Exclude all the holes in this region
141+
ps=union(ps,XE(x,y),K,true);
142+
end
143+
144+
% Get the holes in those regions
145+
h=holes(psIn);
146+
147+
% Loop over all the holes
148+
for i=1:numel(h)
149+
[x,y]=boundary(h(i),1);
150+
ps=subtract(ps,XE(x,y),K,true);
151+
end
152+
end
153+
154+
function ps=XE(x,y)
155+
% Expand the edges for one polyregion
156+
if x(end)==x(1) && y(end)==y(1)
157+
inp=[x y];
158+
else
159+
inp=[x(end) y(end)% This is a loop, re-add the end
160+
x y];
161+
end
162+
163+
P=[];
164+
for i=2:size(inp,1)
165+
d=norm(inp(i-1,:)-inp(i,:));% distance between adjacent pts
166+
n=max(2,floor(150*d));% n pts to increase it to
167+
if n==2
168+
P=[P%#ok
169+
inp(i-1,:)];
170+
else
171+
%disp expand
172+
xe=linspace(inp(i-1,1),inp(i,1),n)'; % interp
173+
ye=linspace(inp(i-1,2),inp(i,2),n)';
174+
% Add all but last pt to avoid dups
175+
P=[P;%#ok
176+
xe(1:end-1) ye(1:end-1)];
177+
end
178+
end
179+
180+
ps=j(P,K,true);
181+
end
182+
183+
end
184+
185+
186+
187+
188+
+49
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
animateFrames();
2+
function animateFrames()
3+
animFilename = 'Blender.gif'; % Output file name
4+
firstFrame = true;
5+
framesPerSecond = 24;
6+
delayTime = 1/framesPerSecond;
7+
8+
% Create the gif
9+
for frame = 1:48
10+
drawframe(frame);
11+
fig = gcf();
12+
fig.Units = 'pixels';
13+
fig.Position(3:4) = [300,300];
14+
im = getframe(fig);
15+
[A,map] = rgb2ind(im.cdata,256);
16+
17+
if firstFrame
18+
firstFrame = false;
19+
imwrite(A,map,animFilename, 'LoopCount', Inf, 'DelayTime', delayTime);
20+
else
21+
imwrite(A,map,animFilename, 'WriteMode', 'append', 'DelayTime', delayTime);
22+
end
23+
end
24+
end
25+
function drawframe(f)
26+
c=(sqrt(5)+1)/2;
27+
d=2*pi/c;
28+
alpha = interp1([0 48],[0 48*2*pi/12],f);
29+
theta = (1:600)*d;
30+
r = sqrt(theta);
31+
32+
theta = theta + alpha;
33+
34+
x = r.*cos(theta);
35+
y = r.*sin(theta);
36+
37+
sz = 30*(1-(1:numel(x))/numel(x)) + 1;
38+
clr = sz;
39+
scatter(x,y,sz,clr,"filled")
40+
axis equal off
41+
axis(45*[-1 1 -1 1])
42+
set(gcf,Color=0.3*[1 1 1])
43+
44+
end
45+
46+
47+
48+
49+

0 commit comments

Comments
 (0)