Elforest
manualdefine dos estilos: sn edges
y nice empty nodes
. Se definen como:
sn edges/.style={for tree={parent anchor=south, child anchor=north}}
y
nice empty nodes/.style={for tree={calign=fixed edge angles},delay={where content={}{shape=coordinate,for parent={for children={anchor=north}}}{}} }
respectivamente.
Cuando ambos estilos se usan con el siguiente árbol, aparece el siguiente error:
! 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}
¿Alguien sabe qué está pasando? ¿Cómo puedo arreglar esto?
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}
Actualizar
Curiosamente, se compila sin errores si Aff
se elimina todo lo que está debajo de la hoja. Es decir, se compilará lo siguiente:
\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}
Respuesta1
Primero, una observación: el error ocurre incluso sin sn edges
estilo.
Creo que esto no es un error forest
, sino más bien un pgf
error. He rastreado el problema hasta la biblioteca \pgfintersectionofpaths
de . El siguiente código replica el error exacto sin .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}}}
He investigado el asunto un poco más. \pgfintersectionofpaths
llamadas \pgfpointintersectionoflines
, que calcula la intersección de dos líneas aplicando alguna transformación de coordenadas a algún punto. Los detalles matemáticos de los dos "algunos" en la oración anterior no son importantes, excepto por el hecho de que el paso final en el cálculo de PGF de la matriz de transformación relevante es la inversión de alguna otra matriz, llamando a \pgftransforminvert
. Es \pgftransforminvert
lo que falla, ya que la matriz que intenta invertir es casi singular. El manual de PGF (p. 641) advierte que esto sucederá:
Este comando producirá un error si el determinante de la matriz es demasiado pequeño, es decir, si la matriz es casi singular.
Pero ¿por qué la matriz es casi singular? Porque los segmentos de línea que intentamos cruzar son casi paralelos. En este punto me pareció que la fuente del problema era la precisión numérica de TeX. Sin embargo ...
Antes de calcular la intersección de líneas llamando \pgfpointintersectionoflines
, \pgfintersectionofpaths
intenta detectar si las líneas se cruzan: esto se hace en \if
-like \pgfiflinesintersect
. Entonces creo que el problema es que \pgfiflinesintersect
afirma que las líneas se cruzan, pero \pgfpointintersectionoflines
falla durante el cálculo de la intersección. (El código de \pgf@iflinesintersect
contiene un comentario "16384 puede no ser una opción sólida", donde 16384 es una constante utilizada en algún proceso de normalización interna. ¿Podría ser esta la fuente del problema?)
Al investigar aún más el comportamiento \pgfintersectionofpaths
, me di cuenta de que en realidad es inconsistente. Se esperaría que las siguientes llamadas de \pgfintersectionofpaths
produjeran el mismo resultado (1 intersección, el origen):
\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
Sin embargo, este no es el caso: el primero, donde las líneas son perpendiculares, produce 1 intersección, el otro, donde las líneas son (exactamente) paralelas, produce 0 intersecciones.
Me encantaría solucionar este problema, pero el problema me parece demasiado complejo y, de todos modos, creo que merece un poco de discusión y que pgf
se debe notificar al autor de.
Respuesta2
No estoy seguro de por qué podría ser así, pero este error parece estar relacionado con la fuente que se utiliza.
Puedo replicar su error cuando compilo su MWE usando las siguientes configuraciones:
- sin especificación de fuente (Computer/Latin Modern), compilado con pdfLaTeX o XeLaTeX
\usepackage{palatino}
, compilado con pdfLaTeX o XeLaTeX\usepackage{libertine}
, compilado con pdfLaTeX o XeLaTeX\usepackage{fontspec} \setmainfont{Linux Libertine O}
, compilado con XeLaTeX\usepackage{fontspec} \setmainfont{Doulos SIL}
, compilado con XeLaTeX\usepackage{fontspec} \setmainfont{TeX Gyre Pagella}
, compilado con XeLaTeX
Pero con estas configuraciones, se compila sin el error:
\usepackage{times}
, compilado con pdfLaTeX o XeLaTeX\usepackage{kpfonts}
, compilado con pdfLaTeX o XeLaTeX\usepackage{fontspec} \setmainfont{Charis SIL}
, compilado con XeLaTeX\usepackage{fontspec} \setmainfont{Cambria}
, compilado con XeLaTeX\usepackage{fontspec} \setmainfont{Brill}
, compilado con XeLaTeX\usepackage{fontspec} \setmainfont{Times New Roman}
, compilado con XeLaTeX
Con este, recibí un error diferente (Dimensión demasiado grande en la \end{forest}
línea):
\usepackage{fontspec} \setmainfont{TeX Gyre Termes}
, compilado con XeLaTeX
Entonces, si eliges bien la fuente, puedes evitar el error. Personalmente, preferiría recibir una explicación de cómo evitarlo, independientemente de la selección de fuente.