Animación tikz compleja con proyector.

Animación tikz compleja con proyector.

Estoy usando tikz para crear una especie de animación de cifrado Ceasar con proyector.

Puedo conseguir lo que quiero pero, como no soy muy hábil con tikz, el resultado es un poco raro porque es muy lento de compilar: esto es un gran inconveniente porque dentro de un documento grande con muchos de ellos se ralentiza muchísimo.

Mi código es el siguiente (bueno, un pequeño ejemplo práctico)

\documentclass{beamer}
\usetheme{Berkeley}
\usepackage{graphicx}
\usepackage{ifthen}
\usepackage{tikz}
\tikzset{
  invisible/.style={opacity=0},
  visible on/.style={alt={#1{}{invisible}}},
  alt/.code args={<#1>#2#3}{\alt<#1>{\pgfkeysalso{#2}}{\pgfkeysalso{#3}} 
  },
}
\begin{document}
\begin{frame}
\centering
\begin{tikzpicture}[scale=0.3, every node/.style={scale=0.3}]
 \pgfmathsetmacro{\alphsize}{26}
 \pgfmathsetmacro{\ang}{360/\alphsize}
 \pgfmathsetmacro{\d}{3}
 \pgfmathsetmacro{\op}{98 + \ang/2 - 1.2}
 \pgfmathsetmacro{\e}{\ang + \ang*\d}
 \pgfmathsetmacro{\ep}{\op + \ang*\d}
 \foreach \x in {0,\ang,...,360} {\draw[gray] (\x:8em) -- (\x:12em);}
 \foreach \x [count=\xi] in {A,...,Z} {
  \node[rotate=\ang - \ang*\xi,visible on=<1>]  at (\op - \ang*\xi:11em)     {{\Large \x}};   
  \node[rotate=\ang - \ang*\xi,visible on=<2>]  at (\op - \ang*\xi:11em) {\ifthenelse{\equal{\x}{T}}{\color{green}\Large \x}{\Large \x}};   
  \node[rotate=\ang - \ang*\xi,visible on=<3>]  at (\op - \ang*\xi:11em) {\ifthenelse{\equal{\x}{E}}{\color{green}\Large \x}{\Large \x}};   
  \node[rotate=\ang - \ang*\xi,visible on=<4>]  at (\op - \ang*\xi:11em) {\ifthenelse{\equal{\x}{L}}{\color{green}\Large \x}{\Large \x}};   
  \node[rotate=\ang - \ang*\xi,visible on=<5>]  at (\op - \ang*\xi:11em) {\ifthenelse{\equal{\x}{E}}{\color{green}\Large \x}{\Large \x}};   
  \node[rotate=\ang - \ang*\xi,visible on=<6>]  at (\op - \ang*\xi:11em) {\ifthenelse{\equal{\x}{P}}{\color{green}\Large \x}{\Large \x}};   
  \node[rotate=\ang - \ang*\xi,visible on=<7>]  at (\op - \ang*\xi:11em) {\ifthenelse{\equal{\x}{H}}{\color{green}\Large \x}{\Large \x}};   
  \node[rotate=\ang - \ang*\xi,visible on=<8>]  at (\op - \ang*\xi:11em) {\ifthenelse{\equal{\x}{O}}{\color{green}\Large \x}{\Large \x}};   
  \node[rotate=\ang - \ang*\xi,visible on=<9>]  at (\op - \ang*\xi:11em) {\ifthenelse{\equal{\x}{N}}{\color{green}\Large \x}{\Large \x}};   
  \node[rotate=\ang - \ang*\xi,visible on=<10>] at (\op - \ang*\xi:11em) {\ifthenelse{\equal{\x}{E}}{\color{green}\Large \x}{\Large \x}};   
  \node[rotate=\e - \ang*\xi,visible on=<1>]  at (\ep - \ang*\xi:9em) {{\large \x}};     
  \node[rotate=\e - \ang*\xi,visible on=<2>]  at (\ep - \ang*\xi:9em) {\ifthenelse{\equal{\x}{W}}{\color{red}\large \x}{\large \x}};     
  \node[rotate=\e - \ang*\xi,visible on=<3>]  at (\ep - \ang*\xi:9em) {\ifthenelse{\equal{\x}{H}}{\color{red}\large \x}{\large \x}};     
  \node[rotate=\e - \ang*\xi,visible on=<4>]  at (\ep - \ang*\xi:9em) {\ifthenelse{\equal{\x}{O}}{\color{red}\large \x}{\large \x}};     
  \node[rotate=\e - \ang*\xi,visible on=<5>]  at (\ep - \ang*\xi:9em) {\ifthenelse{\equal{\x}{H}}{\color{red}\large \x}{\large \x}};     
  \node[rotate=\e - \ang*\xi,visible on=<6>]  at (\ep - \ang*\xi:9em) {\ifthenelse{\equal{\x}{S}}{\color{red}\large \x}{\large \x}};     
  \node[rotate=\e - \ang*\xi,visible on=<7>]  at (\ep - \ang*\xi:9em) {\ifthenelse{\equal{\x}{K}}{\color{red}\large \x}{\large \x}};     
  \node[rotate=\e - \ang*\xi,visible on=<8>]  at (\ep - \ang*\xi:9em) {\ifthenelse{\equal{\x}{R}}{\color{red}\large \x}{\large \x}};     
  \node[rotate=\e - \ang*\xi,visible on=<9>]  at (\ep - \ang*\xi:9em) {\ifthenelse{\equal{\x}{Q}}{\color{red}\large \x}{\large \x}};     
  \node[rotate=\e - \ang*\xi,visible on=<10>] at (\ep - \ang*\xi:9em) {\ifthenelse{\equal{\x}{H}}{\color{red}\large \x}{\large \x}};     
}
 \draw[thick] (0cm,0cm) circle(12em);
 \draw[gray] (0cm,0cm) circle(10em);
 \draw[thick] (0cm,0cm) circle(8em);
\end{tikzpicture} 

\bigskip

\centering
\begin{tikzpicture}[every node/.style={scale=0.6}]
  \draw[step=1em,gray,thin] (0em,0em) grid (9em,2em);
  \node at (0.5em,1.5em) {\textcolor<2> {green}T};
  \node at (1.5em,1.5em) {\textcolor<3> {green}E};
  \node at (2.5em,1.5em) {\textcolor<4> {green}L};
  \node at (3.5em,1.5em) {\textcolor<5> {green}E};
  \node at (4.5em,1.5em) {\textcolor<6> {green}P};
  \node at (5.5em,1.5em) {\textcolor<7> {green}H};
  \node at (6.5em,1.5em) {\textcolor<8> {green}O};
  \node at (7.5em,1.5em) {\textcolor<9> {green}N};
  \node at (8.5em,1.5em) {\textcolor<10>{green}E};
  \node[visible on=<2->]  at (0.5em,0.5em) {\textcolor<2> {red}W};
  \node[visible on=<3->]  at (1.5em,0.5em) {\textcolor<3> {red}H};
  \node[visible on=<4->]  at (2.5em,0.5em) {\textcolor<4> {red}O};
  \node[visible on=<5->]  at (3.5em,0.5em) {\textcolor<5> {red}H};
  \node[visible on=<6->]  at (4.5em,0.5em) {\textcolor<6> {red}S};
  \node[visible on=<7->]  at (5.5em,0.5em) {\textcolor<7> {red}K};
  \node[visible on=<8->]  at (6.5em,0.5em) {\textcolor<8> {red}R};
  \node[visible on=<9->]  at (7.5em,0.5em) {\textcolor<9> {red}Q};
  \node[visible on=<10->] at (8.5em,0.5em) {\textcolor<10>{red}H};
\end{tikzpicture}

\end{frame}
\end{document}

La pregunta es: ¿existe una forma más inteligente de obtener el mismo resultado anterior que se compilará más rápido?

Respuesta1

No veo ningún problema importante que pueda ralentizar significativamente su código. Dado que recompilar una gran cantidad de imágenes complejas de TikZ puede resultar muy molesto, existe una biblioteca externalque obliga a TikZ a guardar y, si es posible, reutilizar las imágenes. Esto se hace de la siguiente manera.

\usetikzlibrary{external}
\tikzexternalize

Editar: Como sugiere @brad en los comentarios, puede resultar ventajoso utilizar \tikzexternalize[prefix=tikz/], para configurar una carpeta para las imágenes temporales de TikZ.

Dado que está utilizando la \onlyconstrucción del proyector, esto no funciona como se esperaba, solo se representa el primer fotograma. Sin embargo, existe un "truco":

Envuelve todo el tikzpictureentorno por \only<m-M>donde mesta elmínimoy Mes elmáximonúmero de fotograma al que hacen referencia los \onlycomandosdentrola imagen tikz.

Dado que la [visible on=<m-M>]opción es "equivalente" al \onlycomando, puedes usarla así.

\only<1-10>{%
\begin{tikzpicture}
    \node[visible on=<1>] {};
    % ...
    \node[visible on=<10>] {};
\end{tikzpicture}
}

He probado esto para su código y los tiempos de compilación segundo (y posteriores) sonmuchomás bajo.

VerUtilice la función externa de tikz con el proyector \solamentepara más información.

El código completo:

\documentclass{beamer}
\usetheme{Berkeley}
\usepackage{graphicx}
\usepackage{ifthen}
\usepackage{tikz}
\tikzset{
  invisible/.style={opacity=0},
  visible on/.style={alt={#1{}{invisible}}},
  alt/.code args={<#1>#2#3}{\alt<#1>{\pgfkeysalso{#2}}{\pgfkeysalso{#3}} 
  },
}

\usetikzlibrary{external}
\tikzexternalize

\begin{document}
\begin{frame}
\centering
\only<1-10>{%
\begin{tikzpicture}[scale=0.3, every node/.style={scale=0.3}]
 \pgfmathsetmacro{\alphsize}{26}
 \pgfmathsetmacro{\ang}{360/\alphsize}
 \pgfmathsetmacro{\d}{3}
 \pgfmathsetmacro{\op}{98 + \ang/2 - 1.2}
 \pgfmathsetmacro{\e}{\ang + \ang*\d}
 \pgfmathsetmacro{\ep}{\op + \ang*\d}
 \foreach \x in {0,\ang,...,360} {\draw[gray] (\x:8em) -- (\x:12em);}
 \foreach \x [count=\xi] in {A,...,Z} {
  \node[rotate=\ang - \ang*\xi,visible on=<1>]  at (\op - \ang*\xi:11em)     {{\Large \x}};   
  \node[rotate=\ang - \ang*\xi,visible on=<2>]  at (\op - \ang*\xi:11em) {\ifthenelse{\equal{\x}{T}}{\color{green}\Large \x}{\Large \x}};   
  \node[rotate=\ang - \ang*\xi,visible on=<3>]  at (\op - \ang*\xi:11em) {\ifthenelse{\equal{\x}{E}}{\color{green}\Large \x}{\Large \x}};   
  \node[rotate=\ang - \ang*\xi,visible on=<4>]  at (\op - \ang*\xi:11em) {\ifthenelse{\equal{\x}{L}}{\color{green}\Large \x}{\Large \x}};   
  \node[rotate=\ang - \ang*\xi,visible on=<5>]  at (\op - \ang*\xi:11em) {\ifthenelse{\equal{\x}{E}}{\color{green}\Large \x}{\Large \x}};   
  \node[rotate=\ang - \ang*\xi,visible on=<6>]  at (\op - \ang*\xi:11em) {\ifthenelse{\equal{\x}{P}}{\color{green}\Large \x}{\Large \x}};   
  \node[rotate=\ang - \ang*\xi,visible on=<7>]  at (\op - \ang*\xi:11em) {\ifthenelse{\equal{\x}{H}}{\color{green}\Large \x}{\Large \x}};   
  \node[rotate=\ang - \ang*\xi,visible on=<8>]  at (\op - \ang*\xi:11em) {\ifthenelse{\equal{\x}{O}}{\color{green}\Large \x}{\Large \x}};   
  \node[rotate=\ang - \ang*\xi,visible on=<9>]  at (\op - \ang*\xi:11em) {\ifthenelse{\equal{\x}{N}}{\color{green}\Large \x}{\Large \x}};   
  \node[rotate=\ang - \ang*\xi,visible on=<10>] at (\op - \ang*\xi:11em) {\ifthenelse{\equal{\x}{E}}{\color{green}\Large \x}{\Large \x}};   
  \node[rotate=\e - \ang*\xi,visible on=<1>]  at (\ep - \ang*\xi:9em) {{\large \x}};     
  \node[rotate=\e - \ang*\xi,visible on=<2>]  at (\ep - \ang*\xi:9em) {\ifthenelse{\equal{\x}{W}}{\color{red}\large \x}{\large \x}};     
  \node[rotate=\e - \ang*\xi,visible on=<3>]  at (\ep - \ang*\xi:9em) {\ifthenelse{\equal{\x}{H}}{\color{red}\large \x}{\large \x}};     
  \node[rotate=\e - \ang*\xi,visible on=<4>]  at (\ep - \ang*\xi:9em) {\ifthenelse{\equal{\x}{O}}{\color{red}\large \x}{\large \x}};     
  \node[rotate=\e - \ang*\xi,visible on=<5>]  at (\ep - \ang*\xi:9em) {\ifthenelse{\equal{\x}{H}}{\color{red}\large \x}{\large \x}};     
  \node[rotate=\e - \ang*\xi,visible on=<6>]  at (\ep - \ang*\xi:9em) {\ifthenelse{\equal{\x}{S}}{\color{red}\large \x}{\large \x}};     
  \node[rotate=\e - \ang*\xi,visible on=<7>]  at (\ep - \ang*\xi:9em) {\ifthenelse{\equal{\x}{K}}{\color{red}\large \x}{\large \x}};     
  \node[rotate=\e - \ang*\xi,visible on=<8>]  at (\ep - \ang*\xi:9em) {\ifthenelse{\equal{\x}{R}}{\color{red}\large \x}{\large \x}};     
  \node[rotate=\e - \ang*\xi,visible on=<9>]  at (\ep - \ang*\xi:9em) {\ifthenelse{\equal{\x}{Q}}{\color{red}\large \x}{\large \x}};     
  \node[rotate=\e - \ang*\xi,visible on=<10>] at (\ep - \ang*\xi:9em) {\ifthenelse{\equal{\x}{H}}{\color{red}\large \x}{\large \x}};     
}
 \draw[thick] (0cm,0cm) circle(12em);
 \draw[gray] (0cm,0cm) circle(10em);
 \draw[thick] (0cm,0cm) circle(8em);
\end{tikzpicture} 
}
\bigskip

\centering
\only<1-10>{%
\begin{tikzpicture}[every node/.style={scale=0.6}]
  \draw[step=1em,gray,thin] (0em,0em) grid (9em,2em);
  \node at (0.5em,1.5em) {\textcolor<2> {green}T};
  \node at (1.5em,1.5em) {\textcolor<3> {green}E};
  \node at (2.5em,1.5em) {\textcolor<4> {green}L};
  \node at (3.5em,1.5em) {\textcolor<5> {green}E};
  \node at (4.5em,1.5em) {\textcolor<6> {green}P};
  \node at (5.5em,1.5em) {\textcolor<7> {green}H};
  \node at (6.5em,1.5em) {\textcolor<8> {green}O};
  \node at (7.5em,1.5em) {\textcolor<9> {green}N};
  \node at (8.5em,1.5em) {\textcolor<10>{green}E};
  \node[visible on=<2->]  at (0.5em,0.5em) {\textcolor<2> {red}W};
  \node[visible on=<3->]  at (1.5em,0.5em) {\textcolor<3> {red}H};
  \node[visible on=<4->]  at (2.5em,0.5em) {\textcolor<4> {red}O};
  \node[visible on=<5->]  at (3.5em,0.5em) {\textcolor<5> {red}H};
  \node[visible on=<6->]  at (4.5em,0.5em) {\textcolor<6> {red}S};
  \node[visible on=<7->]  at (5.5em,0.5em) {\textcolor<7> {red}K};
  \node[visible on=<8->]  at (6.5em,0.5em) {\textcolor<8> {red}R};
  \node[visible on=<9->]  at (7.5em,0.5em) {\textcolor<9> {red}Q};
  \node[visible on=<10->] at (8.5em,0.5em) {\textcolor<10>{red}H};
\end{tikzpicture}
}
\end{frame}
\end{document}

información relacionada