在 TikZ 中保存和重复使用/合并路径?

在 TikZ 中保存和重复使用/合并路径?

在使用 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}

相关内容