TikZ:在命令中用另一个pgfkey覆盖基于一个pgfkey的形状填充

TikZ:在命令中用另一个pgfkey覆盖基于一个pgfkey的形状填充

我正在创建一个基于带有 pgf 键/值参数的命令生成 tikz 图片的包。我想要两个参数,一个指定具有特定填充颜色的基本形状,另一个在为 false 时将该填充“打开”(指定颜色),为 true 时将该填充“关闭”(变为白色)。我在下面创建了一个简化的示例:

\documentclass[border=5pt]{standalone}
\usepackage{xifthen}
\usepackage{tikz}
\newboolean{shapecolour}
\pgfkeys{/tikz/.cd,
 circle/.style={fill=red},
 square/.style={fill=green},
 triangle/.style={fill=yellow},
 blank/.style={fill=white},
 colourshape/.store in=\colourshape,
 colourshape=circle,
 nocolour/.store in=\nocolour,
 nocolour=false,
 circle/.pic={\draw [fill] circle(0.5); },
 square/.pic={\draw [fill] (0,0) -- (0,1) -- (1,1) -- (1,0) -- cycle;},
 triangle/.pic={\draw [fill] (0,0) -- (1,0) -- (0.5, 1) -- cycle;},
 }

\begin{document}

\newcommand{\TestCommand}[1][]{
 \tikzset{colourshape=circle, nocolour=false, #1}
 \setboolean{shapecolour}{\nocolour}
 \pic[\ifthenelse{\boolean{shapecolour}}{blank}{\colourshape}]{\colourshape};
}

\begin{tikzpicture}
 \TestCommand[colourshape=triangle, nocolour=true]
\end{tikzpicture}

\end{document}

根据输入的 pgfkeys 参数,这是我的代码所期望的结果TestCommand

代码的期望结果

因此,上述代码应生成一个白色填充的三角形。但我得到的却是错误,! Argument of \boolean has an extra }.我知道我可以通过pic为形状的每个变体指定一个单独的三角形以更冗长的方式实现相同的结果,但我希望有一个更紧凑的解决方案,尤其是因为将有更多样式选项可供遵循。

答案1

如果没有关于整个项目的更多信息,很难确定。但是,从您的示例来看,我根本不会在这里使用条件。如果您确实使用了条件,我会研究 PGF 的.is if处理程序,这将使事情变得容易得多。

首先是一些关键点:

\tikzset{%

我们可以在这里使用详细名称,因为用户界面根本不需要它们。

  Crazymoomin circle/.pic={\draw [fill=Crazymoomin@fill] (.5,.5) circle (0.5);},
  Crazymoomin square/.pic={\draw [fill=Crazymoomin@fill] (0,0) -- (0,1) -- (1,1) -- (1,0) -- cycle;},
  Crazymoomin triangle/.pic={\draw [fill=Crazymoomin@fill] (0,0) -- (1,0) -- (0.5, 1) -- cycle;},

为了能够在用户界面中使用简单的键名,我们将它们放在自定义路径上,但我们会确保标准 TiZ 键在这里也可以使用。

  /Crazymoomin/.search also={/tikz},

切换路径。

  /Crazymoomin/.cd,

现在我们可以使用简单的名称而不必覆盖默认值。

  fill/.code={%

这将保存自定义颜色。

    \colorlet{Crazymoomin@fill}{#1}%
  },

还有一个形状。

  shape/.store in=\Crazymoomin@shape,

为了巧妙地处理颜色/形状组合,让我们做出colour shape一个选择键。

  colour shape/.is choice,

现在对于选项,每个选项都切换到我们的路径并设置形状pic和填充。

  colour shape/triangle/.style={/Crazymoomin/.cd, shape=triangle, fill=yellow},
  colour shape/circle/.style={/Crazymoomin/.cd, shape=circle, fill=red},
  colour shape/square/.style={/Crazymoomin/.cd, shape=square, fill=green},

no colour可以将填充设置为白色。

  no colour/.style={/Crazymoomin/fill=white},

确保所有事物都有一个默认值。

  fill=gray,
  shape=circle,
}

现在命令。

\newcommand{\TestCommand}[1][]{%
 \tikzset{%

切换到我们的路径。

   /Crazymoomin/.cd,

默认设置。无论如何,这都会设置填充颜色,因此no colour默认情况下实际上是 false。

   colour shape=circle,

用户选项。

   #1,
 }%

还有pic

 \pic {Crazymoomin \Crazymoomin@shape};
}

然后我们可以写,例如,

\begin{tikzpicture}
 \TestCommand[colour shape=triangle, no colour]
 \scoped[xshift=12.5mm]{\TestCommand[colour shape=circle, no colour]}
 \scoped[xshift=25mm]{\TestCommand[colour shape=square, no colour]}
 \scoped[yshift=12.5mm]{\TestCommand[colour shape=triangle]}
 \scoped[xshift=12.5mm, yshift=12.5mm]{\TestCommand[colour shape=circle]}
 \scoped[xshift=25mm, yshift=12.5mm]{\TestCommand[colour shape=square]}
\end{tikzpicture}

生产

形状变化

显然这很尴尬,因为我不想在\TextCommand没有任何定位信息的情况下搞太多乱七八糟的事情(呃!?)。

完整代码:

\documentclass[border=10pt,multi,tikz]{standalone}
\makeatletter
\tikzset{%
  Crazymoomin circle/.pic={\draw [fill=Crazymoomin@fill] (.5,.5) circle (0.5);},
  Crazymoomin square/.pic={\draw [fill=Crazymoomin@fill] (0,0) -- (0,1) -- (1,1) -- (1,0) -- cycle;},
  Crazymoomin triangle/.pic={\draw [fill=Crazymoomin@fill] (0,0) -- (1,0) -- (0.5, 1) -- cycle;},
  /Crazymoomin/.search also={/tikz},
  /Crazymoomin/.cd,
  fill/.code={%
    \colorlet{Crazymoomin@fill}{#1}%
  },
  shape/.store in=\Crazymoomin@shape,
  colour shape/.is choice,
  colour shape/triangle/.style={/Crazymoomin/.cd, shape=triangle, fill=yellow},
  colour shape/circle/.style={/Crazymoomin/.cd, shape=circle, fill=red},
  colour shape/square/.style={/Crazymoomin/.cd, shape=square, fill=green},
  no colour/.style={/Crazymoomin/fill=white},
  fill=gray,
  shape=circle,
}
\newcommand{\TestCommand}[1][]{%
 \tikzset{%
   /Crazymoomin/.cd,
   colour shape=circle,
   #1,
 }%
 \pic {Crazymoomin \Crazymoomin@shape};
}
\makeatother
\begin{document}
\begin{tikzpicture}
 \TestCommand[colour shape=triangle, no colour]
 \scoped[xshift=12.5mm]{\TestCommand[colour shape=circle, no colour]}
 \scoped[xshift=25mm]{\TestCommand[colour shape=square, no colour]}
 \scoped[yshift=12.5mm]{\TestCommand[colour shape=triangle]}
 \scoped[xshift=12.5mm, yshift=12.5mm]{\TestCommand[colour shape=circle]}
 \scoped[xshift=25mm, yshift=12.5mm]{\TestCommand[colour shape=square]}
\end{tikzpicture}
\end{document}

相关内容