我正在尝试结合两个想法并通过包将 Metapost 代码放入 TeX 中luampcode
:
TeX 内部的工作动画(下面是第 1 部分):https://melusine.eu.org/syracuse/luatex/luamplibAnimate/
以及 TeX 之外的工作动画(下面的第 2 部分):https://melusine.eu.org/syracuse/metapost/animations/mehats/?swf=anim.swf
Xubuntu 18.04;TeXLive 2020;LuaLaTeX 1.12.0;MetaPost 2.00;animate
2020-04-25 起的版本;luamplib
2020-02-24 起的 v2.20.5。
第1部分
后
lualatex mplibanimate.tex
lualatex mplibanimate.tex
该代码按预期工作:
% mplibanimate.tex
\documentclass{article}
\usepackage{animate}
\usepackage{luamplib}
\begin{document}
\mplibcodeinherit{enable} % pour permettre la mémoire entre les
% biginfig(i) produites
\newcommand{\lemniscate}[1]{% #1: l'angle en degres
\begin{mplibcode}
if(#1=0):
u:=4cm;%
a:=2u;%
h:=a/4;%
s:=1.3;%
path lemn;%
path carre;%
carre = (0,0)--(1,0)--(1,1)--(0,1)--cycle;
fi;
beginfig(#1);
pickup pencircle scaled 0.6pt;
drawarrow (0,-s*u)--(0,s*u);
drawarrow (-s*u,0)--(s*u,0);
path cercle,hori,verti;
pair O,P,Q,R,M;
O:=(0,0);
cercle := fullcircle scaled (a);
pickup pencircle scaled 0.4pt;
draw cercle dashed evenly withcolor blue;
P:=(a/2*cosd(#1),a/2*sind(#1)); % chemin qui parcourt le cercle
Q:=(a/2*cosd(#1),0); %projection sur (Ox)
% projection de Q sur [O,P]
R = cosd(#1)*cosd(#1)*(a/2*cosd(#1),a/2*sind(#1));
% M sur [PQ] tel que QM = QR
QR := abs(R-Q);
if(sind(#1)>0.0):
M = Q + (0,QR);
else:
M = Q - (0,QR);
fi;
if #1=0:
lemn:=M;
else:
lemn:= lemn--M;
fi;
if ((#1>0) and (#1<90)) or ((#1>180) and (#1<270)):
draw carre scaled 6 rotated (angle(Q-P)+180) shifted Q;
draw carre scaled 6 rotated (angle(R-P)) shifted R;
fi;
if((#1>=90) and (#1<180)) or ((#1>=270) and (#1<360)):
draw carre scaled 6 rotated (angle(Q-P)+180) shifted Q;
draw carre scaled 6 rotated (angle(R-P)+180) shifted R;
fi;
draw O--P dashed evenly withcolor blue;
draw P--Q dashed evenly withcolor blue;
draw R--Q--M withcolor green;
label.lrt(btex $a$ etex, (a/2,0));
label.llft(btex $x$ etex, (s*u,0));
label.llft(btex $y$ etex, (0,s*u));
label(btex \itshape Lemniscate \par de Gerono etex, (-0.7u,1.15u));
label(btex $x^4=a^2(x^2-y^2)$ etex, (0.7u,-1.15u));
dotlabel.llft(btex $O$ etex, O);
dotlabel.urt(btex $M$ etex, M);
dotlabel.urt(btex $P$ etex, P);
dotlabel.urt(btex $Q$ etex, Q);
dotlabel.urt(btex $R$ etex, R);
pickup pencircle scaled 1pt;
draw lemn withcolor red;
clip currentpicture to (-s*u,-s*u)--(s*u,-s*u)--(s*u,s*u)--(-s*u,s*u)--cycle;
endfig;
\end{mplibcode}
}
\begin{center}
\begin{animateinline}[poster=last, controls]{24}
%
\multiframe{360}{i=0+1}{\lemniscate{\i}}
\end{animateinline}
\end{center}
Le PDF produit est à télécharger dans la liste plus haut.
\end{document}
第2部分
后
mpost anim.mp
lualatex anim-together.tex
lualatex anim-together.tex
这也很好用:
% anim.mp
%@AUTEUR: Laurent Méhats
%@DATE: 30 décembre 2012
% Pangramme panaccentué conçu par Gilles Esposito-Farèse, mentionné
% dans les « Petites leçons de typographie » de Jacques André :
% http://jacques-andre.fr/faqtypo/lessons.pdf
% --%<-- script.sh
% mpost anim.mp
% mptopdf anim-*.mps
% pdfjoin anim-*-mps.pdf -o anim.pdf
% pdf2swf anim.pdf -o temp.swf
% swfcombine -dz -r 25 temp.swf -o anim.swf
% --%<-- script.sh
filenametemplate "%j-%3c.mps";
verbatimtex%&latex
\documentclass{article}
\usepackage[utf8]{inputenc}
\usepackage{fourier}
\usepackage[T1]{fontenc}
\begin{document}
etex;
% text material and glyphs contours
picture tex_pct, glp_pct;
numeric glp_num, pth_num[];
path glp_pth[][];
% tex_pct btex .. etex material
% glp_num number of glyphs within tex_pct
% pth_num[i] number of paths defining the rank i (0 .. glp_num-1) glyph
% glp_pth[i][j] rank j (0 .. pth_num[i]-1) path of the rank i glyph
% glp_pct glyphs picture
tex_pct:=btex{\begin{minipage}{\textwidth}\begin{center}
Dès Noël où un zéphyr\\
haï me vêt de glaçons\\
würmiens je dîne d'exquis\\
rôtis de b\oe{}uf au kir à l'aÿ\\
d'âge mûr \& cætera !
\end{center}\end{minipage}}etex;
glp_pct:=nullpicture;
string fnt_str, txt_str, sub_str;
numeric txt_wd;
glp_num:=0;
for tkn within tex_pct:
if textual tkn:
fnt_str:=fontpart tkn;
txt_str:=textpart tkn;
txt_wd:=0;
for glp_idx=0 upto (length txt_str-1):
sub_str:=substring (glp_idx, glp_idx+1) of txt_str;
pth_num[glp_num]:=0;
for sub_tkn within glyph ASCII sub_str of fnt_str
scaled (fontsize fnt_str/1000)
xscaled xxpart tkn
yscaled yypart tkn
shifted (txt_wd+xpart tkn, ypart tkn):
glp_pth[glp_num][pth_num[glp_num]]:=pathpart sub_tkn;
addto glp_pct doublepath glp_pth[glp_num][pth_num[glp_num]];
pth_num[glp_num]:=pth_num[glp_num]+1;
endfor
glp_num:=glp_num+1;
txt_wd:=txt_wd+
(xxpart tkn)*xpart urcorner (sub_str infont fnt_str);
endfor
fi
endfor
% background dimensions and foreground transformation
numeric bg_wd, bg_hg;
picture bg_pct;
bg_wd:=640;
bg_hg:=360;
bg_pct:=nullpicture;
addto bg_pct contour origin--(bg_wd, 0)--(bg_wd, bg_hg)--(0, bg_hg)--cycle;
numeric fg_wd, fg_hg;
transform fit_trn;
fg_wd:=xpart(urcorner glp_pct-llcorner glp_pct);
fg_hg:=ypart(urcorner glp_pct-llcorner glp_pct);
fit_trn:=identity
shifted -.5[llcorner glp_pct, urcorner glp_pct]
scaled .9min(bg_wd/fg_wd, bg_hg/fg_hg)
shifted +.5[llcorner bg_pct, urcorner bg_pct];
% drawing options
color bg_clr, fg_clr;
pen fg_pen;
numeric dot_scl;
bg_clr:=black;
fg_clr:=white;
fg_pen:=pencircle scaled 2;
dot_scl:=4;
% animation
numeric duration, fps, f_num;
duration:=10;
fps:=25;
f_num:=fps*duration;
for idx=0 upto (f_num/2-1):
beginfig(idx)
draw bg_pct withcolor bg_clr;
drawoptions (withcolor fg_clr);
for i=0 upto glp_num-1:
for j=0 upto pth_num[i]-1:
path pth; numeric tim;
pth:=glp_pth[i][j] transformed fit_trn;
tim:=arctime 2(arclength pth)/f_num*idx of pth;
draw subpath (0, tim) of pth withpen fg_pen;
draw point (tim) of pth withpen fg_pen scaled dot_scl;
endfor
endfor
drawoptions ();
endfig;
endfor
for idx=0 upto (f_num/2-1):
beginfig(f_num/2+idx)
draw bg_pct withcolor bg_clr;
drawoptions (withcolor fg_clr);
for i=0 upto glp_num-1:
for j=0 upto pth_num[i]-1:
path pth; numeric tim;
pth:=glp_pth[i][j] transformed fit_trn;
tim:=arctime 2(arclength pth)/f_num*idx of pth;
draw subpath (tim, length pth) of pth withpen fg_pen;
draw point (tim) of pth withpen fg_pen scaled dot_scl;
endfor
endfor
drawoptions ();
endfig;
endfor
end
加
% anim-together.tex
\documentclass{standalone}
\usepackage[controls]{animate}
\usepackage{graphicx}
\begin{document}
\animategraphics{10}{anim-}{000}{249}
\end{document}
第 3 部分
这是我最后一次尝试在luamplib
Metapost 的帮助下将第二部分放在 TeX 文件中,并包含mps
文件。我运行
lualatex together-animation.tex
lualatex together-animation.tex
看起来我的btex ... etex
和都textext("...")
没有生成图片。因此,变量glp_pct
变空,导致fg_wd
长度fg_hg
为零,之后此代码片段中出现除以零的错误bg_wd/fg_wd, bg_hg/fg_hg
。
% together-animation.tex
\documentclass{article}
\usepackage{animate} %,xcolor
\usepackage{luamplib}
\begin{document}
\mplibtextextlabel{enable}
\mplibcodeinherit{enable}
\mpliblegacybehavior{disable}
%\mplibglobaltextext{enable}
%\mplibverbatim{disable}
\newcommand{\lemniscate}[1]{%
\begin{mplibcode}
%filenametemplate "%j-%3c.mps"; % malipivo, not needed
verbatimtex%&latex
\documentclass{article}
\usepackage[utf8]{inputenc}
\usepackage{fourier}
\usepackage[T1]{fontenc}
\begin{document}
etex;
picture tex_pct, glp_pct;
numeric glp_num, pth_num[];
path glp_pth[][];
% original block of code
%tex_pct:=btex{\begin{minipage}{\textwidth}\begin{center}
%Dès Noël où un zéphyr\\
%haï me vêt de glaçons\\
%würmiens je dîne d'exquis\\
%rôtis de b\oe{}uf au kir à l'aÿ\\
%d'âge mûr \& cætera !
%\end{center}\end{minipage}}etex;
tex_pct:=textext("\begin{minipage}{\textwidth}\begin{center}
Dès Noël où un zéphyr\\
haï me vêt de glaçons\\
würmiens je dîne d'exquis\\
rôtis de b\oe{}uf au kir à l'aÿ\\
d'âge mûr \& cætera !
\end{center}\end{minipage}");
tex_pct:=btex abc etex; % malipivo, minimal try
%tex_pct:=textext("abc"); % malipivo, try
label(tex_pct, (0,0));
glp_pct:=nullpicture;
string fnt_str, txt_str, sub_str;
numeric txt_wd;
glp_num:=0;
for tkn within tex_pct:
if textual tkn:
fnt_str:=fontpart tkn;
txt_str:=textpart tkn;
txt_wd:=0;
for glp_idx=0 upto (length txt_str-1):
sub_str:=substring (glp_idx, glp_idx+1) of txt_str;
pth_num[glp_num]:=0;
for sub_tkn within glyph ASCII sub_str of fnt_str
scaled (fontsize fnt_str/1000)
xscaled xxpart tkn
yscaled yypart tkn
shifted (txt_wd+xpart tkn, ypart tkn):
glp_pth[glp_num][pth_num[glp_num]]:=pathpart sub_tkn;
addto glp_pct doublepath glp_pth[glp_num][pth_num[glp_num]];
pth_num[glp_num]:=pth_num[glp_num]+1;
endfor
glp_num:=glp_num+1;
txt_wd:=txt_wd+
(xxpart tkn)*xpart urcorner (sub_str infont fnt_str);
endfor
fi
endfor
% background dimensions and foreground transformation
numeric bg_wd, bg_hg;
picture bg_pct;
bg_wd:=320; % 1280
bg_hg:=180; % 720
bg_pct:=nullpicture;
%addto glp_pct contour origin--(1, 1)--cycle; % malipivo
addto glp_pct contour fullcircle scaled 1mm withcolor red; % malipivo
addto bg_pct contour origin--(bg_wd, 0)--(bg_wd, bg_hg)--(0, bg_hg)--cycle withcolor blue;
numeric fg_wd, fg_hg;
transform fit_trn;
fg_wd:=xpart(urcorner glp_pct-llcorner glp_pct);
fg_hg:=ypart(urcorner glp_pct-llcorner glp_pct);
fit_trn:=identity
shifted -.5[llcorner glp_pct, urcorner glp_pct]
scaled .9min(bg_wd/fg_wd, bg_hg/fg_hg)
shifted +.5[llcorner bg_pct, urcorner bg_pct];
% drawing options
color bg_clr, fg_clr;
pen fg_pen;
numeric dot_scl;
bg_clr:=green;
fg_clr:=white;
fg_pen:=pencircle scaled 2;
dot_scl:=4;
% animation
numeric duration, fps, f_num;
duration:=10;
fps:=25;
f_num:=fps*duration;
numeric idx;
idx:=#1; % malipivo
%for idx=0 upto (f_num/2-1): % malipivo removed
%if(#1=idx): % malipivo try
beginfig(idx) % idx
draw bg_pct withcolor bg_clr;
drawoptions (withcolor fg_clr);
draw (0,0)--(200,10) withcolor red; % malipivo, some minimum drawing
for i=0 upto glp_num-1:
for j=0 upto pth_num[i]-1:
path pth; numeric tim;
pth:=glp_pth[i][j] transformed fit_trn;
tim:=arctime 2(arclength pth)/f_num*idx of pth;
draw subpath (0, tim) of pth withpen fg_pen;
draw point (tim) of pth withpen fg_pen scaled dot_scl;
endfor
endfor
drawoptions ();
endfig;
%fi; % malipivo try
%endfor % malipivo removed
%end. % malipivo, not needed
\end{mplibcode}
}
\begin{center}
\begin{animateinline}[poster=last,controls]{1}
%
%a \newframe b % the animate package works if tested
\multiframe{5}{i=0+1}{left\lemniscate{\i}right}
% from 5 to 124 (initial value in the code, 250/2-1)
%\lemniscate{0}
\end{animateinline}
\end{center}
\end{document}