這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
ofpgf
的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
,它透過對某個點應用一些座標變換來計算兩條線的交點。上一句中兩個「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編譯
因此,如果你選擇正確的字體,就可以避免這種錯誤。不過,就我個人而言,我仍然希望了解如何避免它,無論字體選擇如何。