pgfkeys 的简单示例

pgfkeys 的简单示例

我正在努力理解pgfkeys包。我目前使用keycommand包,我发现它非常容易理解:它只是带有命名参数而不是编号参数的普通 LaTeX 命令。但是,我想使用它,pgfkeys因为我的项目很大程度上基于 TikZ,我相信它是一个更强大的解决方案。我认为了解如何将以下小示例从 翻译成keycommand将对pgfkeys我有很大帮助。

例子

我创建了一个绘制doublecircle小工具的命令。它有两个参数:diametercolor,均为可选参数,默认值分别为1red

\documentclass[border=5mm]{standalone}

\usepackage{tikz}
\usepackage{keycommand}

\newcounter{currentheight}
\setcounter{currentheight}{0}

\newkeycommand{\doublecircle}[diameter=1,color=red]{%
  \fill[\commandkey{color}] (0,\thecurrentheight) circle (\commandkey{diameter}/2);
  \fill[\commandkey{color}] (\commandkey{diameter}/2,\thecurrentheight) circle (\commandkey{diameter}/2);
}

\begin{document}

\begin{tikzpicture}[y=-1cm]
\doublecircle[color=blue]
\addtocounter{currentheight}{5}
\doublecircle[diameter=4]
\addtocounter{currentheight}{6}
\doublecircle[diameter=3,color=green]
\end{tikzpicture}

\end{document}

结果

三个双圆小工具

答案1

可能的解决方案:

\documentclass[border=5mm]{standalone}

\usepackage{tikz}

\pgfkeys{/tikz/.cd,% to set the path
  circle height/.initial=0, % initial value
  circle height/.get=\circleheight, % to get the value from a macro
  circle height/.store in=\circleheight, % to store the value into a macro
  diameter/.initial=1,
  diameter/.get=\diameter,
  diameter/.store in=\diameter,
  circle color/.initial=red,
  circle color/.get=\circlecolor,
  circle color/.store in=\circlecolor,
}

\newcommand{\pgfdoublecircle}[1][]{%
  \tikzset{circle color=red,diameter=1,#1}% the default options will be overwritten by the one introduced
  \fill[\circlecolor] (0,\circleheight) circle (\diameter/2);
  \fill[\circlecolor] (\diameter/2,\circleheight) circle (\diameter/2);
}

\begin{document}
\begin{tikzpicture}[y=-1cm]
\pgfdoublecircle[circle color=blue]
\pgfdoublecircle[circle height=5,diameter=4]
\pgfdoublecircle[circle height=11,diameter=3,circle color=green]
\end{tikzpicture}

\end{document}

根据奎伯比尔贝尔 评论以及其他问答pgfkeys 密钥处理程序 .get 和 .store 起什么作用?TikZ 风格的论据我决定放弃这种设置密钥的低效方法。因此,应该优先使用以下方法:

\pgfkeys{/tikz/.cd,% to set the path
  circle height/.store in=\circleheight, % to store the value into a macro
  circle height=0, % initial value
  diameter/.store in=\diameter,
  diameter=1,
  circle color/.store in=\circlecolor,
  circle color=red,
}

最终结果显然与后一种方法一致。

答案2

有几种方法可以获取、设置和存储值,另请参阅第一部分我的另一个答案.
根据密钥以及其值的需要,必须使用其中一种方式。

我们也常常看到

/my namespace/key/.code=\pgfmathsetmacro\namespace@key{#1}

也可以在这里使用,并以已经计算好的形式提供值,尽管这里实际上不需要它,因为 TikZ 几乎可以抛出 PGF Math 本身中的任何内容。请参阅(还有)我的另一个答案如何更有效地使用它(关于的部分+)。

代码

\documentclass[tikz,border=5mm]{standalone}
\newcommand*{\doublecircleset}{\pgfqkeys{/double circle}}
\makeatletter
\doublecircleset{
  /double circle/.code={\pgfqkeys{/double circle}{#1}},
  color/.initial=red, % initialize key 'color' with value 'red'
  height/.initial=0, % see color
  diameter/.store in=\doublecircle@diameter, % the key 'diameter' will be used more than once and also in the 'scope', let's store it right away
  diameter=1,                                % the default value is '1'
  add to height/.style={height/.expanded=\pgfkeysvalueof{/double circle/height}+#1} % let's take the value of the 'height' key and add '#1'.
                                                     % expansion is needed otherwise we have a selv-referencing macro (and an infinite loop)
}
\newcommand{\doublecircle}[1][]{%
  % let's group the whole macro so that the changes to the keys and whatnot are local, this is how TikZ works.
  % we could have used '\begingroup \doublecircleset{#1} … … … \endgroup' here, but the scope allows us to set the radius too.
  \scope[/double circle={#1}, radius=(\doublecircle@diameter)/2] % alright, execute the key=values and set the radius
    \pgfkeysgetvalue{/double circle/height}\doublecircle@height  % we need the height more than once, a single macro would be nice to use
    \fill[color=\pgfkeysvalueof{/double circle/color}]           %
      (0,{\doublecircle@height}) circle []                       % if we use () or , in the key (which is allowed: PGF math) we need to enclose it in braces
      (xyz cs: x={(\doublecircle@diameter)/2},                   % either way
               y={\doublecircle@height}) circle []
      ;
  \endscope
}
\makeatother
\begin{document}
\begin{tikzpicture}[y=-1cm]
\doublecircle[color=blue]
\doublecircleset{add to height=5}
\doublecircle[diameter=4]
\doublecircleset{add to height=6}
\doublecircle[diameter=3, height=2*(2+3), color=green]
\end{tikzpicture}
\end{document}

相关内容