更新我最近发现这个问题Nickolay Kolev \tikz
在 tikzpicture 环境中使用。很多用户认为这是错误的做法,我同意这很奇怪,但有时非常有用。我也同意最好避免这种情况。我在 中使用了这种可能性 pgfornament
。
我不明白为什么如果我反转 tikzpicture(包装器)的两行,我会得到不同的结果。overlay
我认为,重置边界框,但为什么在第二个 tikzpicture 中,覆盖层会重新设置一般边界框。当我使用示波器时,问题就消失了?
更新我认为 tikz 的专家认为最好使用范围而且这个问题很愚蠢......
或者在 pgfmanual 中,我读到
所有图形选项对于它们适用的{tikzpicture}来说都是本地的。
红色图片没有边界框。
\documentclass[11pt]{scrartcl}
\usepackage{tikz}
\begin{document}
baseline\begin{tikzpicture}[baseline=(current bounding box.north west)]
\tikz[overlay] \path (0,0) -- (1,1) node {\color{blue}$\bullet$};
\draw[help lines,blue!20] (0,0) grid (2,2) ;
\end{tikzpicture}baseline%
%
\begin{tikzpicture}[baseline=(current bounding box.south west)]
\draw[help lines,red!20] (0,0) grid (2,2) ;
\tikz[overlay] \path (0,0) -- (1,1) node {\color{red}$\bullet$};
\end{tikzpicture}baseline
\end{document}
使用 pgfinterruptboundingbox
绿色图片。边界框正确。第一个边界框受到保护。
解决方案是将覆盖线放置在 pgfinterruptboundingbox 环境内,以便问题与当前边界框相关联。
baseline\begin{tikzpicture}[baseline=(current bounding box.south west)]
\draw[help lines,green!50] (0,0) grid (2,2) ;
\begin{pgfinterruptboundingbox}
\tikz[overlay] \path (0,0) -- (1,1) node {\color{green}$\bullet$};
\end{pgfinterruptboundingbox}
\end{tikzpicture}baseline
范围没问题
\documentclass[11pt]{scrartcl}
\usepackage{tikz}
\begin{document}
baseline\begin{tikzpicture}[baseline=(current bounding box.north west)]
\tikz[overlay] \path (0,0) -- (1,1) node {\color{blue}$\bullet$};
\draw[help lines,blue!20] (0,0) grid (2,2) ;
\end{tikzpicture}baseline
\begin{tikzpicture}[baseline=(current bounding box.south west)]
\draw[help lines,red!20] (0,0) grid (2,2) ;
\begin{scope} [overlay] \path (0,0) -- (1,1) node {\color{red}$\bullet$};
\end{scope}
\end{tikzpicture}baseline
\end{document}
( 范围和 tikzpicture 之间真正的区别是什么?)
更新这个问题可能太笼统了,更好的答案是 tikz 的表现如何overlay
?
答案1
很多用户认为 [嵌套 TikZ 图片] 是一种错误的做法
那么那就是我了。
这是另一个可能发生意外结果的例子。主要原因很简单:TikZ 不预计其环境是嵌套的,因此在启动和停止时不会检查各种假设。特别是,通过跟踪代码,我们可以看到 TikZ 花费了大量精力来处理 tikzpicture 环境中的范围和分组。由于必须从范围中提取某些信息(例如边界框信息),因此 TikZ 必须“偷运”这些信息,它通过使用全局变量来实现这一点。它以非常巧妙的方式做到这一点,即信息仅传递到 TikZ 希望传递的地方,而不是传递到任何其他分组之外。
但是对于主 tikzpicture 环境本身,它不期望嵌套,因此不使用这些复杂的方法。例如,对于边界框,它知道这\pgf@picmaxx
是当前图片边界框的最大 x 值,并且只涉及一张图片,因此它可以将其视为全局变量,因为这使生活变得容易得多:每个分配都可以是\pgf@picmaxx
全局的,以避免组和范围的麻烦。为了避免复杂化,我们需要做的就是确保在 tikzpicture 环境开始时将所有这些全局变量都设置为其默认值。
\pgf@picmaxx
让我们通过您的代码来追踪分配:
\documentclass[11pt]{scrartcl}
\usepackage{tikz}
\begin{document}
baseline\begin{tikzpicture}[baseline=(current bounding box.north west)]
在 tikzpicture 的开始处,它被设置为:-16000.0pt
\tikz[overlay]
从技术上讲,这里也设置为 -16000.0pt
\path (0,0) -- (1,1) node {\color{blue}$\bullet$};
在该命令结束时,它被设置为 0.0pt,这是该 tikzpicture 的最大 x 范围,因为它有键overlay
。
\draw[help lines,blue!20] (0,0) grid (2,2) ;
现在,它被设置为 57.00548pt,这是上述命令的范围。
\end{tikzpicture}baseline%
这是仍然这里是 57.00548pt,因为它是全局分配的。
%
\begin{tikzpicture}[baseline=(current bounding box.south west)]
现在重置为 -16000.0pt
\draw[help lines,red!20] (0,0) grid (2,2) ;
这里设置为 57.00548pt
\tikz[overlay]
此时,由于我们已经开始了一个新的 tikzpicture,因此我们将其重置为 -16000.0pt。
\path (0,0) -- (1,1) node {\color{red}$\bullet$};
由于overlay
键的作用,我们在这里得到 0.0pt 的分配,该分配直到图片结束都有效。
\end{tikzpicture}baseline
这里仍然是0.0pt。
\end{document}
它适用于范围的原因在于,由于范围是嵌套的,因此 TikZ/PGF 会竭尽全力确保在设置和拆除范围时边界框等功能正常工作。我认为这是您最基本问题的答案:
范围和 tikzpicture 之间的真正区别是什么?
要正确嵌套 tikzpictures,必须查看范围的代码,并查看它竭尽全力保留的键、长度和宏。然后做同样的事情。我猜,这就是你用 and 实际做的事情。\savecurrentboundingbox
我\restorecurrentboundingbox
认为你答案末尾的问题本身就是一个很好的问题。即使我认为嵌套 TikZ 图片不是一个好主意,但正如你所指出的,不可避免地存在需要这样做的情况。知道如何确保在必须这样做时安全地做到这一点将是无价的信息(并且,我认为,它会表明人们不应该这样做轻轻因此它可以起到威慑作用)。
答案2
tikzpicture
一种可能性是,当创建了带有\begin{tikzpicture}
或 的环境时,\tikz
许多变量和选项都已正确设置。路径现在为空,但为什么是相同的路径?
下一个代码显示,如果没有覆盖,我们可以在页面上放置一些内容,并且边界框是正确的
我避免\begin{pgfinterruptboundingbox}
使用两个宏\savecurrentboundingbox
和\restorecurrentboundingbox
\documentclass[11pt]{scrartcl}
\usepackage{tikz,lipsum}
\newcommand\savecurrentboundingbox{%
\coordinate (saved cbb ne) at (current bounding box.north east);
\coordinate (saved cbb sw) at (current bounding box.south west); }
\newcommand\restorecurrentboundingbox{%
\useasboundingbox (saved cbb sw) rectangle (saved cbb ne); }
\begin{document}
\lipsum[1]
\fbox{%
\begin{tikzpicture}[baseline=(current bounding box.south west)]
\draw[help lines,red!20] (0,0) grid (2,2) ;
\savecurrentboundingbox
\tikz {%
\path[use as bounding box] (0,0) rectangle (0,0);
\path (0,0) -- (4,4) node {\color{red}$\bullet$};}%
\restorecurrentboundingbox
\end{tikzpicture}%
}baseline
\end{document}
了解 tikzpicture 环境开始时使用的重要变量是什么将会很有趣。