这个问题试图扩展其他两者的目的都是为了提供 tikz-pics 的“最佳”实践,或者至少提供几个如何阐明一些可能采用的更高级技巧的示例。
要求 :
通常,为图片设置一组基本尺寸是有意义的。允许用户更改这些尺寸使他们能够以某种小方式自定义图片。这在各种情况下都很有用。TikZ 将图片的选项收集到 forpic actions
命令读取 中。允许在中指定的选项传递到 pgf 树中的分支、挑选任何相关键并将剩余的键传递回树中知道如何处理它们的其他家族\draw pic[PIC ACTIONS] {...}
似乎是合理的。pic actions
代码 :
这个问题需要更清晰的代码@LoopSpace,剥离书法代码以专注于处理pic actions
。我在代码中尝试了四种方法,基本上尝试将键传递到正确的分支,如果它们不存在,则将它们传递到树上。我主要针对处理程序进行此尝试.search also
。
\documentclass[tikz]{standalone}
\usetikzlibrary{calc,calligraphy}
\makeatletter
\def\inf@key#1{%
\pgfkeysvalueof{/tikz/infinity dimensions/#1}%
}
\tikzset{
% Dimensions
infinity dimensions/.is family,
infinity dimensions/width/.initial =1 em,
infinity dimensions/height/.initial=1 em,
infinity dimensions/upper target/.initial=0.2,
infinity dimensions/lower target/.initial=0.8,
infinity dimensions/.search also={/tikz, /pgf},
% Method 1
%infinity dimensions/.style={infinity dimensions/.cd,},
% Method 2
%infinity dimensions/.style={infinity dimensions/#1},
% Method 3
infinity dimensions/.style={infinity dimensions/.cd,#1},
% Method 4
%infinity dimensions/.style={@infinity dimensions/.list={#1}},
%@infinity dimensions/.style={/tikz/infinity dimensions/#1}
% Pic/Symbol
infinity symbol/.pic = {
% Method 1
%\draw[infinity dimensions, pic actions]
% Method 2
%\draw[infinity dimensions=pic actions]
% Method 3
\draw[infinity dimensions=pic actions]
% Method 4
%\draw[infinity dimensions={pic actions}]
let \p1=(0,0) in
(\p1) .. controls (-\inf@key{upper target}*\inf@key{width}, \inf@key{height}) and (-\inf@key{lower target}*\inf@key{width},-\inf@key{height}) ..
(\p1) .. controls ( \inf@key{lower target}*\inf@key{width}, \inf@key{height}) and ( \inf@key{upper target}*\inf@key{width},-\inf@key{height}) .. cycle;
},
}
\makeatother
\begin{document}
\begin{tikzpicture}
\draw pic[double] {infinity symbol};
\end{tikzpicture}
\begin{tikzpicture}
\draw pic[height=2em] {infinity symbol};
\end{tikzpicture}
\end{document}
问题 :
方法 1 和 4 返回错误,指出/tikz/height
不存在。方法 2 和 3 返回错误,指出不存在。代码似乎要么跳到和根/tikz/infinity dimensions/pic actions
的上一级,无法识别分支中的某些内容,要么无法识别中的某些内容。/tikz
/pgf
/tikz/infinity dimensions
pic actions
/tikz/infinity dimensions
问题 :
如何将传递pic actions
给某些底层样式,以便可以设置该样式的各部分,并且该样式未涵盖的样式选项将传递回和/tikz
分支/pgf
。
最简单的机制可能是使用.search also
处理程序,但我的尝试似乎失败了。也许它更复杂,而且确实需要密钥过滤。
背景 :
这问题意味着pic actions
在某种程度上受到限制。
@Qrrbrbirlbel提供了一些替代策略,但我还没有成功使用其中任何一种。
答案1
pic actions
如果说是有限的,那就有点误导了。当然,它们和其他东西一样,都是有局限性的。锤子也是有局限性的:它不能把水烧开。
我认为问题在于你试图让它们做一些它们不适用的事情,并且可能试图用pic
s 做一些它们不适用的事情。spic
很容易创建,但通常情况下,这种便利性是以功能和灵活性为代价的。当然,你可以不使用 ,而拥有功能和灵活性,却不拥有便利性pic
。
这不是我通常配置的方式pic
,因为我不想仅仅因为我倾向于做不同的事情而覆盖你的配置。但我认为关键是灵活设置选项的最简单方法是将它们作为参数传递给特定,pic
而不是将它们作为选项传递给路径pic
。
例如,
\documentclass[tikz,border=10pt,multi]{standalone}
\usetikzlibrary{calc}
\makeatletter
\def\inf@key#1{%
\pgfkeysvalueof{/tikz/infinity dimensions/#1}%
}
\tikzset{
% Dimensions
infinity dimensions/.is family,
infinity dimensions/width/.initial =1 em,
infinity dimensions/height/.initial=1 em,
infinity dimensions/upper target/.initial=0.2,
infinity dimensions/lower target/.initial=0.8,
infinity dimensions/.search also={/tikz,/pgf},
infinity setup/.code={%
\tikzset{%
infinity dimensions/.cd,
#1,
/tikz/.cd,
}%
},
infinity symbol/.pic = {%
\draw [infinity dimensions/.cd, pic actions, infinity setup=#1]
let \p1=(0,0) in
(\p1) .. controls (-\inf@key{upper target}*\inf@key{width}, \inf@key{height}) and (-\inf@key{lower target}*\inf@key{width},-\inf@key{height}) ..
(\p1) .. controls ( \inf@key{lower target}*\inf@key{width}, \inf@key{height}) and ( \inf@key{upper target}*\inf@key{width},-\inf@key{height}) .. cycle;
},
}
\makeatother
\begin{document}
\begin{tikzpicture}
\draw pic [rotate=-45] {infinity symbol={height=2em, line width=2mm, double=blue, draw=green}};
\end{tikzpicture}
\end{document}
答案2
这个答案是对@cfr 答案的赞美。
观察结果:
@cfr 的答案比他展示的更灵活,例如可以很容易地使用以下调用来绘制符号
\draw pic [rotate=-45, infinity setup={height=2em, line width=2mm, double=blue, draw=green}] {infinity symbol};
代码 :
在玩@cfr 代码时,我偶然发现了实现他/她提供的相同机制的另一种方法这里。从执行角度来看,它似乎没有添加任何内容,但它稍微清理了代码。
\documentclass[tikz]{standalone}
\usetikzlibrary{calc,calligraphy}
\makeatletter
\def\inf@key#1{%
\pgfkeysvalueof{/tikz/infinity dimensions/#1}%
}
初始部分读取相同并简单设置尺寸。
\tikzset{
% Dimensions
infinity dimensions/.is family,
%infinity dimensions/.search also={/tikz, /pgf},
infinity dimensions/width/.initial =1 em,
infinity dimensions/height/.initial=1 em,
infinity dimensions/upper target/.initial=0.2,
infinity dimensions/lower target/.initial=0.8,
}
然后,我们根据另一个答案调整@cfr的代码,如下所示。提供一个every KEY
和KEY
设置它的对应项似乎是常见的做法。据说这在tikz中随处可见,但我还没有证实这一点。
\tikzset{
every infinity/.style={pic actions, infinity dimensions/.cd},
infinity/.style={every infinity/.append style={#1}},
}
使用#1
启用\draw pic {infinity={...}};
调用签名,删除它会导致 tikz 忽略输入。这是强制使用\draw pic[infinity={...}] {infinity};
。后一种语法将选项传递给every infinity/.style
via infinity/.syle
,提供类似于 @cfr 代码的接口。
\tikzset{
% Pic/Symbol
infinity symbol/.pic = {
\path[every infinity, #1]
let \p1=(0,0) in
(\p1) .. controls (-\inf@key{upper target}*\inf@key{width}, \inf@key{height}) and (-\inf@key{lower target}*\inf@key{width},-\inf@key{height}) ..
(\p1) .. controls ( \inf@key{lower target}*\inf@key{width}, \inf@key{height}) and ( \inf@key{upper target}*\inf@key{width},-\inf@key{height}) .. cycle;
},
}
\makeatother
\begin{document}
\begin{tikzpicture}
\draw pic[draw] at (0,-0.5em) {infinity symbol};
\draw pic[draw, double,infinity={lower target=1.5,upper target=0.5}] at (0, 0.5em) {infinity symbol};
\draw pic[double,draw] at (0, 1.0em) {infinity symbol={lower target=1.5,upper target=1.5}};
\end{tikzpicture}
\end{document}
最后一件可能值得关注的事情是,我将 传递pic actions
给基本样式,every infinity
但我是在路径更改之前这样做的。同样,也可以将其从基本样式中删除,而将其放入对 draw 的调用中,如 中所示\draw[pic actions, every infinity] ...
。无论哪种方式,效果都是一样的,后者稍微更“硬编码”。不过有一个警告,如果pic actions
放置在路径更改之后,如every infinity={infinity dimensions/.cd, pic actions}
或\draw[every infinity, pica actions]
中所示,则必须启用该行infinity dimensions/.serach also={/tikz, /pgf}
,否则您将收到错误消息,指示无法识别该键。
笔记:
最初我并没有意识到它pic actions
不喜欢在除 之外的任何路径下。只要处理程序设置正确,/tikz
您就可以将其传递给 say ,例如。由于它在此根中起作用,因此其中的任何内容也绑定到此根,因此会失败,因为它现在在路径中调用,而不是。因此 中包含的任何内容都在路径中执行。最初我认为更像是一个可以随意传递和解压的容器,这是不正确的。infinity dimensions/.style={}
.search also
infinity dimensions/.search also={/tikz}
pic actions
upper target=...
infinity dimensions/.style{upper target=...}
/tikz
/tikz/infinity dimensions
pic actions
/tikz
pic actions