[metapost] Animated graphics with Metapost?

Troy Henderson thenders at gmail.com
Sat Jun 11 19:24:00 CEST 2011


Martin,

I generated this SWF a while back using MetaPost.

http://www.tlhiv.org/tmp/ellipse.swf

Basically, I drew each frame of the animation programmatically (as
previously suggested).  The key to making the animations work like you
expect them to is (as suggested) to have the BoundingBox of each frame
be the same.  You can do this explicitly in MetaPost by the command

setbounds currentpicture to p;

where p is a path (I would assume preferably a rectangular path).

Once this is done, you can include each of these MPS/EPS files into a
LaTeX document and create a single PDF in which each page is exactly
the size it should be and contain a single graphic.  I will provide
the code for this at the end of this message.

You can then convert this PDF to SWF using SWFtools by

pdf2swf foo.pdf foo.swf

The only thing you might want to do after converting to this SWF is to
change the delay between frames.  This can be accomplished by (again
with SWFtools)

swfcombine -dr <fps> foo.swf -o bar.swf

where <fps> is the number of frames per second you want in the animation.

Below is the code for the aforementioned ellipse.  It creates a LaTeX
file automatically, but you have to execute PDFLaTeX on the file
followed by the pdf2swf and swfcombine commands (which it tells you to
do in the MetaPost output).

Troy

----

c:=2/(1+sqrt(5)); % Ratio of "y-radius" to "x-radius" (should be positive)
N:=64; % Number of frames in the animation
T:=4; % Approximate time (in seconds) to complete an animation cycle
u:=136; % Maximum height/width of ellipse (in PostScript points)

pair f;
if c<1: f:=(1+-+c,0); v:=u/2; else: f:=(0,1+-+(1/c)); v:=u/c/2; fi; %
Focus f is defined
path p,q;
picture base;
beginfig(0);
	p:=fullcircle yscaled c; % This is the ellipse
	draw p scaled (2*v) withpen pencircle scaled (v/260) dashed evenly; %
Draw the ellipse dashed (will be traced later)
	input mp-tool;
	q:=bbox currentpicture enlarged (v/64); % Enlarge the bounding box slightly
	fill fullcircle scaled (v/32) shifted (f*v) withcolor red; % Focus
	fill fullcircle scaled (v/32) shifted (-f*v) withcolor red; % Focus
	base:=currentpicture; % Save this picture to draw in every frame
	setbounds currentpicture to q; % Set the bounding box as described before
endfig;
W:=ceiling(xpart urcorner q - xpart llcorner q)+1; % The width to pass to LaTeX
H:=ceiling(ypart urcorner q - ypart llcorner q)+1; % The height to pass to LaTeX

write "\documentclass{minimal}" to jobname & ".ltx";
write "\usepackage[paperwidth=" & decimal(W) & "bp,paperheight=" &
decimal(H) & "bp,margin=0bp,noheadfoot]{geometry}" to jobname &
".ltx";
write "\usepackage{graphicx}" to jobname & ".ltx";
write "\usepackage{ifpdf}\ifpdf\DeclareGraphicsRule{*}{mps}{*}{}\fi"
to jobname & ".ltx";
write "\usepackage[pdfstartview=Fit,bookmarks=false]{hyperref}" to
jobname & ".ltx";
write "\begin{document}" to jobname & ".ltx";
write "\noindent\includegraphics{" & jobname & ".0}\clearpage" to
jobname & ".ltx";

L:=length p; % Length (in "time") of the ellipse curve
pair z;
for n=1 upto (N-1): % Generate each frame of the animation
	beginfig(n);
		fill q withcolor 0.99*white;
		draw base; % Draw the common picture saved above
		draw subpath (0,(n-1)/(N-1)*L) of p scaled (2*v) withpen pencircle
scaled (v/130) withcolor blue; % Trace the ellipse in blue
		z:=point ((n-1)/(N-1)*L) of p scaled v; % The point on the ellipse
where we are thusfar
		fill fullcircle scaled (v/32) shifted (2*z) withcolor blue; % Draw the point
		draw (-f*v)--(2*z)--(f*v) withpen pencircle scaled (v/260); % Draw
the string used to trace the ellipse
		setbounds currentpicture to q; % Set the bounding box so that it is
the same for each frame
	endfig;
	write "\noindent\includegraphics{" & jobname & "." & decimal(n) &
"}\clearpage" to jobname & ".ltx"; % Update LaTeX file
endfor;
write "\end{document}" to jobname & ".ltx"; % Finish up the LaTeX file

message " ";
message "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%";
message "Execute the following commands to generate the animation:";
message " ";
message "pdflatex " & jobname & ".ltx";
message "pdf2swf " & jobname & ".pdf";
message "swfcombine -dr " & decimal(max(min(ceiling(N/T),255),1/255))
& " " & jobname & ".swf -o " & jobname & ".swf";
message " ";
message "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%";
message " ";

end
-------------- next part --------------
A non-text attachment was scrubbed...
Name: ellipse.mp
Type: application/octet-stream
Size: 3681 bytes
Desc: not available
URL: <http://tug.org/pipermail/metapost/attachments/20110611/7af9a770/attachment.obj>


More information about the metapost mailing list