TikZ 中存在错误?图层上的线宽

TikZ 中存在错误?图层上的线宽

我在 TikZ 中发现了一个奇怪的行为。如果我全局设置线宽或为当前范围设置线宽,它不会影响内部的线,{pgfonlayer}但箭头尖端会发生变化:

行宽

我是否发现了一个错误?是否有人知道解决方案或至少是一种解决方法?

代码

\documentclass{minimal}

\usepackage{tikz}
\pgfdeclarelayer{background}
\pgfsetlayers{background,main}

\begin{document}
\begin{tikzpicture}[line width=5pt]
    \draw (0,0) -- (5,0);
    \draw [<->] (0,1) -- (5,1);
    \begin{pgfonlayer}{background}
        \draw (0,2) -- (5,2) node [right] {on BG};
        \draw [<->] (0,3) -- (5,3) node [right] {on BG};
    \end{pgfonlayer}
\end{tikzpicture}
\end{document}

更新

正如 Christian Feuersäger 所说,新图层可以设置具有默认设置的全新图片。但在这种情况下,所有设置都应重置。而且在我看来,every picture无论如何都应该评估样式。

这是一个扩展示例,显示了 的不一致行为every picture(仅对背景层的节点采用颜色,完全忽略线宽,甚至根据line width设置更改箭头提示)。
它还展示了我的解决方法,因为我正在使用环境的快捷方式,{pgfonlayer}所以很容易添加使用 的范围every picture。不幸的是,这{scope}不尊重直接提供给 的设置{tikzpicture}。而且它似乎与 Caramdir 的\makeatletter\tikz@options\makeatother解决方法不兼容……

\documentclass{minimal}

\usepackage{tikz}
\pgfdeclarelayer{background}
\pgfsetlayers{background,main}
\tikzset{every picture/.style={line width=5pt,blue,>=stealth}}

\newcommand{\bglayer}[1]{%
    \begin{pgfonlayer}{background}
        \begin{scope}[every picture]
        #1
        \end{scope}
    \end{pgfonlayer}
}

\begin{document}
\begin{tikzpicture}[green]
    \draw (0,0) -- (5,0);
    \draw [<->] (0,1) -- (5,1);
    \bglayer{%
        \draw (0,2) -- (5,2) node [right] {on BG};
        \draw [<->] (0,3) -- (5,3) node [right] {on BG};
    }
\end{tikzpicture}
\end{document}

示例 2


后续问题:在 {pgfonlayer} 之后恢复 TikZ 设置

答案1

正如评论中所述,我相信 PGF 负责人会将您的请求视为功能请求(而不是错误报告)。因此,可能需要更长时间才能得到结果。但也许 PGF 负责人会发现,为完整图片设置的选项不是图层的一部分,这完全出乎意料,他可能想针对该特定部分实施修复,我不知道。说了这么多:我也想要一个更好的解决方案。但要做好等待的准备(也许要等很长时间)。

同时,了解给定的分层架构如何工作可能会有助于避免此类问题。

以下是我的理解。它包括以下相互作用:

  1. 图层
  2. 选项更改(尤其是样式)
  3. 图形设置

通常,您可以随时根据需要更改选项。如果您更改样式,样式将根据使用情况进行评估(例如,every node将在 期间进行评估\node)。但影响图形状态的选项(如colorlinewidth类似选项)有所不同:它们由范围(至少我认为如此)和\paths(\draw当然包括 )应用。

每当您切换图层时,pgf 都会开始将低级绘图指令收集到不同的框中。所有已收集到不同图层中的低级绘图指令都不会复制到新图层中。

这很清楚。但由于“低级绘图指令”包括诸如\pgfsetlinewidth以及颜色分配之类的内容,因此这些设置不会复制到激活的图层。

切换到新层后,PGF 将继续进行正常处理。具体而言,它将继续评估样式,并且这些样式仍具有与切换层之前相同的值。

我想这对你来说也不是什么新鲜事。但这意味着你可以(也许应该)定义(自定义)样式来在图层之间共享选项。你使用样式的方法every picture实际上使用了该方法,但它可以普遍应用。

例如,

\begin{tikzpicture}
\tikzset{my style/.style={red,line width=10pt}}
\begin{scope}[my style]
...
\end{scope}

\pgfonlayer{...}
\begin{scope}[my style]
...
\end{scope}
\endpgfonlayer}
\end{tikzpicture}

可以完成这项工作。我同意,这并不像人们所希望的(或期望的)那么简单。但这是迄今为止的设计方式;其他一切都必须等待(直到有人实现改进的版本)。

换句话说:您采用的方法every picture是正确的,也许是目前唯一的方法。

关于“重置”:如前所述,图层不会引入全新的图片。它会继承所有当前样式和所有当前选项(除了那些已经写入其图层的图形状态选项)。因此,“重置”任何东西都不是选项。

答案2

这似乎是 pgf 中的错误:\pgfsetlinewidth设置图层时,路径样式似乎被遗忘了。我不知道为什么会发生这种情况。以下是 pgf 中的一个最小示例:

\documentclass{article}

\usepackage{pgf}
\pgfdeclarelayer{background}
\pgfsetlayers{background,main}

\begin{document}
\begin{pgfpicture}
    \pgfsetlinewidth{5pt}
    \pgfpathmoveto{\pgfpointorigin}
    \pgfpathlineto{\pgfpoint{5cm}{0cm}}
    \pgfusepath{draw}

    \begin{pgfonlayer}{background}
        \pgfpathmoveto{\pgfpoint{0cm}{1cm}}
        \pgfpathlineto{\pgfpoint{5cm}{1cm}}
        \pgfusepath{draw}
    \end{pgfonlayer}
\end{pgfpicture}
\end{document}

使用 TikZ,您可以\makeatletter\tikz@options\makeatother在 之后添加。这应该会让您获得在最后一个(或)\begin{pgfonlayer}{background}中设置的选项,但是如果您嵌套了(即,仅使用最内层范围的选项),它将无法正常工作。scopetikzpicturescopes

相关内容