弯曲的双箭头“A la chef”

弯曲的双箭头“A la chef”

我非常喜欢双箭头的风格“厨师”。我想将它们用于框图,但我意识到它们似乎不能很好地处理使用命令等获得的非线性路径to[in=#,out=#]。例如,此代码

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{calc}
\usepackage{verbatim}
\usepackage[active,tightpage]{preview}
\PreviewEnvironment{tikzpicture}
\setlength{\PreviewBorder}{10pt}%
\usetikzlibrary{arrows, decorations.markings}
% for double arrows a la chef
% adapt line thickness and line width, if needed
\tikzstyle{vecArrow} = [thick, decoration={markings,mark=at position
   1 with {\arrow[semithick]{open triangle 60}}},
   double distance=1.4pt, shorten >= 5.5pt,
   preaction = {decorate},
   postaction = {draw,line width=1.4pt, white,shorten >= 4.5pt}]
\tikzstyle{innerWhite} = [semithick, white,line width=1.4pt, shorten >= 4.5pt]

\begin{document}
\begin{tikzpicture}[thick]
  \node[draw,rectangle] (a) {A};
  \node[inner sep=0,minimum size=0,right of=a] (k) {}; % invisible node
  \node[draw,rectangle,right of=k] (b) {B};
  \node[draw,rectangle,below of=a] (c) {C};

  % 1st pass: draw arrows
  \draw[vecArrow] (a) to (b);
  \draw[vecArrow] (k) to[out=-90,in=0] (c);
  \draw[vecArrow] (a) to[out=90,in=90] (b);

  % 2nd pass: copy all from 1st pass, and replace vecArrow with innerWhite
  \draw[innerWhite] (a) to (b);
  \draw[innerWhite] (k) to[out=-90,in=0] (c);
  \draw[innerWhite] (a) to[out=90,in=90] (b);

  % Note: If you have no branches, the 2nd pass is not needed
\end{tikzpicture}
\end{document}

得出这个结果

在此处输入图片描述

甚至看不到箭头。

还有什么想法可以让这种风格与弯曲的线条保持一致吗?

答案1

众所周知在曲率较大的情况下装饰可能会消失如果它们位于路径末尾。因此,一个可能的解决方法是用 替换at position 1。(切换到,感谢@gbernardi!)at position 0.99at position 0.9990.999

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{calc}
\usepackage{verbatim}
\usepackage[active,tightpage]{preview}
\PreviewEnvironment{tikzpicture}
\setlength{\PreviewBorder}{10pt}%
\usetikzlibrary{arrows, decorations.markings}
% for double arrows a la chef
% adapt line thickness and line width, if needed
\tikzset{vecArrow/.style={thick, decoration={markings,mark=at position
   0.999 with {\arrow[semithick]{open triangle 60}}},
   double distance=1.4pt, shorten >= 5.5pt,
   preaction = {decorate},
   postaction = {draw,line width=1.4pt, white,shorten >= 4.5pt}},
innerWhite/.style={semithick, white,line width=1.4pt, shorten >= 4.5pt}}

\begin{document}
\begin{tikzpicture}[thick]
  \node[draw,rectangle] (a) {A};
  \node[inner sep=0,minimum size=0,right of=a] (k) {}; % invisible node
  \node[draw,rectangle,right of=k] (b) {B};
  \node[draw,rectangle,below of=a] (c) {C};

  % 1st pass: draw arrows
  \draw[vecArrow] (a) to (b);
  \draw[vecArrow] (k) to[out=-90,in=0] (c);
  \draw[vecArrow] (a) to[out=90,in=90] (b);

  % 2nd pass: copy all from 1st pass, and replace vecArrow with innerWhite
  \draw[innerWhite] (a) to (b);
  \draw[innerWhite] (k) to[out=-90,in=0] (c);
  \draw[innerWhite] (a) to[out=90,in=90] (b);

  % Note: If you have no branches, the 2nd pass is not needed
\end{tikzpicture}
\end{document}

在此处输入图片描述

或者,您可以使用outlined arrow装饰

\documentclass[tikz,border=3.14mm]{standalone}
\usetikzlibrary{decorations,decorations.text} %  decorations.text just 4 fun

\usetikzlibrary{decorations,decorations.text} %  decorations.text just 4 fun
\pgfkeys{/tikz/.cd,
    outlined arrow width/.store in=\OutlinedArrowWidth,
    outlined arrow width=5pt,
    outlined arrow step/.store in=\OutlinedArrowStep,
    outlined arrow step=1pt,
    outlined arrow length/.store in=\OutlinedArrowLength,
    outlined arrow length=5pt,
}

\pgfdeclaredecoration{outlined arrow}{initial}
{% initial arrow butt
\state{initial}[width=\OutlinedArrowStep,next state=cont] {
    \pgfmoveto{\pgfpoint{\OutlinedArrowStep}{\OutlinedArrowWidth/2}}
    \pgfpathlineto{\pgfpoint{0.3\pgflinewidth}{\OutlinedArrowWidth/2}}
    \pgfpathlineto{\pgfpoint{0.3\pgflinewidth}{-\OutlinedArrowWidth/2}}
    \pgfpathlineto{\pgfpoint{1pt}{-\OutlinedArrowWidth/2}}
    \pgfcoordinate{lastup}{\pgfpoint{1pt}{\OutlinedArrowWidth/2}}
    \pgfcoordinate{lastdown}{\pgfpoint{1pt}{-\OutlinedArrowWidth/2}}
    \xdef\marmotarrowstart{0}
  }
  \state{cont}[width=\OutlinedArrowStep]{
    \ifdim\pgfdecoratedremainingdistance>\OutlinedArrowLength% continue the outlined path
     \pgfmoveto{\pgfpointanchor{lastup}{center}}
     \pgfpathlineto{\pgfpoint{\OutlinedArrowStep}{\OutlinedArrowWidth/2}}
     \pgfcoordinate{lastup}{\pgfpoint{\OutlinedArrowStep}{\OutlinedArrowWidth/2}}
     \pgfmoveto{\pgfpointanchor{lastdown}{center}}
     \pgfpathlineto{\pgfpoint{\OutlinedArrowStep}{-\OutlinedArrowWidth/2}}
     \pgfcoordinate{lastdown}{\pgfpoint{\OutlinedArrowStep}{-\OutlinedArrowWidth/2}}
    \else
     \ifnum\marmotarrowstart=0% draw the arrow head
     \pgfmoveto{\pgfpointadd{\pgfpointanchor{lastup}{center}}{\pgfpoint{-0.5\pgflinewidth}{0}}}
     \pgflineto{\pgfpoint{-0.5\pgflinewidth}{\OutlinedArrowWidth}}
     \pgflineto{\pgfpointadd{\pgfpointdecoratedpathlast}{\pgfpoint{-0.5\pgflinewidth}{0}}}
     \pgflineto{\pgfpoint{-0.5\pgflinewidth}{-\OutlinedArrowWidth}}
     \pgflineto{\pgfpointadd{\pgfpointanchor{lastdown}{center}}{\pgfpoint{-0.5\pgflinewidth}{0}}}
     \xdef\marmotarrowstart{1}
     \else
     \fi
    \fi%
  }
  \state{final}[width=5pt]
  { % perhaps unnecessary but doesn't hurt either
    \pgfmoveto{\pgfpointdecoratedpathlast}
  }
}
\begin{document}
\begin{tikzpicture}[thick,decoration=outlined arrow]
  \node[draw,rectangle] (a) {A};
  \node[inner sep=0,minimum size=0,right of=a] (k) {}; % invisible node
  \node[draw,rectangle,right of=k] (b) {B};
  \node[draw,rectangle,below of=a] (c) {C};
  \draw[decorate] (a) to (b);
  \draw[decorate] (k) to[out=-90,in=0] (c);
  \draw[decorate] (a) to[out=90,in=90] (b);
  \draw[white,line width=4pt,shorten <=1pt,shorten >=4pt] (a) to (b);
  \draw[white,line width=4pt] (k) -- ++(0,-4pt);
\end{tikzpicture}  
\end{document}

在此处输入图片描述

相关内容