如何在 TikZ 中使用 \newcommand 创建自定义形状并移动它们

如何在 TikZ 中使用 \newcommand 创建自定义形状并移动它们

我尝试创建树状结构,用于基本算术,以便学生学习计算。这些树应该如下图所示,只是有更多的层级(用于计算多个计算)。

在此处输入图片描述

为了方便起见,我想用 3 个正方形(用于两个加数和解)和一个带运算符的圆圈来定义单个元素。所以我定义了一个命令,它应该给我这个基本元素。

\documentclass[12pt]{article}
\usepackage{tikz}
\usetikzlibrary{tikzmark}
\usetikzlibrary{intersections}
\usetikzlibrary{shapes.geometric}
\usetikzlibrary{3d}
\usetikzlibrary{arrows}
\usetikzlibrary{calc}

\newcommand{\tree}[4]{
\draw[shift=(#1)] (-1,1.75) rectangle node{\footnotesize #2} (-.5,2.25);
\draw[shift=(#1)] (1,1.75) rectangle node{\footnotesize #3} (1.5,2.25);

\draw[shift=(#1)] (-.75,1.75)--(-.75,1.25)--(.05,1.25);
\draw[shift=(#1)] (1.25,1.75)--(1.25,1.25)--(.45,1.25);
\draw[shift=(#1)] (0.25,1.25) circle  (.2);
\draw[shift=(#1)] (.25,1.25)--+(2pt,0pt)--+(-2pt,0pt);
\draw[shift=(#1)] (.25,1.05)--(.25,.75);

\draw[shift=(#1)] (0,.25) rectangle node{\footnotesize #4} (.5,.75);
}

\begin{document}
    \begin{tikzpicture}
        \tree{0,0}{100}{54}{8}
    \end{tikzpicture}
\end{document}

但是上面的代码一直在编译,没有给出任何错误。有没有一种简单的方法来定义一个预先构造的 TikZpicture,可以直接插入到另一个图形中?

问候覆膜机

答案1

测试该示例时我确实遇到错误。

无论如何,请注意,a 和 similar 的选项\draw是逗号分隔的条目列表,因此如果 a对<value>中的<key>=<value>包含逗号,则需要使用<key>={<value>},否则解析器会感到困惑。因此,使用shift={(#1)}和 您的示例可以按预期工作。

无论如何,还有其他一些建议:

scope

您可以使用环境稍微简化一下代码scope

\newcommand{\tree}[4]{
\begin{scope}[shift={(#1)}]
\draw ...
\end{scope}
}

减少手工绘图

您不需要使用明确的坐标来绘制所有内容,而是可以将节点彼此相对放置,并向draw节点添加绘制其边框的选项。

\documentclass[12pt]{article}
\usepackage{tikz}
\usetikzlibrary{positioning}
\newcommand{\tree}[4]{
\begin{scope}[
  shift={(#1)},
  every node/.style={
    draw,
    font=\footnotesize,
    node distance=3mm and 4mm
  }
]
\node  (a) {#4};
\node [circle,inner sep=2pt,above=of a] (op) {$-$};
\node [above left=of op] (b) {#2};
\node [above right=of op] (c) {#3};
\draw (a) -- (op) -| (b)
             (op) -| (c);
\end{scope}
}

\begin{document}
    \begin{tikzpicture}
        \tree{0,0}{100}{54}{8}
    \end{tikzpicture}
\end{document}

pics

TikZ 3.0 引入了这一pic概念,其目的是制作小型、可重复使用的图表。

\documentclass[12pt]{article}
\usepackage{tikz}
\usetikzlibrary{positioning}
\tikzset{
  pics/tree/.style args={#1#2#3}{
  code={
    \begin{scope}[
      every node/.style={
        draw,
        font=\footnotesize,
        node distance=3mm and 4mm
      }
    ] 
    \node  (a) {#3};
    \node [circle,inner sep=2pt,above=of a] (op) {$-$};
    \node [above left=of op] (b) {#1};
    \node [above right=of op] (c) {#2};
    \draw (a) -- (op) -| (b)
                 (op) -| (c);
    \end{scope}
       }
  }
}

\begin{document}
    \begin{tikzpicture}
        \pic at (0,0) {tree={100}{54}{8}};
    \end{tikzpicture}
\end{document}

答案2

\pic概念的小变化Torbjørn T.回答:

在此处输入图片描述

\documentclass[12pt, tikz, margin=3mm]{standalone}
\usetikzlibrary{arrows.meta,
                calc,
                positioning,
                quotes}

\tikzset{node distance = 7mm,
TBbox/.style = {draw, minimum width=12mm, minimum height=5mm,
                inner sep=1mm, outer sep=0mm},
TBsum/.style = {circle, draw, minimum size=5mm, inner sep=0mm, font=\Large},
pics/TBB/.style n args  % Tree Building Block
             = {4}{code={
    \node (@tbb-1) [TBbox]    {#1};
    \node (@tbb-2) [TBbox, right=6mm of @tbb-1] {#2};
    \node (@tbb-3) [TBsum, below=1mm of $(@tbb-1.south)!0.5!(@tbb-2.south)$] {$#3$};
    \node (@tbb-4) [TBbox, below=3mm of @tbb-3] {#4};
    \coordinate    (-in1)  at (@tbb-1.north);
    \coordinate    (-in2)  at (@tbb-2.north);
    \coordinate    (-out)  at (@tbb-4.south);
    \draw[gray,->]   (@tbb-1) |- (@tbb-3);
    \draw[gray,->]   (@tbb-2) |- (@tbb-3);
    \draw[gray,->]   (@tbb-3) -- (@tbb-4);
                        }% end of code
                    },% end of style
every edge quotes/.style = {font=\footnotesize, inner sep=1mm, auto}
        }% endof tikzset

\begin{document}
    \begin{tikzpicture}
\pic (a) at (0,0) {TBB={100}    % input 1
                       {54}     % input 2
                       {-}      % math operation
                       {8}      % result
                   };
\pic (b) [below=of a-out] {TBB={8}{2}{+}{10}};
    \draw[->]   (a-out) to ["copy"] (b-in1);
\pic (c) [below=of b-out] {TBB={10}{2}{\times}{\textbf{20}}};
    \draw[->]   (b-out) to ["copy"]  (c-in1);
    \end{tikzpicture}
\end{document}

答案3

如果您正在构建树,为什么不使用forest

\documentclass[margin=2pt]{standalone}
\usepackage{forest}

\begin{document}
\begin{forest}
result/.style={
        draw, 
        minimum width=1cm,
        minimum height=6mm,
    },
data/.style={
        result, 
        edge path=\noexpand\path[\forestoption{edge}]
            (!u.parent anchor)-|(.child anchor)
            \forestoption{edge label};
    },
sign/.style={
    circle,
    minimum size=5mm,
    inner sep=2pt,
    draw
    },
for tree={grow'=90, 
    draw, 
    },
[9, result 
    [+, sign  
        [5, data
            [5, result, edge={<-} [+, sign [2, data][3,data]]]
        ]
        [4, data,
            [4, result, edge={<-} [-, sign [6, data][2,data]]]
        ]
    ]
]
\end{forest}
\end{document}

在此处输入图片描述

相关内容