tl;dr

tl;dr

Warum platziert der folgende Tikz-Code die Pfeilspitze dort, wo sie platziert ist?

\documentclass[border=5pt, tikz]{standalone}
\usetikzlibrary{arrows.meta, bending}

\begin{document}
\begin{tikzpicture}
  \draw[-Latex, double] (0:0.5) arc (0:180:0.5);
\end{tikzpicture}

\end{document}

schlecht positionierte Pfeilspitze

Ich erhalte das erwartete Verhalten, wenn ich die Doppellinie entferne, die bendingBibliothek entferne oder die Standardpfeilspitze latexanstelle der LatexPfeilspitze von verwende arrows.meta.

keine Doppelliniekein VerbiegenLatex-Pfeilspitze

Die Kombination dieser drei Funktionen scheint jedoch irgendwie zu scheitern. Gibt es eine Möglichkeit, alle drei zusammenarbeiten zu lassen?

Antwort1

tl;dr

Definieren Sie das folgende Makro neu, indem Sie zwei neue Zeilen hinzufügen:

\documentclass[border=5pt,tikz]{standalone}
\usetikzlibrary{arrows.meta,bending}

\begin{document}

\makeatletter

\def\pgf@draw@curved#1#2{%
  % Prepare:
  {%
    \pgf@xc\pgf@xb          % <--- adding new line
    \pgfarrows@getid{#1}{#2}%
    \pgf@xb\pgf@xc          % <--- adding new line
    % Do shift:
    \expandafter\expandafter\expandafter\pgf@arrow@drawer@rigid@shift\csname pgf@ar@ends@\pgf@arrow@id\endcsname%
    \expandafter\let\expandafter\pgf@arrow@bending@mode\csname pgf@ar@bending@mode@#1\endcsname%
    \ifx\pgf@arrow@bending@mode\pgfutil@empty\let\pgf@arrow@flex@mode\pgf@arrow@mode@is@flex\fi%
    % do swap:
    {%
      \csname pgf@ar@saves@\pgf@arrow@id\endcsname%
      \ifcase\pgf@arrow@flex@mode\relax%
        \expandafter\expandafter\expandafter\pgf@arrow@drawer@rigid\csname pgf@ar@visual@\pgf@arrow@id\endcsname% like flex
      \or%
        \expandafter\expandafter\expandafter\pgf@arrow@drawer@rigid\csname pgf@ar@visual@\pgf@arrow@id\endcsname% 
      \or%
        \expandafter\expandafter\expandafter\pgf@arrow@drawer@rigid\csname pgf@ar@ends@\pgf@arrow@id\endcsname%      
      \or%
        \pgf@arrow@drawer@bend%
      \fi%
      % hull points inside the above
    }%
  \expandafter}%
  % Transform to next tip:
  \expandafter\pgf@xb\the\pgf@xb%
}
\def\pgf@arrow@drawer@rigid@shift#1#2#3{% tip end, back end, line end, sep
  % Let xa be the actual back end of the current arrow plus the back end:
  \advance\pgf@xb by#2%
  \pgf@xa\pgf@xb%
  % Update the xb:
  \pgf@x#1%
  \advance\pgf@x by\pgfarrowsep%
  \advance\pgf@xb by-\pgf@x%
}


\def\pgf@arrow@drawer#1#2{%
  % Prepare:
  {%
    \pgfarrows@getid{#1}{#2}%
    % Do shift:
    \expandafter\expandafter\expandafter\pgf@arrow@drawer@shift\csname pgf@ar@ends@\pgf@arrow@id\endcsname%
    % Do slant:  
    \ifdim\pgfarrows@slant pt=0pt%
    \else%
      \pgftransformxslant{\pgfarrows@slant}%
    \fi%
    % do swap:
    \ifpgfarrowswap%
      \pgftransformyscale{-1}%
    \fi%
    {%
      \csname pgf@ar@saves@\pgf@arrow@id\endcsname%
      \pgfscope%
        \pgf@arrows@color@setup%
        \pgflowlevelsynccm\csname pgf@ar@cache@\pgf@arrow@id\endcsname%
      \endpgfscope%
      \pgf@arrows@rigid@hull%
    }%  
  \expandafter}%
  % Transform to next tip:
  \expandafter\pgftransformxshift\expandafter{\the\pgf@xc}%
}

\def\test#1{\tikz\draw[double,-{#1}](1,0)..controls(1,1)and(0,1)..(0,0);}

\test{Rectangle[length=1,width=5,black]
      Rectangle[length=2,width=4,black!80]
      Rectangle[length=3,width=3,black!60]
      Rectangle[length=4,width=2,black!40]
      Rectangle[length=10,width=1,black!20]}
\test{latex[]}
\test{Straight Barb}
\test{Hooks}
\test{Arc Barb}
\test{Tee Barb}
\test{Classical TikZ Rightarrow}
\test{Computer Modern Rightarrow}
\test{Implies}
\test{Latex}
\test{Stealth}
\test{Kite}
\test{Square}
\test{Circle}
\test{Round Cap}
\test{Butt Cap}
\test{Triangle Cap}
\test{Fast Triangle}
\test{Fast Round}
\test{Rays}

\end{document}

Längere Geschichte

Die Dimension \pgf@xbwird verwendet, um die Positionen der Pfeilspitzen zu speichern. Aus irgendeinem Grund wird sie jedoch durch etwas in überschrieben \pgfarrows@getid.

Ein Workaround besteht darin, \pgf@xczum Erinnern zu verwenden \pgf@xbund anschließend zu reparieren \pgf@xb. \pgfarrows@getidMan kann jedes beliebige Dimensionsregister verwenden. Langfristig ist es jedoch besser, eine neue Dimension zu deklarieren.

Noch längere Geschichte

Warum bendingBibliothek

Ohne bendingBibliothek wird das Xshift außerhalb der Gruppe durchgeführt, was \pgfarrows@getidalles ruiniert. Das heißt, das Überschriebene \pgf@xbwird gelöscht, wenn die Gruppe beendet wird, sodass das Richtige \pgf@xbverwendet wird. (siehe \pgf@arrow@drawer. Dies ist die Originalversion von \pgf@draw@curved.)

Da die Bibliothek jedoch bendingdrei Modi einführt, die eine unterschiedliche Behandlung von Xshift erfordern, wird Xshift in dem ausgeführt, \ifcasedas in der Gruppe liegt, wo \pgfarrows@getidalles ruiniert wird.

Warum sind manche Pfeilspitzen immun?

Einige Pfeilspitzen sind Duplikate der Pfeile, die wir im Mathematikmodus verwenden. Diese Pfeile sind unabhängig von PGF/TikZs Parameter. Kurz gesagt: latexeine Instanz.

Für Pfeilspitzen wie sind einige Berechnungen auf PGF/Ti erforderlich Latex.\pgfarrows@getidkDie Parameter von Z. Genauer gesagt müssen sie ausgeführt werden \pgfarrowslinewidthdependent.

Warum double?

Denn wenn doubleverwendet wird, wird die Berechnung \pgfarrowslinewidthdependentnoch komplexer und \pgf@xbüberschrieben!

Antwort2

Wenn Sie die bendingBibliothek laden, wird die Standardmethode zum Zeichnen von Pfeilspitzen von quickin geändert flex. flexist rechenintensiver als quick, aber weniger aufwendig als bendund liefert normalerweise bessere Ergebnisse. Aber nicht immer. Sie können die quickStandardeinstellung wiederherstellen, indem Sie sie explizit angeben:

\documentclass[border=5pt, tikz]{standalone}
\usetikzlibrary{arrows.meta, bending}

\begin{document}
\begin{tikzpicture}
  \draw[-Latex, double] (0:0.5) arc (0:180:0.5);
  \scoped[yshift=10mm]{\draw[-{Latex[quick]}, double] (0:0.5) arc (0:180:0.5);}
\end{tikzpicture}
\end{document}

Pfeilspitzen

Keine der drei Methoden führt jedoch zu großartigen Ergebnissen – das quickpassiert einfach dem besten der verfügbaren Übel.

verwandte Informationen