Los bordes sn y los bonitos estilos de nodos vacíos en el bosque conducen a la división por cero; ¿qué está sucediendo?

Los bordes sn y los bonitos estilos de nodos vacíos en el bosque conducen a la división por cero; ¿qué está sucediendo?

Elforestmanualdefine dos estilos: sn edgesy 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 Affse 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 edgesestilo.

Creo que esto no es un error forest, sino más bien un pgferror. He rastreado el problema hasta la biblioteca \pgfintersectionofpathsde . El siguiente código replica el error exacto sin .pgfintersectionsforest

\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. \pgfintersectionofpathsllamadas \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 \pgftransforminvertlo 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, \pgfintersectionofpathsintenta detectar si las líneas se cruzan: esto se hace en \if-like \pgfiflinesintersect. Entonces creo que el problema es que \pgfiflinesintersectafirma que las líneas se cruzan, pero \pgfpointintersectionoflinesfalla durante el cálculo de la intersección. (El código de \pgf@iflinesintersectcontiene 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 \pgfintersectionofpathsprodujeran 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 pgfse 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.

información relacionada