我想做的事
我想绘制分组密码操作模式的图表,例如这个ECB 模式。我以前这样做过,但没有为图表的特定部分定义形状。但是,这次我想正确地做到这一点,并为 XOR 运算和明文、密文和 IV 的块定义形状。
对于 XOR 运算这个问题之前已经问过。但是,我需要定义一个新的形状,即明文、密文和 IV 的块。
我的方法
我现在的方法是基于矩形形状定义一个新形状,并使用 for 循环在矩形内绘制 9 条均匀分布的垂直线。这样,矩形内就会产生 10 个大小相同的隔间。为此,我计算了两条垂直线之间的距离。然后,我从保存的锚点开始north.east
,在计算出的距离内绘制 9 条垂直线。我在以下 MWE 中执行了此操作:
\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{calc}
\makeatletter
\pgfdeclareshape{block}
{
\inheritsavedanchors[from=rectangle] % this is a rectanble
\inheritanchorborder[from=rectangle]
\inheritanchor[from=rectangle]{north}
\inheritanchor[from=rectangle]{north west}
\inheritanchor[from=rectangle]{north east}
\inheritanchor[from=rectangle]{center}
\inheritanchor[from=rectangle]{west}
\inheritanchor[from=rectangle]{east}
\inheritanchor[from=rectangle]{mid}
\inheritanchor[from=rectangle]{mid west}
\inheritanchor[from=rectangle]{mid east}
\inheritanchor[from=rectangle]{base}
\inheritanchor[from=rectangle]{base west}
\inheritanchor[from=rectangle]{base east}
\inheritanchor[from=rectangle]{south}
\inheritanchor[from=rectangle]{south west}
\inheritanchor[from=rectangle]{south east}
\inheritbackgroundpath[from=rectangle]
\foregroundpath{
\setlength{\pgf@ya}{\pgfshapeminheight}
\setlength{\pgf@xa}{\pgfshapeminwidth}
\pgfmathsetlength\pgfutil@tempdima{\pgf@xa / 10}
\pgfpathmoveto{\northeast}
\foreach \i in {1,...,9}
{%
\pgfpathmoveto{\pgfpointadd{\pgfpoint{\pgf@x}{\pgf@y}}{\pgfpoint{-\pgfutil@tempdima}{0pt}}}
\pgfpathlineto{\pgfpointadd{\pgfpoint{\pgf@x}{\pgf@y}}{\pgfpoint{0pt}{-2\pgf@ya}}}
}
}
}
\makeatother
\begin{document}
\tikzset{blockstyle/.style={draw, minimum width = 4cm, minimum height = 0.4cm, shape=block}}
\begin{tikzpicture}
\node[blockstyle] (p1) at (0.1cm,0.1cm) {};
\node[above] at (p1.north) {Plaintext 1};x
\end{tikzpicture}
\end{document}
问题
在 处绘制一个块(0,0)
可以正常工作,但是一旦在另一个位置绘制一个块,垂直线的绘制就会与矩形外绘制的线条混淆,如下图所示:
因此我的问题是:绘制线条的计算有什么问题?
编辑似乎问题发生在节点未放置在 时(0,0)
。这可能是问题根源的线索。我采用了 MWE 和相应的文本。
答案1
我把循环改得更明确一些,这似乎有效。你说的对\pgfpathmoveto{\northeast}
。我还给形状和节点样式赋予了不同的名称。(我还要提一下,你也可以使用pic
s 和local bounding box
)。
\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{calc}
\makeatletter
\pgfdeclareshape{fblock}
{
\inheritsavedanchors[from=rectangle] % this is a rectanble
\inheritanchorborder[from=rectangle]
\inheritanchor[from=rectangle]{north}
\inheritanchor[from=rectangle]{north west}
\inheritanchor[from=rectangle]{north east}
\inheritanchor[from=rectangle]{center}
\inheritanchor[from=rectangle]{west}
\inheritanchor[from=rectangle]{east}
\inheritanchor[from=rectangle]{mid}
\inheritanchor[from=rectangle]{mid west}
\inheritanchor[from=rectangle]{mid east}
\inheritanchor[from=rectangle]{base}
\inheritanchor[from=rectangle]{base west}
\inheritanchor[from=rectangle]{base east}
\inheritanchor[from=rectangle]{south}
\inheritanchor[from=rectangle]{south west}
\inheritanchor[from=rectangle]{south east}
\inheritbackgroundpath[from=rectangle]
\foregroundpath{
\setlength{\pgf@ya}{\pgfshapeminheight}
\setlength{\pgf@xa}{\pgfshapeminwidth}
\pgfmathsetlength\pgfutil@tempdima{\pgf@xa / 10}
\foreach \i in {1,...,9}
{
\pgfpathmoveto{\pgfpointadd{\northeast}{\pgfpoint{-\i*\pgfutil@tempdima}{0pt}}}
\pgfpathlineto{\pgfpointadd{\northeast}{\pgfpoint{-\i*\pgfutil@tempdima}{-2\pgf@ya}}}
}
}
}
\makeatother
\begin{document}
\tikzset{block/.style={draw, minimum width = 4cm, minimum height = 0.4cm,
shape=fblock}}
\begin{tikzpicture}%[every block/.style={draw}]
\node[block] (p1) at (0,0) {};
\node[above] at (p1.north) {Plaintext 1};
\node[block, left=1.5cm] (iv) at (p1.west) {};
\end{tikzpicture}
\end{document}