我正在尝试将具有特定形状(杯子)的文件包含到另一个 TikZ 图像中,以便使用杯子作为“印章”来绘制更复杂的图形。该文件位于 /usr/share/tikzit/shapes/cap.tikz
\documentclass{article}
\usepackage[svgnames]{xcolor}
\usepackage{tikz}
\usetikzlibrary{decorations.markings}
\usetikzlibrary{shapes.geometric}
\pagestyle{empty}
\pgfdeclarelayer{edgelayer}
\pgfdeclarelayer{nodelayer}
\pgfsetlayers{edgelayer,nodelayer,main}
\tikzstyle{none}=[inner sep=0pt]
\tikzstyle{node1}=[cap,fill=White,draw=Black]
\tikzstyle{simple}=[-,draw=Black,line width=2.000]
\tikzstyle{arrow}=[-,draw=Black,postaction={decorate},decoration={markings,mark=at position .5 with {\arrow{>}}},line width=2.000]
\tikzstyle{tick}=[-,draw=Black,postaction={decorate},decoration={markings,mark=at position .5 with {\draw (0,-0.1) -- (0,0.1);}},line width=2.000]
\usepackage[graphics,tightpage,active]{preview}
\PreviewEnvironment{tikzpicture}
\newlength{\imagewidth}
\newlength{\imagescale}
\begin{document}
\begin{tikzpicture}
\begin{pgfonlayer}{nodelayer}
\node [style=node1] (0) at (-2.5, 1.5) {};
\end{pgfonlayer}
\end{tikzpicture}
\end{document}
我想要包含的代码如下:
\begin{tikzpicture}
\path [use as bounding box] (-2,-2) rectangle (2,2);
\begin{pgfonlayer}{nodelayer}
\node [style=none] (0) at (0, 0.75) {};
\node [style=none] (1) at (-0.5, 0) {};
\node [style=none] (2) at (0.5, 0) {};
\end{pgfonlayer}
\begin{pgfonlayer}{edgelayer}
\draw [in=0, out=90] (2.center) to (0.center);
\draw [in=270, out=-90, looseness=0.75] (1.center) to (2.center);
\draw [in=90, out=180] (0.center) to (1.center);
\end{pgfonlayer}
\end{tikzpicture}
但似乎我不知道如何指定 cup 的目录。我收到此错误:
软件包 pgfkeys 错误:密钥“/tikz/cap”需要一个值。我将忽略该密钥。
似乎我必须处理 tikzstyle 或 pgfkey,但我不知道如何指定外部文件。
答案1
正如我在评论中提到的,TikZ 不允许使用图片作为节点的选项。如果我理解正确的话,您的问题可以通过使用标题为 的小图片来解决pic
。它们在 TikZ v3.0 和最新版本手册的“18 张图片:路径上的小图片”部分中有描述(在最新版本 3.0.1a 中,它在第 251 页上显示)。
- 将您设计的图像设计成小图片并在任何文档中将其调用为“\pic {pic 名称}”;
- 设计的图片存储在 \tikzset{...} 中并将其存储在私有样式包中,例如“my_TikZ_presets”,LaTeX 必须知道这一点(即:将其存储在本地树中的某个位置并更新 LaTeX 文件名数据库;
- 在文档中,如果您喜欢使用这些图片,则需要加载此样式,并在 TikZ 图片中设置使用的选项
tikzset
(参见下面的代码)
下面是 MWE,它演示了上述内容。
\documentclass{article}
\usepackage[svgnames]{xcolor}
\usepackage{tikz}
\usetikzlibrary{decorations.markings,positioning,shapes.geometric}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\tikzset{PIC/.style = {%this you can store for example as
% my_TikZ-presets.style somewhere,
% where (La)TeX looking for yours packages
% (not in main tree)
% here you can collect all styles, which
% you use in yours TikZ pictures
% small picture bell
bell/.pic = {%path [use as bounding box] (-2,-2) rectangle (2,2); do really need them?
\draw [in= 90,out=180] (0,0.75) coordinate (-top) to
(-0.5,0) coordinate (-bottom left);
\draw [in= 90,out= 0] (0,0.75) to
(0.5, 0) coordinate (-bottom right);
\draw [in=270,out=-90, looseness=0.75] (-0.5,0) to (+0.5,0);
}%
},% end of bell style
% for nodes with rectangular shape
box/.style = {draw, line width=1mm, inner sep=1mm,
minimum width = 44mm, minimum height=33mm,
font=\itshape, align=left},
% for shortening lines on the both sides
shorten <>/.style = {shorten < = #1, shorten > = #1},
% etc
}% end of tikzset
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \endinput
\usepackage[graphics,tightpage,active]{preview}
\PreviewEnvironment{tikzpicture}
\begin{document}
\begin{tikzpicture}[PIC]
% demo for connecting small pictures width line
\pic[red] at (0,0) (A) {bell};
\pic[blue] at (3,0) (B) {bell};
\draw[dotted, ultra thick,shorten <>=2mm] (A-bottom right) -- (B-bottom left);
% demo for use it as stamp on letter envelope
\node[box,below right] (C) at (-0.75,-0.5) {To my\\ dearest\\ Clementine};
\pic[below left=of C.north east] (D) {bell};
\end{tikzpicture}
\end{document}
在上述 MWE 的设计中,我只部分遵循了您的设计。我允许自己在图片设计方面有一定的自由度 :-)。在 MWE 中,只考虑与其相关的定义和包。此 MWE 提供:
答案2
这与Zarko 的回答。我还使用了pic
,并且按照 Zarko 的做法,我将其称为bell
。
我要做的是创建一个小型的 TikZ 库,当您希望在图片中使用此类功能时,可以将其与其他库一起加载。
我不完全清楚不同层的用途是什么,因此我以特定的方式详细阐述它,希望您能够看到如何根据自己的需要修改代码。
首先,库代码。我建议将其保存为tikzlibrarybell.code.tex
。<TEXMFHOME>/tex/generic/pgf/
这<TEXMFHOME>
是您的个人texmf
树。在 TeX Live 中,kpsewhich -var TEXMFHOME
将为您提供路径。但是,如果您只想将其用于一张图片,则可以将其保存在您的工作目录中。当您说 时,特定的文件名允许 TikZ 找到它\usetikzlibrary{bell}
。
如果我更好地理解了键值对,这段代码无疑会得到显著改善。这是我目前的努力和我目前的理解的成果。
请注意,此处的使用/bell
可防止与标准键或其他库中的键发生冲突。例如,我使用的是/bell/cap
而不是普通的cap
,因此此处不会妨碍行尾的使用cap
。此代码中的使用cap
严格限于/bell
键路径。
% tikzlibrarybell.code.tex
\ProvidesFile{tikzlibrarybell.code.tex}
\pgfdeclarelayer{bell edge layer}
\pgfdeclarelayer{bell node layer}
\pgfsetlayers{bell edge layer,bell node layer,main}
\tikzset{% modified from code at tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarybackgrounds.code.tex
on bell edge layer/.style={%
execute at begin scope={%
\pgfonlayer{bell edge layer}%
\let\tikz@options=\pgfutil@empty%
\tikzset{every on bell edge layer/.try,#1}%
\tikz@options%
},
execute at end scope={\endpgfonlayer}
},
on bell node layer/.style={%
execute at begin scope={%
\pgfonlayer{bell node layer}%
\let\tikz@options=\pgfutil@empty%
\tikzset{every on bell node layer/.try,#1}%
\tikz@options%
},
execute at end scope={\endpgfonlayer}
},
pics/bell/.style={%
code={%
\tikzset{%
/bell/.cd,
#1,
/tikz/.cd,
}%
\path [use as bounding box] (-2,-2) rectangle (2,2);
\begin{scope}[on bell node layer]
\node [pic actions, /bell/node style] (a) at (0, 0.75) {\bell@top@node};
\node [pic actions, /bell/node style] (b) at (-0.5, 0) {\bell@left@node};
\node [pic actions, /bell/node style] (c) at (0.5, 0) {\bell@right@node};
\end{scope}
\begin{scope}[on bell edge layer]
\path [pic actions, /bell/cap style] (c.center) [in=0, out=90] to (a.center) [in=90, out=180] to (b.center) [in=270, out=-90, looseness=0.75] to (c.center);
\end{scope}
}%
},
/bell/.search also={/tikz},
/bell/.cd,
top/.store in=\bell@top@node,
left/.store in=\bell@left@node,
right/.store in=\bell@right@node,
% this cannot be the right way to do this!!!
cap/.code={\tikzset{/bell/cap style/.style={/tikz/.cd, #1}}},
nodes/.code={\tikzset{/bell/node style/.style={/tikz/.cd, #1}}},
top=,
left=,
right=,
cap style/.style={draw},
node style/.style=,
}
\endinput
这定义了一个带有一个可选参数的pic
调用bell
。如果指定,参数应该是铃声的选项。除了标准 TikZ 选项外,您还可以使用
cap={<style for cap itself>}
nodes={<style for nodes, if any>}
top={<text for node at top>}
left={<text for node at bottom left>}
right={<text for node at bottom right>}
默认情况下,形状只是简单绘制,节点都是空的,没有任何样式。
给定这个库,我们可以bell
pic
按照以下方式创建一行:
\documentclass[tikz,border=10pt]{standalone}
\usetikzlibrary{shapes.geometric,bell}
\begin{document}
\begin{tikzpicture}
\pic {bell};
\pic at (2,0) {bell={%
nodes={fill opacity=.75, text=blue, text opacity=1, inner color=blue!10, outer color=blue!30, font=\sffamily, inner sep=0pt, shape=ellipse},
cap={draw=blue!50!black, ball color=blue!50, thick},
top={top},
left={left},
right={right},
}};
\pic at (4,0) {bell={%
nodes={text=red, draw=red, thick, fill=white, font=\sffamily, inner sep=1pt, shape=circle},
cap={draw=red, thick, inner color=red!95!black, outer color=red!75!black},
top={A},
left={B},
right={C},
}};
\pic at (6,0) {bell};
\end{tikzpicture}
\end{document}
pic actions
代码中的 意味着您还可以传递其他选项,这些选项将影响 的所有元素pic
。但是,这不应与lines
和中使用的选项冲突nodes
,否则您可能会得到奇怪的结果。(例如,尝试\pic [fill=green!10] {bell};
看看我的意思!)
以下是一个例子:
\begin{tikzpicture}
\pic [rotate=90] {bell};
\pic at (2,0) [rotate=-90] {bell={nodes={draw, circle, fill=white, inner sep=1pt, font=\sffamily}, top=1, left=2, right=3, cap={draw, fill=gray!25}}};
\end{tikzpicture}
完整代码:
\begin{filecontents}{tikzlibrarybell.code.tex}
% tikzlibrarybell.code.tex
\ProvidesFile{tikzlibrarybell.code.tex}
\pgfdeclarelayer{bell edge layer}
\pgfdeclarelayer{bell node layer}
\pgfsetlayers{bell edge layer,bell node layer,main}
\tikzset{% modified from code at tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarybackgrounds.code.tex
on bell edge layer/.style={%
execute at begin scope={%
\pgfonlayer{bell edge layer}%
\let\tikz@options=\pgfutil@empty%
\tikzset{every on bell edge layer/.try,#1}%
\tikz@options%
},
execute at end scope={\endpgfonlayer}
},
on bell node layer/.style={%
execute at begin scope={%
\pgfonlayer{bell node layer}%
\let\tikz@options=\pgfutil@empty%
\tikzset{every on bell node layer/.try,#1}%
\tikz@options%
},
execute at end scope={\endpgfonlayer}
},
pics/bell/.style={%
code={%
\tikzset{%
/bell/.cd,
#1,
/tikz/.cd,
}%
\path [use as bounding box] (-2,-2) rectangle (2,2);
\begin{scope}[on bell node layer]
\node [pic actions, /bell/node style] (a) at (0, 0.75) {\bell@top@node};
\node [pic actions, /bell/node style] (b) at (-0.5, 0) {\bell@left@node};
\node [pic actions, /bell/node style] (c) at (0.5, 0) {\bell@right@node};
\end{scope}
\begin{scope}[on bell edge layer]
\path [pic actions, /bell/cap style] (c.center) [in=0, out=90] to (a.center) [in=90, out=180] to (b.center) [in=270, out=-90, looseness=0.75] to (c.center);
\end{scope}
}%
},
/bell/.search also={/tikz},
/bell/.cd,
top/.store in=\bell@top@node,
left/.store in=\bell@left@node,
right/.store in=\bell@right@node,
% this cannot be the right way to do this!!!
cap/.code={\tikzset{/bell/cap style/.style={/tikz/.cd, #1}}},
nodes/.code={\tikzset{/bell/node style/.style={/tikz/.cd, #1}}},
top=,
left=,
right=,
cap style/.style={draw},
node style/.style=,
}
\endinput
\end{filecontents}
\documentclass[tikz,border=10pt,multi]{standalone}
\usetikzlibrary{shapes.geometric,bell}
\begin{document}
\begin{tikzpicture}
\pic {bell};
\pic at (2,0) {bell={%
nodes={fill opacity=.75, text=blue, text opacity=1, inner color=blue!10, outer color=blue!30, font=\sffamily, inner sep=0pt, shape=ellipse},
cap={draw=blue!50!black, ball color=blue!50, thick},
top={top},
left={left},
right={right},
}};
\pic at (4,0) {bell={%
nodes={text=red, draw=red, thick, fill=white, font=\sffamily, inner sep=1pt, shape=circle},
cap={draw=red, thick, inner color=red!95!black, outer color=red!75!black},
top={A},
left={B},
right={C},
}};
\pic at (6,0) {bell};
\end{tikzpicture}
\begin{tikzpicture}
\pic [rotate=90] {bell};
\pic at (2,0) [rotate=-90] {bell={nodes={draw, circle, fill=white, inner sep=1pt, font=\sffamily}, top=1, left=2, right=3, cap={draw, fill=gray!25}}};
\end{tikzpicture}
\end{document}