图片之谜仍在继续

图片之谜仍在继续

关于图片之谜的讨论已经很多了如何给 \pic 命名如何给 \pic 命名(第二部分)。这里还有一个问题/观察,可能与此有关,也可能与此无关。回答时节点中 tikzpictures 中移位边缘标签并排,中间带有箭头local bounding boxTorbjørn T. 的回答。所以我尝试将它与 pic 语法结合起来,使整个图片像节点一样可引用。(是的,我知道path pictures,但我看到将它们用于此目的时出现的问题是,据我所知,在添加所有元素之前我会知道这个东西的大小。)我尝试将其合并到 的定义中pic

\documentclass[tikz,border=3.14mm]{standalone}
\begin{document}
\tikzset{vertex/.style={circle, minimum size=4pt, inner sep=0pt, fill=orange}}
\tikzset{mygraph/.pic={\xdef\myname{\pgfkeysvalueof{/tikz/name prefix}}
        \typeout{\myname}
            \begin{scope}[font=\footnotesize, thick,local bounding box=\myname]
                \node[vertex] (root)    at (4,  5) {};
                \node[vertex] (o)       at (4,  4) {};
                \node[vertex] (oc)      at (4,  3) {};
                \node[vertex] (oco)     at (4,  2) {};
                \node[vertex] (a)       at (5,  4) {};

                \foreach \xfrom/\xto/\xlabel in {
                    root/o/o, o/oc/c, oc/oco/o,
                    root/a/a} {
                    \draw (\xfrom) to node[pos=0.5,fill=white]{\xlabel} (\xto);
                };
            \end{scope}
        }
    }

    \begin{tikzpicture}
        \pic (graph1) at (0,0) {mygraph};
        \pic (graph2) at (3,0) {mygraph};
    \draw[-latex] (graph1) to (graph2);
    % just for fun 
    \draw[-latex,shorten >=1mm,shorten <=1mm] (graph1a) to[out=-10,in=160] (graph2root);
    \end{tikzpicture}
\end{document}

在此处输入图片描述

如您所见,箭头从其结束处开始。另一方面,我天真地期望输出与我将范围放在 之外的代码生成的输出相同pic

\documentclass[tikz,border=3.14mm]{standalone}
\begin{document}
\tikzset{vertex/.style={circle, minimum size=4pt, inner sep=0pt, fill=orange}}
\tikzset{mygraph/.pic={\begin{scope}[font=\footnotesize, thick]
                \node[vertex] (root)    at (4,  5) {};
                \node[vertex] (o)       at (4,  4) {};
                \node[vertex] (oc)      at (4,  3) {};
                \node[vertex] (oco)     at (4,  2) {};
                \node[vertex] (a)       at (5,  4) {};

                \foreach \xfrom/\xto/\xlabel in {
                    root/o/o, o/oc/c, oc/oco/o,
                    root/a/a} {
                    \draw (\xfrom) to node[pos=0.5,fill=white]{\xlabel} (\xto);
                };
            \end{scope}
        }
    }

    \begin{tikzpicture}
      \begin{scope}[local bounding box=graph1]
        \pic (graph1) at (0,0) {mygraph};
      \end{scope}
      \begin{scope}[local bounding box=graph2]
        \pic (graph2) at (3,0) {mygraph};
      \end{scope}
    \draw[-latex] (graph1) to (graph2);
    % just for fun 
    \draw[-latex,shorten >=1mm,shorten <=1mm] (graph1a) to[out=-10,in=160] (graph2root);
    \end{tikzpicture}
\end{document}

在此处输入图片描述

问题):为什么会这样?如何解决?

答案1

我认为这是一个时间问题,因为宏的全局定义\myname。结果是两个局部边界框都相同,即第二个。

可以通过扩展\myname可选参数来修复此问题scope

\begingroup
\edef\x{\endgroup
  \noexpand\begin{scope}[
    font=\noexpand\footnotesize,
    thick,
    local bounding box=\myname,
  ]
}\x

完整示例:

\documentclass[tikz,border=3.14mm]{standalone}
\begin{document}
\tikzset{
  vertex/.style={
    circle,
    minimum size=4pt,
    inner sep=0pt,
    fill=orange,
  },
  mygraph/.pic={%
    \xdef\myname{\pgfkeysvalueof{/tikz/name prefix}}
    \typeout{\myname}
    \begingroup
    \edef\x{\endgroup
      \noexpand\begin{scope}[
        font=\noexpand\footnotesize,
        thick,
        local bounding box=\myname,
      ]
    }\x
      \node[vertex] (root)    at (4,  5) {};
      \node[vertex] (o)       at (4,  4) {};
      \node[vertex] (oc)      at (4,  3) {};
      \node[vertex] (oco)     at (4,  2) {};
      \node[vertex] (a)       at (5,  4) {};

      \draw
        \foreach \xfrom/\xto/\xlabel in {root/o/o, o/oc/c, oc/oco/o, root/a/a} {
          (\xfrom) to node[pos=0.5,fill=white]{\xlabel} (\xto)
        }
      ;
    \end{scope}
  }
}

\begin{tikzpicture}
  \pic (graph1) at (0,0) {mygraph};
  \pic (graph2) at (3,0) {mygraph};
  \draw[-latex] (graph1) to (graph2);
  % just for fun
  \draw[-latex,shorten >=1mm,shorten <=1mm]
    (graph1a) to[out=-10,in=160] (graph2root)
  ;
  % more fun
  \draw[red] (graph1.south west) rectangle (graph1.north east);
  \draw[blue] (graph2.south west) rectangle (graph2.north east);
\end{tikzpicture}
\end{document}

结果

顺便说一句,从透明背景可以看出,线中间带有白色背景的节点看起来不太好,尤其是倾斜线的截断线端。

可以通过以下方法修复:

  \draw
    \foreach \xfrom/\xto/\xlabel in {root/o/o, o/oc/c, oc/oco/o, root/a/a} {
      ($(\xfrom)!.5!(\xto)$) node (tmp) {\xlabel}
      (\xfrom) -- (tmp) (tmp) -- (\xto)
    }

完整示例:

\documentclass[tikz,border=3.14mm]{standalone}
\usetikzlibrary{calc}
\begin{document}
\tikzset{
  vertex/.style={
    circle,
    minimum size=4pt,
    inner sep=0pt,
    fill=orange,
  },
  mygraph/.pic={%
    \xdef\myname{\pgfkeysvalueof{/tikz/name prefix}}
    \typeout{\myname}
    \begingroup
    \edef\x{\endgroup
      \noexpand\begin{scope}[
        font=\noexpand\footnotesize,
        thick,
        local bounding box=\myname,
      ]
    }\x
      \node[vertex] (root)    at (4,  5) {};
      \node[vertex] (o)       at (4,  4) {};
      \node[vertex] (oc)      at (4,  3) {};
      \node[vertex] (oco)     at (4,  2) {};
      \node[vertex] (a)       at (5,  4) {};

      \draw
        \foreach \xfrom/\xto/\xlabel in {root/o/o, o/oc/c, oc/oco/o, root/a/a} {
          ($(\xfrom)!.5!(\xto)$) node (tmp) {\xlabel}
          (\xfrom) -- (tmp) (tmp) -- (\xto)
        }
      ;
    \end{scope}
  }
}

\begin{tikzpicture}
  \pic (graph1) at (0,0) {mygraph};
  \pic (graph2) at (3,0) {mygraph};
  \draw[-latex] (graph1) to (graph2);
  % just for fun
  \draw[-latex,shorten >=1mm,shorten <=1mm]
    (graph1a) to[out=-10,in=160] (graph2root)
  ;
  % more fun
  \draw[red] (graph1.south west) rectangle (graph1.north east);
  \draw[blue] (graph2.south west) rectangle (graph2.north east);
\end{tikzpicture}
\end{document}

精炼结果

相关内容