tikz-cd:帶有右箭頭的額外灰線

tikz-cd:帶有右箭頭的額外灰線

起初我以為這是我的pdf閱讀器的問題。例如,使用程式碼

\documentclass{article}
\usepackage{tikz-cd}
\begin{document}

\begin{tikzcd}
    A & B
    \arrow[Rightarrow, from=1-1, to=1-2]
\end{tikzcd}

\end{document}

結果Rightarrow似乎包含兩條額外的小灰線:

在此輸入影像描述

該問題已在這個問題幾個月前,作者提供了一個複雜的新樣式nRightarrow,似乎可以解決這個問題(Rightarrow上、nRightarrow下):

在此輸入影像描述

然而,對這種新風格的需求nRightarrow似乎主要來自其他更複雜的問題。那麼我想知道,針對這兩條多餘的灰線的問題,目前是否有更簡單的解決方案?

nRightarrow下面是一個 MWE,我在其中複製了連結問題的程式碼。

\documentclass{article}
\usepackage{tikz-cd}
\usetikzlibrary{calc}

\newlength{\eqoffset}
\makeatletter
% relative coordinates: (0,0) is the arrow's tail, x points towards the head,
% y points perpendicular, unit distance is \eqoffset
\newcommand{\relptstart}[2]{($($(k0)!#1*\eqoffset+\pgf@shorten@start@additional!0:(k1)$)!#2*\eqoffset!90:(k1)$)}
% (0,0) is the arrow's tip, rest is the same
\newcommand{\relptend}[2]{($($(k1)!#1*\eqoffset-\pgf@shorten@end@additional
    -2*\eqoffset-.5*\pgflinewidth!180:(k0)$)!#2*\eqoffset!-90:(k0)$)}
\tikzcdset{
    nRightarrow/.style={line join=round,
    no head,
    /tikz/commutative diagrams/@shiftabletopath,
    execute at begin to = {
        % Do not use tikzcd@noda or tikzcd@x here, it causes interference.
        % Use new names instead
        \path (\tikztostart) -- (\tikztotarget) coordinate[pos=0] (k0) coordinate[pos=1] (k1);
        \pgfpointnormalised{\pgfpointdiff{\pgfpointanchor{k1}{center}}{\pgfpointanchor{k0}{center}}}
        \pgfgetlastxy{\kdx}{\kdy}
        \tikzset{
        to path={
            % arrow body
            % the .06 is from \pgftransformxshift{.06\pgfutil@tempdima}
            \relptstart{0}{1}
            -- \relptend{-.06}{1}
            {
                % correct vertical position, more central horizontal position
                %               [xshift=-\kdy*\eqoffset, yshift=\kdx*\eqoffset]
                % matches original Rightarrow more closely
                [xshift=-\kdy*\eqoffset-\kdx*(\eqoffset+.25*\pgflinewidth),
                yshift=\kdx*\eqoffset-\kdy*(\eqoffset+.25*\pgflinewidth)] 
                \tikztonodes}
            \relptstart{0}{-1}
            -- \relptend{-.06}{-1}
            % arrow tip
            % fake the round cap by using round joins and drawing the path twice with a turnaround at the caps
            \relptend{2}{0}         % tip to top end
            .. controls \relptend{1}{0.05} and \relptend{-0.75}{1.25} ..
            \relptend{-1.4}{2.65}   % top end back to tip
            .. controls \relptend{-0.75}{1.25} and \relptend{1}{0.05} ..
            \relptend{2}{0}         % tip to bottom end
            .. controls \relptend{1}{-0.05} and \relptend{-0.75}{-1.25} ..
            \relptend{-1.4}{-2.65}  % bottom end back to tip
            .. controls \relptend{-0.75}{-1.25} and \relptend{1}{-0.05} ..
            \relptend{2}{0}
            % Add a degenerate path segment at the end so shorten < and shorten > are not applied again
            (k1)
        }}
    }}
}
\setlength{\eqoffset}{.225ex}
\makeatother


\begin{document}

\begin{tikzcd}[column sep=large]
    A & B
    \arrow[Rightarrow, from=1-1, to=1-2]
\end{tikzcd}

\begin{tikzcd}[column sep=large]
    A & B
    \arrow[nRightarrow, from=1-1, to=1-2]
\end{tikzcd}

\end{document}

答案1

連結的問題源自於一個冗長的討論與 TikZ-CD 的作者討論如何重新實現平行線。代碼好像差不多達到 PGF 級別

這裡沒有重新實現 PGF 繪製線條的方式,而是關於如何稍微改變 PGF 繪製線條的double方式的概念證明double

  • 要么通過延長內線
  • 或透過縮短外線。

這遠非完美,但最適合

  • 直線
  • 由一段組成(一開始只有一個移動),
  • 不是虛線並使用普通rect線帽。

此外,箭頭最好不要接觸繪製的節點。

spath3庫可以幫助使(不)縮短不會扭曲曲線,並且還可以幫助將其應用於具有多個段的路徑。

程式碼

\documentclass[tikz]{standalone}
\usepackage{tikz-cd}
\makeatletter
\def\pgf@double@cheat#1{%
  \let\pgf@tips@mode\pgf@tips@mode@false
  \pgfsetarrowsstart{}\pgfsetarrowsend{}%
  \pgfsetshortenstart{#1}\pgfsetshortenend{#1}%
  \pgf@prepare@end@of@path\pgf@prepare@start@of@path}
\pgfset{
  shorten outer/.code=%
    \pgfmathsetlength\pgfutil@tempdima{#1}%
    \pgfkeyssetevalue{/pgf/shorten outer}{\the\pgfutil@tempdima},
  shorten outer=+0pt,
  unshorten inner/.code=%
    \pgfmathsetlength\pgfutil@tempdima{#1}%
    \pgfkeyssetevalue{/pgf/unshorten inner}{\the\pgfutil@tempdima},
  unshorten inner=+0pt}
\usepackage{etoolbox}
\patchcmd{\pgf@stroke@inner@line}{\pgfsyssoftpath@invokecurrentpath}{%
    \ifdim\pgfkeysvalueof{/pgf/unshorten inner}>0pt
      \pgf@double@cheat{-\pgfkeysvalueof{/pgf/unshorten inner}}%
    \fi\pgfsyssoftpath@invokecurrentpath}{}{\PatchFailed}

\patchcmd{\pgfusepath}{\fi\pgfsyssoftpath@invokecurrentpath\pgf@up@action}{%
  \fi \ifdim\pgfinnerlinewidth>0pt
        \ifdim\pgfkeysvalueof{/pgf/shorten outer}>0pt
          \pgfgetpath\pgf@temppath
          \pgf@double@cheat{\pgfkeysvalueof{/pgf/shorten outer}}\fi\fi
      \pgfsyssoftpath@invokecurrentpath%
      \ifdim\pgfinnerlinewidth>0pt
        \ifdim\pgfkeysvalueof{/pgf/shorten outer}>0pt
          \pgfsetpath\pgf@temppath\fi\fi\pgf@up@action}{}{\PatchFailed}
\makeatother
\newcommand*\everycell[1]{%
  \draw[cd=Rightarrow,#1]node(A){$A$}node(B)at(2,0){$B$}(A)to(B);}
\begin{document}
\tikz[
  cd/.code=\tikzcdset{#1}, anchor=base,
  cd dbl/.style={cd={background color=green}},
  cells={nodes={behind path, help lines, draw, shape=asymmetrical rectangle}},
  column 1/.append style={anchor=base west, nodes=path only},
  rows/.style args={#1 => #2}{row #1/.append style={#2}},
  rows/.list={2 => unshorten inner = .05pt,
              3 => shorten outer = .05pt,
              4 => {cd dbl=green, unshorten inner = 2pt},
              5 => {cd dbl=green, shorten outer = 2pt}}
]\matrix[column sep=\tabcolsep]{
 \node{normal:};        & \everycell{} & \everycell{bend left} \\
 \node{inner:};         & \everycell{} & \everycell{bend left} \\
 \node{outer:};         & \everycell{} & \everycell{bend left} \\
 \node{extreme inner:}; & \everycell{} & \everycell{bend left} \\
 \node{extreme outer:}; & \everycell{} & \everycell{bend left} \\};

\begin{tikzcd}[unshorten inner=+0.01pt]
    A & B
    \arrow[Rightarrow, from=1-1, to=1-2]
\end{tikzcd}
\end{document}

輸出

在這種情況下,最好自己編譯並使用不同的縮放等級和不同的 PDF 檢視器/渲染器來查看輸出。不過,您可以點擊前兩張圖片來查看它的放大版本。

在此輸入影像描述如上所述,但帶有繪製的節點

在此輸入影像描述

答案2

我寫tikz-nfold專門解決這個問題:

\documentclass{article}

\usepackage{tikz}
\usetikzlibrary{cd}
\usetikzlibrary{nfold}

\begin{document}

\begin{tikzcd}
    A & B
    \arrow[Rightarrow, from=1-1, to=1-2, nfold]
\end{tikzcd}

\end{document}

順便說一句,作者tikz-cd最近通知我\usepackage{tikz-cd}是一個遺留功能,儘管使用它並沒有什麼問題。

答案3

如果您使用xy交換圖的包,則箭頭尾部沒有垂直線或平行線。

\documentclass[a4paper,12pt]{article}
\usepackage[all,cmtip]{xy}

\begin{document}
\xymatrix@C=3pc{A \ar@{=>}[r]& B}
\end{document}

在此輸入影像描述

相關內容