![维度太大/三条(非常简单的)链的算术溢出](https://linux22.com/image/420299/%E7%BB%B4%E5%BA%A6%E5%A4%AA%E5%A4%A7%2F%E4%B8%89%E6%9D%A1%EF%BC%88%E9%9D%9E%E5%B8%B8%E7%AE%80%E5%8D%95%E7%9A%84%EF%BC%89%E9%93%BE%E7%9A%84%E7%AE%97%E6%9C%AF%E6%BA%A2%E5%87%BA.png)
我正在尝试绘制一个非常简单的辫状图,下面的代码“半成功”地构建了一个具有所需输出的 PDF(但仅在编译因以下错误而停止之前),但我无法在任何实际文档中使用此代码,因为它总是以Dimension too large
和Arithmetic overflow
错误终止\end{knot}
。删除一条或两条线似乎可以使其编译良好(似乎取决于哪些线)。
- 为什么会发生这个错误?
- 我该如何修复它?(最好使用
knots
包)。
\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{knots}
\begin{document}
\begin{tikzpicture}
\node at (0,0) {$\bullet$};
\node at (1,0) {$\bullet$};
\node at (1.5,0) {$\bullet$};
\begin{knot}
\strand (1,0) to (0,-3);
\strand (1.5,0) to (0.5,-3);
\strand (0,0) to (1.5,-3);
\end{knot}
\node at (0,-3) {$\bullet$};
\node at (0.5,-3) {$\bullet$};
\node at (1.5,-3) {$\bullet$};
\end{tikzpicture}
\end{document}
答案1
这实际上是 PGF 库的一个问题intersections
。该knots
库使用 PGF 交点例程来查找所有指定线之间的交点(毕竟,为什么要重新发明轮子?)。不幸的是,当 PGF 库查找平行线之间的交点时会出现问题。
我可以使用以下代码复制该问题:
\documentclass{article}
%\url{https://tex.stackexchange.com/q/561184/86}
\usepackage{tikz}
\usetikzlibrary{intersections}
\begin{document}
\begin{tikzpicture}
\draw[ultra thick, orange,name path=a] (1,0) to (0,-3);
\draw[ultra thick, orange,name path=b] (1.5,0) to (0.5,-3);
\path[name intersections={of=a and b}];
\end{tikzpicture}
\end{document}
(并且,据记录,我正在针对 PGF 的最新开发版本进行测试。)
实际情况是,当 PGF 寻找两条线段的交点时,它会尝试使用公式,而不是真正寻找交点(就像它寻找曲线那样)。现在在库中有以下注释:
原则上,此例程能够计算整个交点……但我们仅在检查边界框重叠后才调用它。这有两个原因:
- 鲁棒性。在求解线性方程组时,几乎平行的线可能会导致“尺寸太大” XXX:我仍然需要用使用 FPU 的线性求解器替换线性求解器。也许我不再需要 BB 检查了?
- 性能。我希望先检查 BB 会更快(但这在 TeX 中不确定)
并且代码中有各种注释表明正在使用的公式首先被仔细用于检查平行线。
dimension too large
然而,当我看到你的(平行)线时,显然还是出了问题。
显然,最好的结果是在代码中修复此问题。与此同时,有几个可能的“表面”修复方法。一个是调整路径,使它们不再平行。我不再收到以下错误:
\documentclass{article}
%\url{https://tex.stackexchange.com/q/561184/86}
\usepackage{tikz}
\usetikzlibrary{intersections}
\begin{document}
\begin{tikzpicture}
\draw[ultra thick, orange,name path=a] (1,0) to (0.01,-3); % This used to be (0,-3)
\draw[ultra thick, orange,name path=b] (1.5,0) to (0.5,-3);
\path[name intersections={of=a and b}];
\end{tikzpicture}
\end{document}
另一种方法是强制 PGF 使用更费力的分治法(用于曲线)。一种方法是将控制点放在端点处:
\documentclass{article}
%\url{https://tex.stackexchange.com/q/561184/86}
\usepackage{tikz}
\usetikzlibrary{intersections}
\begin{document}
\begin{tikzpicture}
\draw[ultra thick, orange,name path=a] (1,0) .. controls +(0,0) and +(0,0) .. (0,-3);
\draw[ultra thick, orange,name path=b] (1.5,0) to (0.5,-3);
\path[name intersections={of=a and b}];
\end{tikzpicture}
\end{document}
(我不知道是否有一种简单的方法可以用to
路径来实现这一点。如果一个人致力于将一切都变成路径,那么他可能可以定义一条to
直线但实际上是贝塞尔的路径to
。)
(我需要做一些调查来检查我是否真的在使用最新的代码,因为https://github.com/pgf-tikz/pgf/issues/369表明此问题已修复。啊,不,已修复建议的但尚未落实。
答案2
这不是我问题的完整答案,但以下代码对我来说工作正常(没有错误)(感谢这条推文)。我可以使用它来获取我想要的图表,但我仍然不知道到底是什么导致了错误,并且想知道...
\begin{tikzpicture}[knot gap=7]
\draw[knot] (1,0) to (0,-3);
\draw[knot] (1.5,0) to (0.5,-3);
\draw[knot] (0,0) to (1.5,-3);
\node at (0,0) {$\bullet$};
\node at (1,0) {$\bullet$};
\node at (1.5,0) {$\bullet$};
\node at (0,-3) {$\bullet$};
\node at (0.5,-3) {$\bullet$};
\node at (1.5,-3) {$\bullet$};
\end{tikzpicture}