bordas sn e bons estilos de nós vazios na floresta levam à divisão por zero; o que está acontecendo?

bordas sn e bons estilos de nós vazios na floresta levam à divisão por zero; o que está acontecendo?

Oforestmanualdefine dois estilos: sn edgese 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 Afffolha 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 edgesestilo.

Acredito que isso não seja um forest, mas sim um pgfbug. Rastreei o problema até a biblioteca \pgfintersectionofpathsde . O código a seguir replica o erro exato sem .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}}}

Eu investiguei o assunto um pouco mais. \pgfintersectionofpathschama \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. É \pgftransforminverto 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, \pgfintersectionofpathstenta detectar se as linhas se cruzam: isso é feito no \if-like \pgfiflinesintersect. Então acredito que o problema é que \pgfiflinesintersectafirma que as linhas se cruzam, mas \pgfpointintersectionoflinesfalha durante o cálculo da interseção. (O código \pgf@iflinesintersectconté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 \pgfintersectionofpathsproduzissem 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 pgfdeva 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.

informação relacionada