根据 pgfmanual,不允许在剪切路径上设置选项,因此
\clip[fill=red] (0,0) circle (1);
不起作用。这很好,上述情况当然是可以避免的。
然而,当设置这些选项时,同样不起作用隐含地every path/.style={fill=red}
,通过提供一个包含的范围来表示。
有没有办法获取我的路径并剪辑它?也就是说,有没有办法清除单个路径上的当前全局设置?
下面是我想要做(但不能做)的事情的一个例子:
\documentclass{article}
\usepackage{tikz}
\begin{document}
\begin{tikzpicture}[every path/.style={fill=red}]
\clip (0,0) -- (1,0) -- (1,1) -- (0,0);
\draw (0,0) rectangle (1,1);
\end{tikzpicture}
\end{document}
(我要强调的是,这是一个最小例如:在实际情况下,我有很多路径和很多不同的层和范围,并且非常希望能够在主tikzpicture
环境中指定默认路径样式。即使这样做:
\documentclass{article}
\usepackage{tikz}
\begin{document}
\begin{tikzpicture}
\clip (0,0) -- (1,0) -- (1,1) -- (0,0);
\begin{scope}[every path/.style={fill=red}]
\draw (0,0) rectangle (1,1);
\end{scope}
\end{tikzpicture}
\end{document}
在最终的真实世界实现中会令人恼火。)
如果有帮助的话,我正在使用 TeXLive 2010,但 pgf 的日期是 2010-07-25。
答案1
这似乎有效。这是更好的选择吗?
\begin{tikzpicture}[every path/.style={fill=red}]
{
\tikzset{every path/.style={}}
\clip (0,0) -- (1,0) -- (1,1) -- (0,0);
}
\draw (0,0) rectangle (1,1);
\end{tikzpicture}
由 Andrew Stacey 于 2012-12-27 编辑上述问题是如何clip
与设置边界框进行交互。当剪辑生效时,剪辑路径应设置边界框,并且在计算边界框时不应考虑所有剪辑路径。不幸的是,虽然剪辑持续到范围结束,但忽略后续路径的方法(对于边界框计算)仅持续到当前组的结束。我(Andrew Stacey)实际上会将此归类为 TikZ 错误:由于剪辑持续到范围结束,因此对边界框计算的限制也应持续到范围结束。有多种方法可以解决这个问题:
由于通常将剪辑限制在某个范围内,因此请将其放在
every path/.append style={overlay}
相关范围内:\begin{tikzpicture}[every path/.style={fill=red}] \begin{scope}[every path/.append style={overlay}] { \tikzset{every path/.style={}} \clip (0,0) -- (1,0) -- (1,1) -- (0,0); } \draw (-1,-1) rectangle (2,2); \end{scope} \end{tikzpicture}
由于选项被清除,它将
overlay
从剪辑路径中删除,但它将保留在范围内的所有其他路径上。为了更直观的控制,
overlay
可以将键增强为采取true
或false
(尽管由于实现,需要反转的值true/false
)。然后:\documentclass{article} \usepackage{tikz} \def\invertTFtrue{false} \def\invertTFfalse{true} \tikzoption{overlay}[true]{\csname pgf@relevantforpicturesize\csname invertTF#1\endcsname\endcsname} \begin{document} \fbox{% \begin{tikzpicture}[every path/.style={fill=red}] \begin{scope}[overlay] { \tikzset{every path/.style={}} \clip[overlay=false] (0,0) -- (1,0) -- (1,1) -- (0,0); } \draw (-1,-1) rectangle (2,2); \end{scope} \end{tikzpicture}} \end{document}
最后,可以修复覆盖/剪辑机制,使其适用于范围而不是组。要正确而优雅地做到这一点,需要稍微修复一下底层代码,下面使用可用的钩子来实现相同的目的。
\documentclass{article} \usepackage{tikz} \makeatletter \def\invertTFtrue{false} \def\invertTFfalse{true} \tikzset{ fix clips to scope/.style={% every scope/.append style={% execute at end scope={% \expandafter\global\csname pgf@relevantforpicturesize\savescopeoverlay\endcsname }, execute at begin scope={% \edef\savescopeoverlay{\ifpgf@relevantforpicturesize true\else false\fi}% } }, globalise overlays, clip/.append code={\aftergroup\globaloverlay} }, globalise overlays/.code={% \tikzoption{overlay}[true]{\expandafter\global\csname pgf@relevantforpicturesize\csname invertTF#1\endcsname\endcsname} } } \def\globaloverlay{\global\pgf@relevantforpicturesizefalse} \makeatletter \begin{document} \fbox{% \begin{tikzpicture}[fix clips to scope,every path/.style={fill=red}] \begin{scope} { \tikzset{every path/.style={}} \clip (0,0) -- (1,0) -- (1,1) -- (0,0); } \draw (-1,-1) rectangle (2,2); \end{scope} \draw (-1,1) rectangle (2,2); \end{tikzpicture}} \end{document}