在使用 TikZ 的包中,我生成了两条路径(取决于一些选项值),现在我需要将它们组合成一条用于的路径\filldraw
。我发现TikZ 编程这确实让我可以保存和恢复路径。但是,我在恢复之后所做的任何操作都不会对 产生任何影响\filldraw
。特别是,在示例中-- cycle
被完全忽略。
知道如何在 TikZ 中保存一条或两条路径,然后恢复并继续甚至连接两条路径吗?
一个简化的例子是:
\documentclass{article}
\usepackage{tikz}
\begin{document}
\makeatletter
\begin{tikzpicture}
\path[save path=\tmppath] (0,0) -- (2,2) -- (4,1);
\path[save path=\tmppathII] (6,-2) -- (3,-2);
% Effectively, I want the following, but by using \tmppath and \tmppathII:
% \filldraw[color=red,fill=blue] (0,0) -- (2,2) -- (4,1) -- (6,-2) -- (3,-2) -- cycle;
% This properly draws/fills the \tmppath, but does NOT use the -- cycle at all...
\pgfsyssoftpath@setcurrentpath{\tmppath} -- cycle \filldraw[color=red,fill=blue];
% This only draws \tmppathII, not the whole constructed path...
% \pgfsyssoftpath@setcurrentpath{\tmppath} --
% \pgfsyssoftpath@setcurrentpath{\tmppathII} -- cycle \filldraw[color=red,fill=blue];
\end{tikzpicture}
\end{document}
答案1
你的第一个案例几乎可以工作。需要调整的地方是-- cycle
需要为命令提供语法\filldraw
。第二个命令需要做更多的工作才能...呃...工作。
你可能已经知道这一点(因为你已经发现了软路径),但我还是会解释一下机制,以防别人在听。当你给出一个 TikZ 命令时,比如\path (0,0) -- (2,2) -- (4,1);
TikZ 会将其转换为底层的 PGF 命令,然后使用这些命令构建一个柔软的路径。软路径保存在宏(或一系列宏)中,是构建路径的基本指令。它是“软”的,因为它仍然可以被操作,但它的格式非常简单(这使得操作更加简单)。当save path
给出密钥时,TeX 会保存当前软路径。当 TikZ/PGF 在路径上工作时,会有一个“当前软路径”,即他们此时正在使用的路径。定义路径的任何命令都会添加到此路径中。棘手的是,TikZ 在启动时不会清空当前软路径,因此当\draw
启动命令时,它只会将其内容附加到已经存在的内容上。这是通常空路径,因为每当路径用过的(即渲染)则当前软路径设置为“空”。但不必如此。
因此,该命令\pgfsyssoftpath@setcurrentpath{\tmppath}
本质上是在告诉下一个 TikZ 命令(\filldraw
)“不要以空白路径开头,而是以 开头\tmppath
”。但扩展命令必须经过 TikZ 系统才能处理成软路径标记,这就是为什么 必须-- cycle
在 上\filldraw
而不是 之后的原因\pgfsyssoftpath@setcurrentpath
。
现在我们明白了为什么第二个不起作用。第一个说“使用\tmppath
”,第二个说“不,使用\tmppathII
”。所以第二个获胜,我们只得到第二条路径。在这种情况下,您想要连接路径。如果您真的只是想连接它们,那么您可以将一个接一个地放置(这需要对扩展稍微小心,但完全可以)。假设定义\ge@addto@macro
为添加扩张第二个宏到第一个宏的末尾,然后你可以执行以下操作:
\ge@addto@macro\tmppath\tmppathII
\pgfsyssoftpath@setcurrentpath{\tmppath}
\filldraw[color=red,fill=blue] -- cycle;
复杂之处在于你想用线到不是一个搬去. 每条软路径都以显式移动。你需要将其换成线。为此,我们需要吞噬 的第一个标记\tmppathII
(即\pgfsyssoftpath@movetotoken
)并将其放置\pgfsyssoftpath@linetotoken
在其位置。
此时,我开始想,“如果有一个包可以帮我完成所有这些工作,那不是很好吗?”幸运的是,我之前就想到了这一点,而且由于没有这样的包,所以我写了它。我刚刚更新了它以完成concatenate with lineto
所需的工作。
因此,请前往TeX-SX 包,下载文件spath.dtx
,运行pdflatex spath.dtx
,然后以下操作将执行您想要的操作:
\documentclass{standalone}
\usepackage{tikz}
\usepackage{spath}
\begin{document}
\begin{tikzpicture}
\path[save path=\tmppath] (0,0) -- (2,2) -- (4,1);
\pgfoonew \patha=new spath(\tmppath)
\path[save path=\tmppath] (6,-2) -- (3,-2);
\pgfoonew \pathb=new spath(\tmppath)
\patha.concatenate with lineto(,\pathb)
\patha.close()
\patha.use path with tikz(line width=3pt,draw=red,fill=blue)
\end{tikzpicture}
\end{document}
(编辑:觉得无聊,就实施了这个close
方法。这line width=3pt
是为了表明路径确实被关闭了。)
结果:
答案2
实际上,我刚刚意识到,一开始就没有必要让 TikZ/PGF 创建路径。一种解决方案是简单地存储文本需要在 tex 命令中生成路径,然后只需将其插入(即展开)即可\path
。这是一个简单示例:
\documentclass{article}
\usepackage{tikz}
\begin{document}
\begin{tikzpicture}
\newcommand{\aaa}{(0,0) -- (2,2) -- (4,1)}
\newcommand{\bbb}{(6,-2) -- (3,-2)}
\filldraw[color=red,fill=blue] \aaa -- \bbb -- cycle;
\end{tikzpicture}
\end{document}