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по-видимому, в основном исходит из других, более сложных проблем. Поэтому я хотел бы знать, что для проблемы этих двух дополнительных серых линий, существует ли более простое решение на данный момент?

Ниже представлен MWE, в который я скопировал код nRightarrowиз связанного вопроса.

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

введите описание изображения здесь

Связанный контент