我正在做一个相当复杂的投影仪演示,有时我无法按照需要 使用\spy
命令。TikZ
为了重现该问题,我想出了以下单帧示例(从PGF 手册):
\documentclass{beamer}
\usepackage{etex}
\usepackage{tikz}
\usepackage{pgfplots}
\usetikzlibrary{backgrounds, decorations.fractals, spy}
\begin{document}
\begin{frame}[plain]
\begin{tikzpicture}[spy using overlays={size=12mm}]
\draw [decoration=Koch snowflake] decorate { decorate{ decorate{ decorate{ (0,0) -- (2,0) }}}};
\spy [green,magnification=3] on (0.6,0.1) in node at (-0.3,-1);
\spy [blue,magnification=5] on (1,0.5) in node at (1,-1);
\spy [red,magnification=10] on (1.6,0.1) in node at (2.3,-1);
\end{tikzpicture}
\end{frame}
\end{document}
经过这样的编译,放大的区域除了彩色背景外不会显示任何其他内容。
玩弄这段代码,我注意到任何下列修改可以解决问题:
- 把这一行放在一行
\usepackage{pgfplots}
后面\usetikzlibrary
; - 注释掉该
\usepackage{etex}
行; - 不加载该
backgrounds
库; backgrounds
将库作为最后一个加载。
显然,最后一种可能性非常适合我的问题(并且我已经在我的演示中采用了它),但我想更好地理解上面的代码中发生的情况。
- 哪个角色做包裹
etex
并pgfplots
玩游戏? - 为什么在存在这样的包的情况下,在加载
backgrounds
该包之前的库spy
会导致放大的区域消失? - 更一般地说,为什么罐子
TikZ
里的库的顺序很\usetikzlibrary
重要?我天真地猜测事实并非如此。
在发布问题之前搜索了一下,我发现在这个答案中一些关于图层如何工作的内容,但这并不能完全回答我的问题。
澄清:
在我的示例中,要生成单帧,不需要包etex
和pgfplots
以及库。但是,在我的演示中我需要它们。backgrounds
答案1
Beamer 和 pgfplots 与这个问题不太相关。下面是它出错的原因
Beamer、pgfplots 和 Ti钾Z 将包括 PGF,而 PGF 将包括
pgfcorelayers.code.tex
。pgfcorelayers.code.tex
有\let\pgf@newbox=\newbox
- eTeX 有
\def\newbox{\alloc@4\box\chardef\insc@unt}
backgrounds
有\pgfdeclarelayer{background}
这本质上
\pgf@newbox\pgf@layerbox@background \pgf@newbox\pgf@layerboxsaved@background
spy
有\newbox\tikz@lib@spybox
请注意,此时,\pgf@newbox
不同于\newbox
。事实证明\tikz@lib@spybox
等于\pgf@layerboxsaved@background
。因此,对背景层的操作可能会清理间谍框。
为什么\tikz@lib@spybox
= \pgf@layerboxsaved@background
?
在 TeX 中,只有 255 个盒子寄存器,它们\box0
通过调用\box255
。这非常不方便用户使用。因此,在 plain-TeX 中,Knuth 定义了一种语法\newbox\mybox
。它的工作原理如下:
\count14
会计算有多少个盒子;\newbox
将会加\count14
一,令\mybox
为\count14
。
然而之间存在差异添加并分配和分配并添加. 这很像 C 语言
mybox = count14++;
不同于
mybox = ++count14;
因此,应该确保两者\pgf@newbox
选择\newbox
相同的方式。
顺便说一句:默认情况下,Box 寄存器分配(可能)会打印到日志文件中。如果你检查日志文件,你会看到类似以下内容的内容
\tikz@lib@spybox=\box38
\pgf@layerboxsaved@background=\box38
你就会知道有些事情出错了。
一些解决方法
如果你把 eTeX 放在 Ti 之前钾Z 和 pgfplots,两者
\pgf@newbox
将会\newbox
相同,并且没有问题。然而,如果 Beamer 首先调用 PGF,则此方法不起作用。如果你把 eTeX 放在 Ti 之后钾Z 和 pgfplots,两者
\pgf@newbox
将会\newbox
相同,并且没有问题。然而\newbox
,如果在包含 eTeX 之后使用声明任何框,则此方法不起作用。如果放在
spy
前面backgrounds
,那么间谍框与背景框就不同。然而backgrounds
,如果使用之后声明任何框\newbox
,它将与背景框相同。据我对纯 TeX 的了解,一种安全的方法是尽早包含 eTeX,然后立即重新分配
\let\pgf@newbox=\newbox
。