之前我问过如何将选项传递给图片来操纵它们的绘制方式。使用这个可以创建带有可选组件和用户控制尺寸的图片。我还没有问过如何支持图片的可选部分。这是这个问题的主题。再次强调,这是针对最佳实践的。
要求 :
可选择在图片中启用附加细节。这允许绘制基本形状,并可根据需要进行修改或添加。
背景:
从 pgfmanual 中,pic 必须定义或设置键/tikz/pics/code
,这可以通过快捷方式完成KEY/.pic
,或者如果必须通过使用的样式定义更复杂的 pic pics/KEY/.style={code={...}}
。
代码 :
我尝试了以下方法,目的是将每个代码段堆叠或打包在一起,而不是最新的代码段code
覆盖前一个code
代码段。无论哪个是最后一个,都将执行。
\documentclass[tikz]{standalone}
\tikzset{
pics/.cd,
complex/.is family,
complex/.search also={/tikz/pics},
complex/lower/.style={
code={
\path[pic actions] (-1 em, -1 em) -- (1 em, 1 em) |- cycle;
}
},
complex/upper/.style={
code={
\path[pic actions] (-1 em, -1 em) -- (1 em, 1 em) -| cycle;
}
},
complex/center/.style={
code={
\path[pic actions] (-0.5 em, -0.5 em) rectangle (0.5 em, 0.5 em);
}
},
complex/.style={complex/.cd, center, #1}, % source/.get=\complex@code, code={\complex@code}
}
\begin{document}
\tikz \draw pic[draw] {complex, lower, upper};
\end{document}
问题:
鉴于code
各部分相互覆盖,是否有办法使图片具有额外的几何形状?
答案:
我已经为这个问题提供了自己的答案,但如果有的话我希望能有更好的建议。
答案1
第一个解决方案旨在提供灵活性,因为通过进行微小修改,它允许使用.add code
/ .append code
/.prefix code
处理程序将代码添加到基本几何图形的前面/后面。通过 app/prepending 这些代码片段创建的组合代码随后被传递到/tikz/pics/code
绘制图片的键上。第二个解决方案将所有内容转储到draw
命令中,这感觉不像是一个强大的解决方案。
第一个解决方案:
我们首先为形状设置适当的键。请注意,上部和下部实际上是将代码“粘贴”到原始源上,这使我们能够制作更复杂的形状,这些形状会逐渐添加到某些基本形状上。
\documentclass[tikz]{standalone}
\tikzset{
pics/.cd,
complex/.is family,
complex/source/.code={\draw[pic actions] (-1 em, -1 em) -| (1 em, 1 em);},
complex/upper/.style={
source/.append code={
\path[pic actions, rotate=45] (-1 em,-1 em) rectangle (1 em,1 em);
}
},
complex/lower/.style={
source/.append code={
\path[pic actions] (-0.5 em, -0.5 em) rectangle (0.5 em, 0.5 em);
}
},
}
我必须在下一个代码中使用固定路径,相对路径由于自我反射/调用而似乎在这里不起作用(我不认为这算作递归,但很接近)。(见下面的注释)
\tikzet{
pics/.cd,
complex/.style={
/tikz/pics/code={
\tikzset{pics/complex} % Executes the style
\tikzset{pics/complex/source} % Executes the code
},
complex/.append style={complex/.cd,#1}, % Sets up the style
},
}
最后我们创建文档主体如下
\begin{document}
\tikz draw pic[draw] {complex={upper}};
\end{document}
我认为最好强制执行上述接口\draw [draw] pic {complex={lower}};
。如果您需要提供更自由的接口,这些说明提供了一些(大多数?)替代方案。
笔记:
通过使用以下代码,我们可以对向 pic 用户公开的界面进行相当细粒度的控制。
\documentclass[tikz]{standalone}
...
\tikzset{
pics/.cd,
%complex/.search also={/tikz,/pgf}, %[3]
complex/.style={
code={
\tikzset{pics/complex/source}
},
%complex/.cd, %[1]
%#1 %[2]
},
}
...
\begin{document}
% Standard interface
\tikz draw pic[draw] {complex};
% Enable [1]
\tikz draw pic[draw] {complex, upper};
% Enable [1] and [2]
\tikz draw pic[draw] {complex={upper}, lower};
% Enable [1]-[3]
\tikz draw pic[draw] {complex={upper,double}, lower, thin};
\end{document}
取消注释标有 [1]-[3] 的行可以启用或禁用不同的接口,如下所示:
保留所有三行注释可提供标准 pic 行为,允许以 形式调用
\draw pic[draw] {complex};
。值得注意的是,pic 操作不会改变 pic 的几何形状,因此\draw pic[draw, /pic/complex/upper] {complex};
无法生成上部几何形状,但仍会绘制基本形状。启用 [1] 允许这样的调用,
\draw [draw] pic {complex, lower, upper};
是因为样式将当前路径更改为,/tikz/pics/complex
并且后面的参数upper, lower
现在在此空间内执行。启用 [1] 和 [3] 允许调用类似
\draw [draw] pic {complex, lower, upper, double};
,其中的upper, lower
处理方式与第 2 点中一样。double
另一方面是/tikz
根下的键,在根下无法识别/tikz/pics/complex
。但是,我们允许未知键/tikz/pics/complex
返回到/tikz
和/pgf
,因此随后可以识别该键double
。出于某种原因,这对颜色很挑剔,\draw [draw] pic {complex={lower, red}, upper, double};
例如失败。由于它对颜色很挑剔,它可能也不喜欢箭头规范。显然,在 TikZ 中,颜色和箭头的处理方式类似。启用 [1] 和 [2] 允许将参数传递给
complex
启用调用,例如\draw [draw] pic {complex={lower}, upper};
。启用 [1]、[2] 和 [3] 允许将参数传递到几乎任何地方
\draw [draw] pic {complex={lower, fill=red}, upper, double};
。优先考虑后面的参数\draw [draw] pic {complex={fill=red}, fill=green};
会导致出现绿色符号。启用此接口可能不是一个好主意,它似乎鼓励了草率的编程,并且与 XML 太相似了。
第二种解决方案:
第二种解决方案灵活性稍差,但代码却更简洁。
\tikzset{
pics/.cd,
complex/.is family,
complex/upper/.code={
\path[pic actions] (-1 em, -1 em) -- (1 em, 1 em) -| cycle;
},
complex/lower/.code={
\path[pic actions] (-1 em, -1 em) -- (1 em, 1 em) |- cycle;
},
complex/center/.code={
\path[pic actions] (-0.5 em, -0.5 em) rectangle (0.5 em, 0.5 em);
},
}
虽然它有点不太好用,因为它依赖于绘制命令来调用有助于最终形状的其他代码段。
\tikzset{
pics/.cd,
complex/.style={
code={\draw [pics/complex/.cd, center, #1];}
}
}
这似乎只允许一个接口
\begin{document}
\tikz draw pic[draw] {complex={upper}};
\end{document}