使用 foreach 语句简化 TikZ 绘图

使用 foreach 语句简化 TikZ 绘图

下面,两个图应该是相同的,但实际上却不一样!

\documentclass[margin=2pt]{standalone}
\usepackage{tikz}
\usetikzlibrary{positioning,fit}
\newcommand{\PL}[3][]{
    \node[thick,circle,draw,minimum size=0.5cm,inner sep=0,outer sep=0,label=left:#3,#1](#2){};
    \draw[thick,#1] (#2.south west) -- (#2.north east);
}
\begin{document}
\begin{tikzpicture}
    \PL{L1}{1}
    \PL[below=0.1 of L1]{L2}{2}
    \PL[below=0.1 of L2]{L3}{3}
    \PL[below=0.1 of L3]{L4}{4}
    \PL[below=0.1 of L4]{L5}{5}
    \PL[below=0.1 of L5]{L6}{6}
    \PL[below=0.1 of L6]{L7}{7}
    \node[fit=(L1)(L7), draw] {};
\end{tikzpicture}
\begin{tikzpicture}
    \PL{L1}{1}
    \foreach \i [evaluate=\i as \j using \i - 1] in {2,...,7} {
        \PL[below=0.1cm of L\j]{L\i}{\i}
    }
    \node[fit=(L1)(L7), draw] {};
\end{tikzpicture}
\end{document}

我该如何修复\foreach语句图?

在此处输入图片描述

答案1

如果不将其求\j值为整数,则会得到类似 的数字1.0,其中.0被解释为东锚点。所以我所做的就是用 替换[evaluate=\i as \j using \i - 1][evaluate=\i as \j using {int(\i - 1)}]得到

\documentclass[margin=2pt]{standalone}
\usepackage{tikz}
\usetikzlibrary{positioning,fit}
\newcommand{\PL}[3][]{
    \node[thick,circle,draw,minimum size=0.5cm,inner sep=0,outer sep=0,label=left:#3,#1](#2){};
    \draw[thick,#1] (#2.south west) -- (#2.north east);
}
\begin{document}
    \begin{tikzpicture}
    \PL{L1}{1}
    \PL[below=0.1 of L1]{L2}{2}
    \PL[below=0.1 of L2]{L3}{3}
    \PL[below=0.1 of L3]{L4}{C}
    \PL[below=0.1 of L4]{L5}{R}
    \PL[below=0.1 of L5]{L6}{RC}
    \PL[below=0.1 of L6]{L7}{RH}
    \node[fit=(L1)(L7), draw] {};
\end{tikzpicture}
\begin{tikzpicture}
    \PL{L1}{1}
    \foreach \i [evaluate=\i as \j using {int(\i - 1)}] in {2,...,7} {
        \PL[below=0.1cm of L\j]{L\i}{\i}
    }
    \node[fit=(L1)(L7), draw] {};
\end{tikzpicture}
\end{document}

在此处输入图片描述

附录:由于@AndréC 添加的答案在我看来与原始问题的要点并不相符,因此我添加了一些与原始问题要点相关的内容以及对 AndréC 的某种回应。

  1. 您可以使用 来避免所有这些问题remember...。当然,您可以附加左图的标签,只需声明\i为计数即可。
  2. 使用路径图来删除节点是一种方法,在我看来,你所做的至少同样好,也可以使用strike out附带的shapes.misc。然而,在我看来,这些都不是问题的核心。

这是一个例子(但是如果我是你,我会保留你删除节点的方式,不过可能使用path picture比 更优雅strike through)。

\documentclass[tikz,border=3.14mm]{standalone}
\usetikzlibrary{positioning,fit,shapes.misc}
\newcommand{\PL}[3][]{
    \node[thick,strike out,
    draw,minimum size=0.35cm,inner sep=0,outer sep=0,#1](#2-inner){};
    \node[draw,circle,inner sep=0,fit=(#2-inner),outer sep=1pt,label=left:#3](#2){};
}
\begin{document}
\begin{tikzpicture}
    \PL{L1}{1}
    \foreach \X [count=\i starting from 2,remember=\i as \j (initially 1)] 
    in {2,3,C,R,RC,RH} {
        \PL[below=0.1cm of L\j]{L\i}{\X}
    }
    \node[fit=(L1)(L7), draw] {};
\end{tikzpicture}
\end{document}

在此处输入图片描述

答案2

没有必要使用LaTeX命令来跟踪节点。您所要做的就是声明 tikz styles。为了绘制对角线,我使用了path picture bounding box3.0.1a 手册第 173 页中描述的概念。

风格

\documentclass[margin=5mm]{standalone}
\usepackage{tikz}
\usetikzlibrary{positioning,fit}
%\newcommand{\PL}[3][]{
%    \node[thick,circle,draw,minimum size=0.5cm,inner sep=0,outer sep=0,label=left:#3,#1](#2){};
%    \draw[thick,#1] (#2.south west) -- (#2.north east);
%}

\begin{document}
%    \begin{tikzpicture}
%    \PL{L1}{1}
%    \PL[below=0.1 of L1]{L2}{2}
%    \PL[below=0.1 of L2]{L3}{3}
%    \PL[below=0.1 of L3]{L4}{4}
%    \PL[below=0.1 of L4]{L5}{5}
%    \PL[below=0.1 of L5]{L6}{6}
%    \PL[below=0.1 of L6]{L7}{7}
%    \node[fit=(L1)(L7), draw] {};
%\end{tikzpicture}

\begin{tikzpicture}
    [slash/.style={
        draw,thick,circle,minimum size=.5cm,
        inner sep =0pt,outer sep=0pt,
        label={left:#1},
        path picture={
            \draw(path picture bounding box.south west)--(path picture bounding box.north east);}
    }]
    \node[slash=1](L1){};
    \foreach \i [evaluate=\i as \j using int(\i - 1)] in {2,...,7} {
        \node[below=0.1 of L\j,slash=\i](L\i){};
    }
    \node[fit=(L1)(L7), draw] {};
\end{tikzpicture}
\end{document}

更新(回答marmot):

@marmot:我很清楚我的回答不是问题的核心。而且那也不是我的观点。

为了进一步简化循环:

\documentclass[margin=5mm]{standalone}
\usepackage{tikz}
\usetikzlibrary{positioning,fit}
\begin{document}

\begin{tikzpicture}
    [slash/.style={
        draw,thick,circle,minimum size=.5cm,
        inner sep =0pt,outer sep=0pt,
        label={left:#1},
        path picture={
            \draw(path picture bounding box.south west)--(path picture bounding box.north east);}
    }]
    \node[slash=1](L1){};
    \foreach \j [count=\i] in {2,...,7} {
        \node[below=0.1 of L\i,slash=\j](L\j){};
    }
    \node[fit=(L1)(L7), draw] {};
\end{tikzpicture}
\end{document}

相关内容