第1部分

第1部分

我正在尝试结合两个想法并通过包将 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;animate2020-04-25 起的版本;luamplib2020-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 部分

这是我最后一次尝试在luamplibMetapost 的帮助下将第二部分放在 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}

相关内容