![如何将 Tikz 图片制作成节点?](https://linux22.com/image/458183/%E5%A6%82%E4%BD%95%E5%B0%86%20Tikz%20%E5%9B%BE%E7%89%87%E5%88%B6%E4%BD%9C%E6%88%90%E8%8A%82%E7%82%B9%EF%BC%9F.png)
我正在尝试制作一个力学工作表来教授牛顿二定律!我想要一个拉卡车的发动机。我使用 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
。
\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
。
实际上,直接使用pic
s 而不将它们放在节点内可能更容易。例如,将它们放在某个地方非常容易\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}
解释:
首先,我将你的卡车和发动机图纸转换为pic
s。这非常简单,因为它实际上只是你已经知道的代码。我只是将图纸向左移动了一点,这样它们就水平居中了是= 0。两幅画都位于同一基线上(在X= 0)。
然后,我使用path picture
选项为节点创建样式,我基本上只是将相关内容放置在节点上,pic
以便它成为节点的背景。这里正确设置节点的宽度和高度非常重要:它的宽度和高度应与图片加上线宽的一半一样,否则线条将在节点的边界处被剪裁。我path picture
使用 将 s 相对于相关节点的底部对齐path picture bounding box.south
。
我最终将节点稍微移动了一点,这样它们相对于连接线的高度就合理了。我给节点的背景加了阴影,只是为了让它们可见。你可能想删除这个阴影。
如上所述,一种更简单的方法是仅使用pic
s 并使用向其添加可前缀坐标的功能(有点类似于锚点):
\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}