我在 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}
答案1
正如评论中所述,我相信 PGF 负责人会将您的请求视为功能请求(而不是错误报告)。因此,可能需要更长时间才能得到结果。但也许 PGF 负责人会发现,为完整图片设置的选项不是图层的一部分,这完全出乎意料,他可能想针对该特定部分实施修复,我不知道。说了这么多:我也想要一个更好的解决方案。但要做好等待的准备(也许要等很长时间)。
同时,了解给定的分层架构如何工作可能会有助于避免此类问题。
以下是我的理解。它包括以下相互作用:
- 图层
- 选项更改(尤其是样式)
- 图形设置
通常,您可以随时根据需要更改选项。如果您更改样式,样式将根据使用情况进行评估(例如,every node
将在 期间进行评估\node
)。但影响图形状态的选项(如color
和linewidth
类似选项)有所不同:它们由范围(至少我认为如此)和\path
s(\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}
中设置的选项,但是如果您嵌套了(即,仅使用最内层范围的选项),它将无法正常工作。scope
tikzpicture
scopes