我正在编写一个宏来在 tikz 中生成维吉尼亚方块。它是一个正方形加上一个与其重叠的十字,突出显示了更改的字母。代码如下。
%\documentclass{beamer}
%\usetheme{Berkeley}
\documentclass{standalone}
\let\Tiny\tiny
\usepackage{tikz}
\newcommand{\vigenerecross}[2]{%
\begin{tikzpicture}[scale=0.4,transform shape]
\foreach \i in {0,...,25} {
\foreach \j in {0,...,25} {
\edef\k{\ifnum\numexpr\i+\j\relax>25
\the\numexpr\i+\j-26\relax
\else
\the\numexpr\i+\j\relax
\fi}
\ifnum\i=\numexpr`#2-`A\relax
\ifnum\j=\numexpr`#1-`A\relax
\node[draw, color=green, fill=red, minimum size=0.6cm,inner sep=0pt] at (\i*0.6,-\j*0.6) {\color{black}\strut\symbol{\numexpr`A+\k\relax}};
\else
\node[draw, color=green, fill=red!20!white, minimum size=0.6cm,inner sep=0pt] at (\i*0.6,-\j*0.6) {\color{black}\strut\symbol{\numexpr`A+\k\relax}};
\fi
\else
\ifnum\j=\numexpr`#1-`A\relax
\node[draw, color=green, fill=red!20!white, minimum size=0.6cm,inner sep=0pt] at (\i*0.6,-\j*0.6) {\color{black}\strut\symbol{\numexpr`A+\k\relax}};
\fi
\fi
}
}
\end{tikzpicture}
}
\newsavebox{\vigeneresquare}
\savebox{\vigeneresquare}{%
\begin{tikzpicture}[scale=0.4,transform shape]
\foreach \i in {0,...,25} {
\foreach \j in {0,...,25} {
\edef\k{\ifnum\numexpr\i+\j\relax>25
\the\numexpr\i+\j-26\relax
\else
\the\numexpr\i+\j\relax
\fi}
\node[draw, minimum size=0.6cm,inner sep=0pt] at (\i*0.6,-\j*0.6) {\color{black}\strut\symbol{\numexpr`A+\k\relax}};
}
}
\end{tikzpicture}
}
\newcommand{\vigenere}[2]{{\usebox{\vigeneresquare}\llap{\vigenerecross{#1}{#2}}}}
\begin{document}
\vigenere{M}{L}
\end{document}
它运行良好,但如果我将其插入到 beamer 文件中(只需取消注释前两行并注释第三行),则输出是错误的:重叠的交叉有点小并且不同步。
为什么会发生这种情况?如何解决?
附言:我使用了这个有点奇怪的想法,而不是直接在方块内突出显示相关字母,因为如果我多次使用它来制作一种加密过程的动画,那么这样编译起来就会更快。
答案1
经过反复尝试,我最终解决了我的问题。
如果有人能感兴趣的话,我会发布解决方案(至少是我已经解决的解决方案)。
正确运行的代码如下:
%\documentclass{beamer}
%\usetheme{Berkeley}
\documentclass{standalone}
\let\Tiny\tiny
\usepackage{tikz}
\newcommand{\vigenerecross}[2]{
\begin{tikzpicture}[scale=0.2,transform shape]
\foreach \i in {0,...,25} {
\foreach \j in {0,...,25} {
\edef\k{\ifnum\numexpr\i+\j\relax>25
\the\numexpr\i+\j-26\relax
\else
\the\numexpr\i+\j\relax
\fi}
\ifnum\i=\numexpr`#2-`A\relax
\ifnum\j=\numexpr`#1-`A\relax
\node[draw, color=green, fill=red, minimum size=0.9cm,inner sep=0pt] at (\i*0.9,-\j*0.9) {\normalsize\color{black}\symbol{\numexpr`A+\k\relax}};
\else
\node[draw, color=green, fill=red!20!white, minimum size=0.9cm,inner sep=0pt] at (\i*0.9,-\j*0.9) {\normalsize\color{black}\symbol{\numexpr`A+\k\relax}};
\fi
\else
\ifnum\j=\numexpr`#1-`A\relax
\node[draw, color=green, fill=red!20!white, minimum size=0.9cm,inner sep=0pt] at (\i*0.9,-\j*0.9) {\normalsize\color{black}\symbol{\numexpr`A+\k\relax}};
\fi
\fi
}
}
\end{tikzpicture}%
}
\newsavebox{\vigeneresquare}
\savebox{\vigeneresquare}{
\begin{tikzpicture}[scale=0.2,transform shape]
\foreach \i in {0,...,25} {
\foreach \j in {0,...,25} {
\edef\k{\ifnum\numexpr\i+\j\relax>25
\the\numexpr\i+\j-26\relax
\else
\the\numexpr\i+\j\relax
\fi}
\node[draw, minimum size=0.9cm,inner sep=0pt] at (\i*0.9,-\j*0.9) {\normalsize\color{black}\symbol{\numexpr`A+\k\relax}};
}
}
\end{tikzpicture}%
}
\newcommand{\vigenere}[2]{{\usebox{\vigeneresquare}\llap{\vigenerecross{#1}{#2}}}}
\begin{document}
\vigenere{F}{G}
\end{document}
评论:
- 通过在后面添加 % 来消除十字的移位
\end{tikzpicture}
(我仍然不明白为什么,但就是这样) - 每个框内的字母都正确居中移除
\strut
(这听起来很合理) size=0.9cm
提供更好的比例并修复不正确的水平线(这听起来也很合理)\normalsize
确保字母在正方形和十字形中具有相同的尺寸,而没有它的 beamer 类则不是这种情况(我猜这是因为正方形是\savebox
在序言中保存的,而十字形是在文档内部动态计算的,我假设字体使用了一些不同的设置)