TikZ 的 DVI 编译问题

TikZ 的 DVI 编译问题

以下代码可在 DVI 和 PDF 格式中编译。但是,如果我在命令后绘制任何内容\end{scope},它将无法在 DVI 中编译,并且我会收到以下错误消息:

Latex> ! Undefined control sequence.
Latex> \tikz@intersect@namedpaths ...t@path@name@line \x 
                                                          \endcsname {\pgfsyssoftpat...

PDF 记录了相同的错误,但编译通过,图像被渲染。是什么导致了这个错误?我还有很多东西要补充到这个图中!

更新:根据要求,我添加了一个随机绘制命令\draw (0,0) circle [radius=1cm];,然后触发了错误。使用path name global=line \x并不能解决问题。

\documentclass{article}

\usepackage{tikz} 
\usetikzlibrary{intersections,backgrounds}

\begin{document}
\begin{tikzpicture} 
%axis 
\draw (-.5,0) -- (6.5,0);  

%curve  
\draw[yshift=1cm,name path=curve] (-.5,0) %vertically shiftable
   to[out=70,in=180] (.7,1.5)
   to[out=0,in=180] (2,.5)
   to[out=0,in=180] (4.5,2.5)
   to[out=0,in=160] (6.5,1);

%rectangles
\begin{scope}[on background layer]
\foreach \x in {0,1,2,5}{
    \path[name path=line \x] (\x,0) -- (\x,4);
    \path[name intersections={of=curve and line \x, by={isect \x}}];    
    \draw[fill=gray!50] (isect \x) rectangle (\x+1,0);
    \draw[fill] (isect \x) circle [radius=2pt];
    }
\end{scope}   

\draw (0,0) circle [radius=1cm]; % Won't compile with this added draw

\end{tikzpicture}
\end{document}

答案1

我认为这是intersectionsTikZ 库中的一个错误。虽然它不会在 CVS 版本的 TikZ 中产生错误,但底层错误仍然存​​在。

当 TikZ 命名路径时,它必须将该路径保存到宏中。由于路径在处理过程中可能会发生相当大的变化,因此保存它的最佳时间是在最后。因此,交集库会挂接到最后\tikz@finish调用的宏中。因此,它将所有必要的交集代码存储到宏中,\tikz@intersect@namedpaths然后在最后执行该宏。代码的添加如下所示:

\def\tikz@intersect@finish{%    
        \ifx\tikz@intersect@namedpaths\pgfutil@empty%
        \else%
                \tikz@intersect@namedpaths%
                \let\tikz@intersect@namedpaths=\pgfutil@empty%
        \fi%
}

\tikz@finish这与所有其他东西的运行有关。

问题在于\let。宏\tikz@intersect@namedpaths定义全球。这是因为在路径内部,可能会涉及各种分组,而 TikZ 不想为此烦恼。所以它全局定义了这一点。然而,它只会清除它本地。通常情况下,这是可以的,因为清除发生在与命令相同的级别\path。但在这种情况下,这意味着scope当范围结束时,\tikz@intersect@namedpaths将恢复到其先前的状态全球的\path[name path=line \x] (\x,0) -- (\x,4);值。这是它在保存名为 的路径时所具有的值line \x。因此,当\draw执行范围后的命令时,该命令\tikz@intersect@namedpaths不为空,因此会被处理。

这绝对是一个错误,因为这意味着范围内部命名的任何路径现在都可以在其外部使用 - 因此,如果在范围之前和范围内部使用相同的路径名,则范围之后的路径就是在内部定义的路径,而不是前一个路径。

代码中出现投诉的原因是,在早期版本的 TikZ 中,宏\tikz@intersect@namedpaths会按指定的方式存储路径名。因此它将路径名(在您的示例中)存储为line \x。这意味着当在范围之外的命令\tikz@intersect@namedpaths中执行时\draw,它会尝试找出的含义\x并失败,因为它不再定义。更高版本的 TikZ 首先扩展路径名,这意味着line \x存储为,例如line 1。这就是为什么在更高版本的 TikZ 中不再产生错误,或者在将路径名传递给代码之前扩展路径名时(这就是所做的.expanded)不再产生错误的原因。但是,底层错误仍然存​​在,并且仍然可以通过查看保存的路径来检测到。

真正的解决方法是将 的重置\tikz@intersect@namedpaths变成全局重置。这很简单:将其添加\global到 前面\let。因此,正确的解决方案是将以下内容添加到您的序言中:

\makeatletter
\def\tikz@intersect@finish{%    
        \ifx\tikz@intersect@namedpaths\pgfutil@empty%
        \else%
                \tikz@intersect@namedpaths%
                \global\let\tikz@intersect@namedpaths=\pgfutil@empty%
        \fi%
}
\makeatother

这是一个显示路径持久性的示例。关键是蓝色圆圈。这应该位于下部路径的交汇处,但由于在范围内使用相同的名称,它被转移到上部路径(因为我们需要\tikz@intersect@namedpaths处理一个额外的路径命令之后)。\tikz@intersect@finish按照我描述的方式重新定义可以解决这个问题。

\documentclass{article}
%\url{http://tex.stackexchange.com/q/150598/86}
\usepackage{tikz} 
\usetikzlibrary{intersections}

\begin{document}

\begin{tikzpicture}
\draw[name path=abc] (-3,-3) -- (3,3);
\draw[name path=def] (3,-3) -- (-3,3);
\draw[green, ultra thick, name intersections={of=abc and def}] (intersection-1) circle[radius=6pt];
\begin{scope}
\draw[name path=abc] (-3,-2) -- (2,3);
\draw[green, ultra thick, name intersections={of=abc and def}] (intersection-1) circle[radius=6pt];
\end{scope}
\path (0,0); % needed to invoke \tikz@intersect@namedpath from inside the scope
\draw[blue, ultra thick, name intersections={of=abc and def}] (intersection-1) circle[radius=10pt];
\end{tikzpicture}

\makeatletter
\def\tikz@intersect@finish{%    
        \ifx\tikz@intersect@namedpaths\pgfutil@empty%
        \else%
                \tikz@intersect@namedpaths%
                \global\let\tikz@intersect@namedpaths=\pgfutil@empty%
        \fi%
}
\makeatother

\begin{tikzpicture}
\draw[name path=abc] (-3,-3) -- (3,3);
\draw[name path=def] (3,-3) -- (-3,3);
\draw[green, ultra thick, name intersections={of=abc and def}] (intersection-1) circle[radius=6pt];
\begin{scope}
\draw[name path=abc] (-3,-2) -- (2,3);
\draw[green, ultra thick, name intersections={of=abc and def}] (intersection-1) circle[radius=6pt];
\end{scope}
\path (0,0); % needed to invoke \tikz@intersect@namedpath from inside the scope
\draw[blue, ultra thick, name intersections={of=abc and def}] (intersection-1) circle[radius=10pt];
\end{tikzpicture}
\end{document}

交叉口错误

相关内容