tl;dr

tl;dr

다음 tikz 코드가 화살표 끝을 해당 위치에 배치하는 이유는 무엇입니까?

\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}

잘못 배치된 화살표 끝

이중선을 제거하거나, 라이브러리를 제거하거나 , 의 화살표 팁 대신 bending표준 화살표 팁을 사용 하면 예상되는 동작을 얻습니다 .latexLatexarrows.meta

이중선 없음굽힘 없음라텍스 화살표 팁

그러나 이 세 가지 기능의 조합이 어떻게든 깨지는 것 같습니다. 세 가지 모두를 함께 작동시킬 수 있는 방법이 있나요?

답변1

tl;dr

두 개의 새로운 라인을 추가하여 다음 매크로를 재정의합니다.

\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}

더 긴 이야기

치수는 \pgf@xb화살표 끝의 위치를 ​​기억하는 데 사용됩니다. 그러나 어떤 이유로 \pgfarrows@getid.

따라서 해결 방법은 를 사용하여 \pgf@xc기억한 \pgf@xb다음 \pgf@xb이후에 복구하는 것입니다 \pgfarrows@getid. 원하는 차원 레지스터를 사용할 수 있습니다. 그러나 장기적으로는 새로운 차원을 선언하는 것이 좋습니다.

더 긴 이야기

bending도서관인가 ?

라이브러리가 없으면 bendingxshift는 모든 것을 망치는 그룹 외부에서 수행됩니다 \pgfarrows@getid. 즉, 덮어쓴 항목은 \pgf@xb그룹이 종료되면 사라지므로 올바른 항목 \pgf@xb이 사용됩니다. ( 참조 \pgf@arrow@drawer. 이것은 의 원본 버전입니다 \pgf@draw@curved.)

그러나 bending라이브러리는 xshift를 다르게 처리해야 하는 세 가지 모드를 도입하므로 xshift는 모든 것을 망치는 \ifcase그룹에서 수행됩니다 \pgfarrows@getid.

일부 화살표 팁이 면역되는 이유는 무엇입니까?

일부 화살표 팁은 수학 모드에서 사용하는 것과 중복됩니다. 이 화살표는 PGF/Ti와 무관합니다.케이Z의 매개변수. 간단히 말해서 latex인스턴스입니다.

와 같은 화살표 팁의 경우 PGF/Ti에 대한 일부 계산이 포함됩니다 Latex.\pgfarrows@getid케이Z의 매개변수. 구체적으로 말하면 \pgfarrowslinewidthdependent.

double?

double를 사용하면 계산이 \pgfarrowslinewidthdependent더욱 복잡해지고 덮어쓰기가 되기 때문입니다 \pgf@xb!

답변2

라이브러리 를 로드하면 bending화살표 끝을 그리는 기본 방법이 에서 로 변경 quick됩니다 flex. flex는 에 비해 계산 비용이 더 많이 들지만 quick에 비해 저렴 하며 bend일반적으로 더 나은 결과를 제공합니다. 그러나 항상 그런 것은 아닙니다. quick명시적으로 지정하여 기본값 을 복원할 수 있습니다 .

\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}

화살표 팁

그러나 세 가지 방법 중 어느 것도 훌륭한 결과를 제공하지 못합니다. quick단지 가능한 최선의 해악이 발생할 뿐입니다.

관련 정보