是否可以清除 tikz/pgf 选项?

是否可以清除 tikz/pgf 选项?

根据 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 错误:由于剪辑持续到范围结束,因此对边界框计算的限制也应持续到范围结束。有多种方法可以解决这个问题:

  1. 由于通常将剪辑限制在某个范围内,因此请将其放在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从剪辑路径中删除,但它将保留在范围内的所有其他路径上。

  2. 为了更直观的控制,overlay可以将键增强为采取truefalse(尽管由于实现,需要反转的值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}
    
  3. 最后,可以修复覆盖/剪辑机制,使其适用于范围而不是组。要正确而优雅地做到这一点,需要稍微修复一下底层代码,下面使用可用的钩子来实现相同的目的。

    \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}
    

相关内容