这forest
手动的定义了两种样式:sn edges
和nice empty nodes
。它们的定义如下:
sn edges/.style={for tree={parent anchor=south, child anchor=north}}
和
nice empty nodes/.style={for tree={calign=fixed edge angles},delay={where content={}{shape=coordinate,for parent={for children={anchor=north}}}{}} }
分别。
当这两种样式与以下树一起使用时,我收到以下错误:
! Package PGF Math Error: You asked me to calculate `1/0.0', but I cannot divid
e any number by zero.
See the PGF Math package documentation for explanation.
Type H <return> for immediate help.
...
l.51 \end{forest}
有人知道发生了什么吗?我该如何解决这个问题?
平均能量损失
\documentclass{article}
\usepackage{forest}
\forestset{
sn edges/.style={for tree={parent anchor=south, child anchor=north}},
nice empty nodes/.style={for tree={calign=fixed edge angles},delay={where content={}{shape=coordinate,for parent={for children={anchor=north}}}{}}}
}
\begin{document}
\begin{forest} nice empty nodes, sn edges
[TP
[{the ball} ]
[
[T ]
[PrP
[{$<$the ball$>$} ]
[
[Pr ]
[VoiP
[{$<$the ball$>$} ]
[
[Voi ]
[AffP
[{to Mary} ]
[
[Aff ]
[ThP
[{$<$the ball$>$} ]
[
[Th ]
[AgP
[{by John} ]
[
[Ag ]
[$\surd$throw ]
]
]
]
]
]
]
]
]
]
]
]
]
\end{forest}
\end{document}
更新
有趣的是,如果删除叶子下面的所有内容,编译时不会出现错误Aff
。也就是说,以下内容将编译:
\begin{forest} nice empty nodes, sn edges
[TP
[{the ball} ]
[
[T ]
[PrP
[{$<$the ball$>$} ]
[
[Pr ]
[VoiP
[{$<$the ball$>$} ]
[
[Voi ]
[AffP
[{to Mary} ]
[
[Aff ]
]
]
]
]
]
]
]
]
\end{forest}
答案1
首先,说明一下:即使没有风格也会出现错误sn edges
。
我相信这不是forest
,而是一个pgf
错误。我已将问题追溯到\pgfintersectionofpaths
的pgf
库intersections
。以下代码在没有 的情况下复制了确切的错误forest
。
\pgfintersectionofpaths{%
\pgfpathmoveto{\pgfpoint{0.0pt}{-3.53297pt}}
\pgfpathlineto{\pgfpoint{19.54204pt}{-31.44316pt}}%
}{%
\pgfpathmoveto{\pgfpoint{34.6372pt}{-53.00208pt}}%
\pgfpathlineto{\pgfpoint{19.54204pt}{-31.44316pt}}}
我对此事进行了进一步调查。\pgfintersectionofpaths
调用 \pgfpointintersectionoflines
,它通过对某个点应用一些坐标变换来计算两条线的交点。 上一句中两个“一些”的数学细节并不重要,除了 PGF 计算相关变换矩阵的最后一步是通过调用 来求某个其他矩阵的逆\pgftransforminvert
。 它是\pgftransforminvert
失败的,因为它试图求逆的矩阵接近奇异。 PGF 手册(第 641 页)警告会发生这种情况:
如果矩阵的行列式太小,即矩阵接近奇异,则此命令将产生错误。
但为什么矩阵接近奇异?因为我们试图相交的线段几乎是平行的。此时,在我看来,问题的根源似乎是 TeX 的数值精度。然而...
在通过调用 计算线的交点之前\pgfpointintersectionoflines
,\pgfintersectionofpaths
尝试检测线是否相交:这是在\if
-like中完成的\pgfiflinesintersect
。所以我认为问题在于\pgfiflinesintersect
声称线相交,但\pgfpointintersectionoflines
在计算交点时失败。( 的代码\pgf@iflinesintersect
包含一条注释“16384 可能不是一个可靠的选择。”,其中 16384 是某些内部规范化过程中使用的常数。这可能是问题的根源吗?)
进一步研究的行为\pgfintersectionofpaths
后,我意识到它实际上是不一致的。人们期望以下调用\pgfintersectionofpaths
产生相同的结果(1 个交点,原点):
\pgfintersectionofpaths
{\pgfpathmoveto{\pgfpoint{0pt}{0pt}}\pgfpathlineto{\pgfpoint{1pt}{0pt}}}
{\pgfpathmoveto{\pgfpoint{0pt}{0pt}}\pgfpathlineto{\pgfpoint{0pt}{1pt}}}
\pgfintersectionsolutions
\pgfintersectionofpaths
{\pgfpathmoveto{\pgfpoint{0pt}{0pt}}\pgfpathlineto{\pgfpoint{1pt}{0pt}}}
{\pgfpathmoveto{\pgfpoint{0pt}{0pt}}\pgfpathlineto{\pgfpoint{-1pt}{0pt}}}
\pgfintersectionsolutions
然而,事实并非如此:第一个,其中线条垂直,产生 1 个交点,另一个,其中线条(完全)平行,产生 0 个交点。
pgf
我很想修复这个问题,但是这个问题对我来说太复杂了,而且无论如何,我相信它值得讨论,并且应该通知作者。
答案2
我不确定为什么会出现这种情况,但这个错误似乎与所使用的字体有关。
当我使用以下配置编译您的 MWE 时,我可以复制您的错误:
- 无字体规范(Computer/Latin Modern),使用 pdfLaTeX 或 XeLaTeX 编译
\usepackage{palatino}
,使用 pdfLaTeX 或 XeLaTeX 编译\usepackage{libertine}
,使用 pdfLaTeX 或 XeLaTeX 编译\usepackage{fontspec} \setmainfont{Linux Libertine O}
,使用 XeLaTeX 编译\usepackage{fontspec} \setmainfont{Doulos SIL}
,使用 XeLaTeX 编译\usepackage{fontspec} \setmainfont{TeX Gyre Pagella}
,使用 XeLaTeX 编译
但是使用这些配置,它可以编译而不会出现错误:
\usepackage{times}
,使用 pdfLaTeX 或 XeLaTeX 编译\usepackage{kpfonts}
,使用 pdfLaTeX 或 XeLaTeX 编译\usepackage{fontspec} \setmainfont{Charis SIL}
,使用 XeLaTeX 编译\usepackage{fontspec} \setmainfont{Cambria}
,使用 XeLaTeX 编译\usepackage{fontspec} \setmainfont{Brill}
,使用 XeLaTeX 编译\usepackage{fontspec} \setmainfont{Times New Roman}
,使用 XeLaTeX 编译
有了这个,我得到了一个不同的错误(线上尺寸太大\end{forest}
):
\usepackage{fontspec} \setmainfont{TeX Gyre Termes}
,使用 XeLaTeX 编译
因此,如果您正确选择字体,则可以避免错误。不过,就我个人而言,无论选择哪种字体,我还是希望有一个如何避免错误的解释。