tikz-cd:带有 Rightarrow 的额外灰线

tikz-cd:带有 Rightarrow 的额外灰线

一开始我以为这是我的 pdf viewer 的问题。例如,代码如下

\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 绘制线条的方式之外,double这里还有一个关于如何稍微改变 PGF 绘制线条方式的概念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}

在此处输入图片描述

相关内容