Oforest
manualdefine dois estilos: sn edges
e nice empty nodes
. Eles são definidos como:
sn edges/.style={for tree={parent anchor=south, child anchor=north}}
e
nice empty nodes/.style={for tree={calign=fixed edge angles},delay={where content={}{shape=coordinate,for parent={for children={anchor=north}}}{}} }
respectivamente.
Quando esses dois estilos são usados com a árvore a seguir, recebo o seguinte erro:
! 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}
Alguém sabe o que está acontecendo? Como posso consertar isso?
MWE
\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}
Atualizar
Curiosamente, ele compila sem erros se tudo abaixo da Aff
folha for excluído. Ou seja, o seguinte será compilado:
\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}
Responder1
Primeiramente, uma observação: o erro ocorre mesmo sem sn edges
estilo.
Acredito que isso não seja um forest
, mas sim um pgf
bug. Rastreei o problema até a biblioteca \pgfintersectionofpaths
de . O código a seguir replica o erro exato sem .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}}}
Eu investiguei o assunto um pouco mais. \pgfintersectionofpaths
chama \pgfpointintersectionoflines
, que calcula a intersecção de duas linhas aplicando alguma transformação de coordenadas a algum ponto. Os detalhes matemáticos dos dois "alguns" na frase anterior não são importantes, exceto pelo fato de que a etapa final no cálculo da matriz de transformação relevante pelo PGF é a inversão de alguma outra matriz, chamando \pgftransforminvert
. É \pgftransforminvert
o que falha, pois a matriz que está tentando inverter é quase singular. O manual da PGF (p. 641) avisa que isso vai acontecer:
Este comando produzirá um erro se o determinante da matriz for muito pequeno, ou seja, se a matriz for quase singular.
Mas por que a matriz é quase singular? Porque os segmentos de reta que estamos tentando cruzar são quase paralelos. Neste ponto, pareceu-me que a origem do problema era a precisão numérica do TeX. No entanto ...
Antes de calcular a interseção das linhas chamando \pgfpointintersectionoflines
, \pgfintersectionofpaths
tenta detectar se as linhas se cruzam: isso é feito no \if
-like \pgfiflinesintersect
. Então acredito que o problema é que \pgfiflinesintersect
afirma que as linhas se cruzam, mas \pgfpointintersectionoflines
falha durante o cálculo da interseção. (O código \pgf@iflinesintersect
contém uma observação "16384 pode não ser uma escolha robusta.", onde 16384 é uma constante usada em algum processo de normalização interna. Esta poderia ser a origem do problema?)
Investigando ainda mais o comportamento \pgfintersectionofpaths
, percebi que na verdade ele é inconsistente. Seria de se esperar que as seguintes chamadas \pgfintersectionofpaths
produzissem o mesmo resultado (1 interseção, a origem):
\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
Porém, este não é o caso: o primeiro, onde as linhas são perpendiculares, produz 1 interseção, o outro, onde as linhas são (exatamente) paralelas, produz 0 interseções.
Eu adoraria consertar isso, mas o problema parece muito complexo para mim e, de qualquer forma, acredito que merece alguma discussão e que o autor pgf
deva ser notificado.
Responder2
Não sei por que isso acontece, mas esse erro parece estar relacionado à fonte usada.
Posso replicar seu erro ao compilar seu MWE usando as seguintes configurações:
- sem especificação de fonte (Computer/Latin Modern), compilado com pdfLaTeX ou XeLaTeX
\usepackage{palatino}
, compilado com pdfLaTeX ou XeLaTeX\usepackage{libertine}
, compilado com pdfLaTeX ou XeLaTeX\usepackage{fontspec} \setmainfont{Linux Libertine O}
, compilado com XeLaTeX\usepackage{fontspec} \setmainfont{Doulos SIL}
, compilado com XeLaTeX\usepackage{fontspec} \setmainfont{TeX Gyre Pagella}
, compilado com XeLaTeX
Mas com essas configurações ele compila sem erro:
\usepackage{times}
, compilado com pdfLaTeX ou XeLaTeX\usepackage{kpfonts}
, compilado com pdfLaTeX ou XeLaTeX\usepackage{fontspec} \setmainfont{Charis SIL}
, compilado com XeLaTeX\usepackage{fontspec} \setmainfont{Cambria}
, compilado com XeLaTeX\usepackage{fontspec} \setmainfont{Brill}
, compilado com XeLaTeX\usepackage{fontspec} \setmainfont{Times New Roman}
, compilado com XeLaTeX
Com este, recebi um erro diferente (Dimensão muito grande na \end{forest}
linha):
\usepackage{fontspec} \setmainfont{TeX Gyre Termes}
, compilado com XeLaTeX
Portanto, se você escolher a fonte certa, poderá evitar o erro. Pessoalmente, eu ainda preferiria ter uma explicação de como evitá-lo, independentemente da seleção da fonte.