在不同位置调用绘图宏

在不同位置调用绘图宏

我编写了一个宏来在 tikz 中进行一些绘图,我希望能够在任意位置调用它(我认为这些位置称为节点?)

我尝试使用相对定位来编写坐标,但是当我调用它时,我的图表相互重叠。

我不确定我是否误解了节点语法或相对坐标。

\documentclass[a4paper]{article}
\usepackage{tikz} 
\usetikzlibrary{positioning}
    
\newcommand{\Register[1]}{
    \fill [gray] +(0,0) rectangle +(4,1);   
    \fill [pink] +(4,0) rectangle +(8,1);   
    
    \draw [thick]         
        +(0,0) -- +(8,0)  -- +(8,1)  -- +(0,1) -- cycle;
    \draw [thick]         
        +(0,0)  +(4,0) -- +(4,1);
    \draw [thin, dashed]  
        +(0,0)  +(2,0) -- +(2,1)  +(6,0) -- +(6,1); 
    \draw [very thin, dotted]  
        +(0,0)  +(1,0) -- +(1,1)  +(3,0) -- +(3,1)
                +(5,0) -- +(5,1)  +(7,0) -- +(7,1);
                
    \node [above right] at +(0,1) {#1};         
}
    

\begin{document}
\begin{tikzpicture} 
    \node (a) {A};
    \Register[R\textsubscript{1}];
    
    \node [below=of a] {B};
    \Register[R\textsubscript{2}]
\end{tikzpicture}
\end{document}

电流输出

答案1

相对坐标是相对于前一个位置的在当前路径中在路径的开始处,前一个位置始终是 (0,0)。

因此,您必须提供一个参考坐标(命令的新参数)并在每个路径的开头使用它。

\documentclass[tikz]{standalone}
\usepackage{tikz} 
\usetikzlibrary{positioning}

\newcommand\Register[2]{
  \fill [gray] (#1) +(0,0) rectangle +(4,1);   
  \fill [pink] (#1) +(4,0) rectangle +(8,1);   
  \draw [thick]         
  (#1) +(0,0) -- +(8,0)  -- +(8,1)  -- +(0,1) -- cycle;
  \draw [thick]         
  (#1) +(0,0)  +(4,0) -- +(4,1);
  \draw [thin, dashed]  
  (#1) +(0,0)  +(2,0) -- +(2,1)  +(6,0) -- +(6,1); 
  \draw [very thin, dotted]  
  (#1) +(0,0)  +(1,0) -- +(1,1)  +(3,0) -- +(3,1)
  +(5,0) -- +(5,1)  +(7,0) -- +(7,1);
  \path (#1) +(0,1) node [above right] {#2};         
}

\begin{document}
\begin{tikzpicture} 
  \node (a) {A};
  \Register{a}{R\textsubscript{1}};
  
  \node [below=of a] (b) {B};
  \Register{b}{R\textsubscript{2}}
\end{tikzpicture}
\end{document}  

在此处输入图片描述

答案2

这看起来很可怕,但除非你必须旋转节点,否则我会采用这种path picture方法:

  1. 它允许列出框,即

    4/gray, 4/pink
    

    表示四个灰色方块和四个粉色方块。(实际上,它们被绘制为一个矩形,以隐藏一些不幸的渲染伪影。)

  2. 这个长方形的高为register/height,宽为<number of boxes> * register/width

    这使您可以更改节点的大小,而不必将它们硬编码到样式中。

  3. 需要三个循环:

    1. 助手.listdim list评估需要多少个盒子,并minimum width相应地设置节点。
    2. 第一个\foreach步骤是遍历用户给定的列表。
    3. 第二个\foreach绘制垂直线。
      (这\the\numexpr\registerNodeWidth-1\relax使得最后一条落在节点右边界上的线不会被绘制。无论如何它都会在节点的边界下。)
  4. [style/.expand once=\Color]命令\fill允许在列表中使用任意样式,例如

    {
      1/red,
      1/{left color=red, right color=blue!50},
      1/{left color=blue!50, right color=green},
      1/green,
      1/{pattern=crosshatch, pattern color=gray}
    }
    

    当然,也包括你自己的。

  5. 不是label的一部分,当您通过或类似物register node放置节点时将不会被考虑。below=of …

如果您希望寄存器左对齐,那么除了手动执行之外below=of ….south west, anchor=north west,还有其他选项,例如\matrix将所有节点放置在其中anchor=west

代码

\documentclass[tikz, border=5pt, convert]{standalone}
\usetikzlibrary{patterns, shadings, positioning, ext.misc}
\pgfkeys{
  /utils/dim list/.style={
    /utils/exec=\def\registerNodeWidth{0},
    /utils/@dim list/.list={#1}},
  /utils/@dim list/.code args={#1/#2}%
    {\edef\registerNodeWidth{\the\numexpr\registerNodeWidth+#1}}}
\tikzset{
  draw,
  register/width/.initial=1cm, register/height/.initial=1cm,
  register/dotted/.style={dotted}, register/dashed/.style={dashed},
  every register node/.style={draw, thick},
  register node/.value required,
  register node/.style 2 args={
    shape=rectangle, every register node, /utils/dim list={#2},
    minimum width=\registerNodeWidth*\pgfkeysvalueof{/tikz/register/width},
    minimum height=\pgfkeysvalueof{/tikz/register/height},
    path picture={
      \foreach[
        remember=\totalWidth as \lastTotalWidth (initially 0),
        evaluate={\totalWidth=\lastTotalWidth+\Width;}]
        \Width/\Color in {#2}
        \fill[style/.expand once=\Color]
          ([xshift=\lastTotalWidth*\pgfkeysvalueof{/tikz/register/width}]%
            path picture bounding box.south west)
          rectangle ++(\Width*\pgfkeysvalueof{/tikz/register/width},
                              \pgfkeysvalueof{/tikz/register/height});
      \foreach \cnt in {1,...,\the\numexpr\registerNodeWidth-1\relax}
        \draw[every register node,
          /utils/if={mod(\cnt,2)}{register/dotted},
          /utils/if={mod(\cnt,4)==2}{register/dashed}]
         ([xshift=\cnt*\pgfkeysvalueof{/tikz/register/width}]%
           path picture bounding box.south west)
           -- ++ (up:\pgfkeysvalueof{/tikz/register/height});
    },
    label={[anchor=south west]north west:$#1$}}}
\begin{document}
\begin{tikzpicture}
\node             [register node={R_1}{4/gray, 4/pink}]            (A) {};
\node[below=of A] [register node={R_2}{3/gray, 2/pink, 3/magenta}] (B) {};
\node[below=of B] [register node={R_3}{
  1/red,
  1/{left color=red, right color=blue!50},
  1/{left color=blue!50, right color=green},
  1/green,
  1/{pattern=crosshatch, pattern color=gray}
}] (C) {};
\end{tikzpicture}
\end{document}

输出

在此处输入图片描述

相关内容