森林中的 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錯誤。我已將問題追溯到\pgfintersectionofpathsofpgfintersections庫。以下程式碼複製了確切的錯誤,但沒有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,它透過對某個點應用一些座標變換來計算兩條線的交點。上一句中兩個「some」的數學細節並不重要,除了 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 時,我可以複製您的錯誤:

  • 無字體規格(電腦/拉丁現代),使用 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編譯

因此,如果你選擇正確的字體,就可以避免這種錯誤。不過,就我個人而言,我仍然希望了解如何避免它,無論字體選擇如何。

相關內容