如何将 Tikz 图片制作成节点?

如何将 Tikz 图片制作成节点?

我正在尝试制作一个力学工作表来教授牛顿二定律!我想要一个拉卡车的发动机。我使用 savebox 保存了发动机和卡车的 tikz 图像,并希望我可以将其存储为命名节点,以便能够“连接”对象。当我尝试通过在节点后插入 eg(A) 来给节点命名时,我收到错误“没有已知的名为 A 的形状”。这意味着我无法连接对象。欢迎提出所有想法!以下是我的 MWE

\documentclass{standalone}

\usepackage{tikz}

\newsavebox\Truck
\sbox\Truck{\begin{tikzpicture}
        %   \draw (0,0)--(10,0);
        \draw [fill=gray!20] (1.75,0.1) rectangle  (4.75,0.75);
        \draw [fill=gray] (2,0.15) circle (0.15) (2.5,0.15) circle (0.15) (4,0.15) circle (0.15) (4.5,0.15) circle (0.15);
        
        
\end{tikzpicture}}

\newsavebox\Engine
\sbox\Engine{\begin{tikzpicture}
        %   \draw (0,0)--(10,0);
        \draw [fill=gray!20] (0,0.2) --(3.4,0.2)--(3.4,2)--(2.4,2)--(2.3,1.4)--(0,1.4)--(0,0.2);  
        \draw [fill=gray!80] (0.8,0.4) circle (0.4) (1.7,0.4) circle (0.4) (2.6,0.4) circle (0.4) ;
        \draw [fill=gray!50] (0.4,1) rectangle (2,1.2);
        \draw [fill=gray!5] (2.5,1) rectangle (3.2,1.7);
\end{tikzpicture}}

\begin{document}
        \begin{tikzpicture}[every node/.style={transform shape},
        truck/.style={node contents=\usebox{\Truck}},
        engine/.style={node contents=\usebox{\Engine}}
        ]
        \draw (0,0) node[truck,above](A)--(4,0) node[truck,above]--(8,0) node[ above,engine];

    \end{tikzpicture}
\end{document}

答案1

这是一个使用 的简单解决方案positioning

A

\documentclass{standalone}

\usepackage{tikz}
\usetikzlibrary{positioning}% added <<<<<<<<<<

\newsavebox\Truck
\sbox\Truck{\begin{tikzpicture}
        %   \draw (0,0)--(10,0);
        \draw [fill=gray!20] (1.75,0.1) rectangle  (4.75,0.75);
        \draw [fill=gray] (2,0.15) circle (0.15) (2.5,0.15) circle (0.15) (4,0.15) circle (0.15) (4.5,0.15) circle (0.15);      
\end{tikzpicture}}

\newsavebox\Engine
\sbox\Engine{\begin{tikzpicture}
        %   \draw (0,0)--(10,0);
        \draw [fill=gray!20] (0,0.2) --(3.4,0.2)--(3.4,2)--(2.4,2)--(2.3,1.4)--(0,1.4)--(0,0.2);  
        \draw [fill=gray!80] (0.8,0.4) circle (0.4) (1.7,0.4) circle (0.4) (2.6,0.4) circle (0.4) ;
        \draw [fill=gray!50] (0.4,1) rectangle (2,1.2);
        \draw [fill=gray!5] (2.5,1) rectangle (3.2,1.7);
\end{tikzpicture}}

\begin{document}
    \begin{tikzpicture}
        \node[inner sep=0pt](E){\usebox{\Engine}};
        \node(T)[right= 2cm of E.south east, anchor = south west,inner sep=0pt]{\usebox{\Truck}};   
        \draw  (T.west)-- (T-|E.east);          
    \end{tikzpicture}

\end{document}

答案2

\node请注意,每个节点都需要一个(可能为空的)标签文本。因此,您始终应该在每个(或node)宏后放置一对花括号。

pic现在,如果您确实想将绘图放置在节点内,那么您可以做的是将s 与 结合使用path picture

实际上,直接使用pics 而不将它们放在节点内可能更容易。例如,将它们放在某个地方非常容易\pic at (0,0) {truck};。但由于我不知道你的最终目标是什么,我发布了这个解决方案:

\documentclass[border=10pt]{standalone}
\usepackage{tikz}

\tikzset{
    truck/.pic={
        \draw[fill=gray!20] 
            (-1.5,0.1) rectangle (1.5,0.75);
        \draw[fill=gray] 
            (-1.25,0.15) circle[radius=0.15] 
            (-0.75,0.15) circle[radius=0.15] 
            (0.75,0.15) circle[radius=0.15] 
            (1.25,0.15) circle[radius=0.15];
    },
    engine/.pic={
        \draw[fill=gray!20] 
            (-1.7,0.2) -- (1.7,0.2) -- (1.7,2) -- (0.7,2) 
                -- (0.6,1.4) -- (-1.7,1.4) -- (-1.7,0.2);  
        \draw[fill=gray!80] 
            (-0.9,0.4) circle[radius=0.4] 
            (0,0.4) circle[radius=0.4] 
            (0.9,0.4) circle[radius=0.4];
        \draw[fill=gray!50] 
            (-1.3,1) rectangle (0.3,1.2);
        \draw[fill=gray!5] 
            (0.8,1) rectangle (1.5,1.7);
    }
}

\begin{document}
\begin{tikzpicture}[
        truck/.style={
            minimum width={3cm+0.4pt},
            minimum height={2cm+0.4pt},
            path picture={
                \pic at ([yshift=0.2pt]path picture bounding box.south) {truck};
            },
            yshift=0.67cm
        },
        engine/.style={
            minimum width={3.4cm+0.4pt},
            minimum height={2cm+0.4pt},
            path picture={
                \pic at ([yshift=0.2pt]path picture bounding box.south) {engine};
            },
            yshift=0.67cm
        },
    ]

    \draw 
        (0,0) node[engine, fill=cyan!10] {} 
            -- (4,0) node[truck, fill=cyan!10] {} 
            -- (8,0) node[truck, fill=cyan!10] {};
\end{tikzpicture}
\end{document}

在此处输入图片描述

解释:

首先,我将你的卡车和发动机图纸转换为pics。这非常简单,因为它实际上只是你已经知道的代码。我只是将图纸向左移动了一点,这样它们就水平居中了= 0。两幅画都位于同一基线上(在X= 0)。

然后,我使用path picture选项为节点创建样式,我基本上只是将相关内容放置在节点上,pic以便它成为节点的背景。这里正确设置节点的宽度和高度非常重要:它的宽度和高度应与图片加上线宽的一半一样,否则线条将在节点的边界处被剪裁。我path picture使用 将 s 相对于相关节点的底部对齐path picture bounding box.south

我最终将节点稍微移动了一点,这样它们相对于连接线的高度就合理了。我给节点的背景加了阴影,只是为了让它们可见。你可能想删除这个阴影。


如上所述,一种更简单的方法是仅使用pics 并使用向其添加可前缀坐标的功能(有点类似于锚点):

\documentclass[border=10pt]{standalone}
\usepackage{tikz}

\tikzset{
    truck/.pic={
        \draw[fill=gray!20] 
            (-1.5,0.1) rectangle (1.5,0.75);
        \draw[fill=gray] 
            (-1.25,0.15) circle[radius=0.15] 
            (-0.75,0.15) circle[radius=0.15] 
            (0.75,0.15) circle[radius=0.15] 
            (1.25,0.15) circle[radius=0.15];
        \coordinate (-front) at (-1.5,0.25);
        \coordinate (-back) at (1.5,0.25);
    },
    engine/.pic={
        \draw[fill=gray!20] 
            (-1.7,0.2) -- (1.7,0.2) -- (1.7,2) -- (0.7,2) 
                -- (0.6,1.4) -- (-1.7,1.4) -- (-1.7,0.2);  
        \draw[fill=gray!80] 
            (-0.9,0.4) circle[radius=0.4] 
            (0,0.4) circle[radius=0.4] 
            (0.9,0.4) circle[radius=0.4];
        \draw[fill=gray!50] 
            (-1.3,1) rectangle (0.3,1.2);
        \draw[fill=gray!5] 
            (0.8,1) rectangle (1.5,1.7);
        \coordinate (-front) at (-1.7,0.25);
        \coordinate (-back) at (1.7,0.25);
    }
}

\begin{document}
\begin{tikzpicture}

    \pic (A) at (0,0) {engine};
    \pic (B) at (3.5,0) {truck};
    \pic (C) at (7,0) {truck};

    \draw 
        (A-back) -- (B-front)
        (B-back) -- (C-front);

\end{tikzpicture}
\end{document}

在此处输入图片描述

相关内容