森林中的 sn 边和漂亮的空节点样式导致除以零;发生了什么?

森林中的 sn 边和漂亮的空节点样式导致除以零;发生了什么?

forest手动的定义了两种样式:sn edgesnice 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错误。我已将问题追溯到\pgfintersectionofpathspgfintersections。以下代码在没有 的情况下复制了确切的错误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 编译

因此,如果您正确选择字体,则可以避免错误。不过,就我个人而言,无论选择哪种字体,我还是希望有一个如何避免错误的解释。

相关内容