要求 :

要求 :

这个问题试图扩展其他两者的目的都是为了提供 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 dimensionspic actions/tikz/infinity dimensions

问题 :

如何将传递pic actions给某些底层样式,以便可以设置该样式的各部分,并且该样式未涵盖的样式选项将传递回和/tikz分支/pgf

最简单的机制可能是使用.search also处理程序,但我的尝试似乎失败了。也许它更复杂,而且确实需要密钥过滤。

背景 :

问题意味着pic actions在某种程度上受到限制。 @Qrrbrbirlbel提供了一些替代策略,但我还没有成功使用其中任何一种。

答案1

pic actions如果说是有限的,那就有点误导了。当然,它们和其他东西一样,都是有局限性的。锤子也是有局限性的:它不能把水烧开。

我认为问题在于你试图让它们做一些它们不适用的事情,并且可能试图用pics 做一些它们不适用的事情。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 KEYKEY设置它的对应项似乎是常见的做法。据说这在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/.stylevia 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 alsoinfinity dimensions/.search also={/tikz}pic actionsupper target=...infinity dimensions/.style{upper target=...}/tikz/tikz/infinity dimensionspic actions/tikzpic actions

相关内容