
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 external
que 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 \only
construcción del proyector, esto no funciona como se esperaba, solo se representa el primer fotograma. Sin embargo, existe un "truco":
Envuelve todo el
tikzpicture
entorno por\only<m-M>
dondem
esta elmínimoyM
es elmáximonúmero de fotograma al que hacen referencia los\only
comandosdentrola imagen tikz.
Dado que la [visible on=<m-M>]
opción es "equivalente" al \only
comando, 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}