6

I can find fat arrows and thin arrows,

I can find fancy curly arrows that start thin and get fat,

All I want is a basic arrow that is thick at the origin, and thin at the other end, indicating that we are going "from" a "larger" space "to" a smaller space.

For use in something like a commutative diagram.

Does tikz have any such thing?

enter image description here

enter image description here

MairAW
  • 128
  • 7
  • 2
    Is this supposed to be a shape like one of those from the shapes.arrows? Or should it be a path, connecting two coordinates or nodes? TikZ doesn't really support variable line width in one path (but solutions exist). But in this simple case it could be replicated by drawing the area itself. – Qrrbrbirlbel Oct 26 '22 at 12:06
  • Well, a path, I suppose. But in the commutative diagram library, I can just draw my arrow with \arrow. I've added a hand-drawn picture of the diagram I was trying to draw (ignore the squiggly red line). – MairAW Oct 26 '22 at 12:50
  • I had seen the solutions you link, but they all seem overcomplicated for what I wanted to do. I think if I wanted to design my own arrow, I could just do it by drawing two slightly offset arrows with one-sided heads. I was hoping there might be a solution without having to design my own though... – MairAW Oct 26 '22 at 12:55
  • you can define a pic for your arrow, then use \path (A)--(B) pic[sloped,midway]{myarrow}; – Black Mild Oct 26 '22 at 14:15

3 Answers3

14

Well, it's not perfect but maybe this can get you started:

enter image description here

Basically I just made an arrow tip with Latex followed by Triangle, and then used it as a decoration on the arrow line (which is drawn in white).

\documentclass{article}

\usepackage{tikz-cd} \usetikzlibrary{decorations.markings}

\tikzset{mytip/.tip={Latex[{color=black, fill=white, length=5mm, width=1.5mm, sep=-.9mm}]Triangle[color=black, fill=white]}, myarrow/.style={white, decoration={transform={xshift=2.75mm}, markings, mark=at position .5 with {\arrow{mytip}}}, postaction=decorate} }

\begin{document}

\begin{tikzcd}[arrows={myarrow}] K\arrow[dr]\ \Omega\arrow[u]\arrow[r] & k \end{tikzcd}

\end{document}

Sandy G
  • 42,558
11

You second sketch is much easier to implement, I believe.

Idea:

  1. Get the length of the path. (This only permits one segment, i.e. one line-to or one curve-to.)
  2. Use that length to set the length of the second arrow tip.

Unfortunately, when the Triangle tip becomes too sharp the head gets beveled off but the arrow tip defintion doesn't account for that and adjust the drawing which is why I'm using line join=round here for both parts.
Though, PGF still uses the length calculations as if the sharp angle would be drawn mitered.

Since I'm not in the mood to do the math to adjust for the lost length, I'm just using a factor of 1.1 to stretch the second tip to about its needed length. This works well enough in this example for straight lines and not so good for curved path (with bending). But that's partly the reason why I'm using draw=none (via \tikz@mode@drawfalse) to force the (remaining) line not be drawn.

Code

\documentclass[tikz]{standalone}
\usetikzlibrary{decorations,bending}
\usepackage{tikz-cd}
\makeatletter
\tikzset{
  ararrow/.default={open}{open},
  ararrow/.code 2 args={%
    \tikz@addoption{%
       \pgfset{tips=true}% draw tips even if the path isn't.
       \pgfgetpath\currentpath
       \pgfprocessround{\currentpath}{\currentpath}%
       \pgf@decorate@parsesoftpath{\currentpath}{\currentpath}%
       \pgfsetarrowsend{%. % dot not really needed when no line is drawn
         Triangle[
           length=1.1*(\pgf@decorate@totalpathlength-4pt+.5*\the\pgflinewidth),
           line join=round,#1]
         Triangle[angle'=60,length=+4pt,line join=round,#2]}%
       \tikz@mode@drawfalse % disable drawing of path
    }
  },
  ararrow **/.style={ararrow={}{}},     ararrow oo/.style={ararrow={open}{open}},
  ararrow *o/.style={ararrow={}{open}}, ararrow o*/.style={ararrow={open}{}},
}
\makeatother
\begin{document}
\begin{tikzcd}[/tikz/arrows={[bend]}]
 K \drar[ararrow o*] \ar[dr, ararrow **, controls={+(1.5,0.5) and +(1,0.8)}] \\
 \Omega \rar[ararrow] \uar[ararrow o*] & k
\end{tikzcd}
\end{document}

Output

enter image description here

Qrrbrbirlbel
  • 119,821
9

You can create your own custom decoration. With the following, you can use options to customize the appearance of the arrow as described in the picture below.

\documentclass[border=10pt]{standalone}
\usepackage{tikz}
\usetikzlibrary{decorations}

\newlength{\tailarrowtiplength} \setlength{\tailarrowtiplength}{1em} \newlength{\tailarrowtipwidth} \newlength{\tailarrowtailwidth} \newlength{\tailarrowjointwidth}

\pgfdeclaredecoration{tail arrow decoration}{initial}{ \state{initial}[width=\pgfdecoratedpathlength, next state=final] { \pgfpathlineto{\pgfpoint{0pt}{0.5\tailarrowtailwidth}} \pgfpathlineto{\pgfpointadd{\pgfpointdecoratedpathlast}{\pgfpoint{-1\tailarrowtiplength}{0.5\tailarrowjointwidth}}} \pgfpathlineto{\pgfpointadd{\pgfpointdecoratedpathlast}{\pgfpoint{-1\tailarrowtiplength}{0.5\tailarrowtipwidth}}} \pgfpathlineto{\pgfpointdecoratedpathlast} \pgfpathlineto{\pgfpointadd{\pgfpointdecoratedpathlast}{\pgfpoint{-1\tailarrowtiplength}{-0.5\tailarrowtipwidth}}} \pgfpathlineto{\pgfpointadd{\pgfpointdecoratedpathlast}{\pgfpoint{-1\tailarrowtiplength}{-0.5\tailarrowjointwidth}}} \pgfpathlineto{\pgfpoint{0pt}{-0.5\tailarrowtailwidth}} \pgfpathclose } \state{final} { \pgfpathmoveto{\pgfpointdecoratedpathlast} } }

\tikzset{ tail arrow tip length/.code={ \setlength{\tailarrowtiplength}{#1} }, tail arrow tip width/.code={ \setlength{\tailarrowtipwidth}{#1} }, tail arrow tail width/.code={ \setlength{\tailarrowtailwidth}{#1} }, tail arrow joint width/.code={ \setlength{\tailarrowjointwidth}{#1} }, tail arrow tip length/.default={ 2em }, tail arrow tip width/.default={ 2em }, tail arrow tail width/.default={ 1em }, tail arrow joint width/.default={ .2em }, tail arrow/.style={ tail arrow tip length, tail arrow tip width, tail arrow tail width, tail arrow joint width, decorate, decoration={tail arrow decoration} } }

\begin{document} \begin{tikzpicture}

\draw[tail arrow, tail arrow tip width=4em, tail arrow tip length=1em, tail arrow joint width=0.5em] (0,-1) -- (5,-2);

\draw[tail arrow] (0,0) -- (5,0);

% description of options

\draw[|-|, red] ([shift={(-2em,-1.5em)}]5,0) -- ([shift={(0em,-1.5em)}]5,0) node[below, midway, font=\ttfamily\scriptsize, align=center] {tail arrow \ tip length};

\draw[|-|, red] ([shift={(0.5em,-1em)}]5,0) -- ([shift={(0.5em,1em)}]5,0) node[right, midway, font=\ttfamily\scriptsize, align=left] {tail arrow \ tip width};

\draw[|-|, red] ([shift={(-2.5em,-0.1em)}]5,0) -- ([shift={(-2.5em,0.1em)}]5,0) node[above left, pos=0, font=\ttfamily\scriptsize, align=right] {tail arrow \ joint width};

\draw[|-|, red] ([shift={(-0.5em,-0.5em)}]0,0) -- ([shift={(-0.5em,0.5em)}]0,0) node[left, midway, font=\ttfamily\scriptsize, align=right] {tail arrow \ tail width};

\end{tikzpicture} \end{document}

enter image description here

Applied in a tikzcd context, you could then do:

\documentclass[border=10pt]{standalone}
\usepackage{tikz-cd}
\usetikzlibrary{decorations}

% [above definitions]

\begin{document}

\begin{tikzcd}[arrows={tail arrow, tail arrow tip width=.75em, tail arrow tail width=.5em, tail arrow tip length=1em}] K\arrow[dr]\arrow[d]\ \Omega\arrow[r] & k \end{tikzcd}

\end{document}

enter image description here

  • @JasperHalbricht This is good and works well with the option Rightarrow. However leftrightarrow or even Leftarrow do not produce the desired result. Is there a way to modify your solution to get such functionality? – encore Jan 10 '23 at 10:24
  • @encore Do you mean the option Rightarrow provided by tikz-cd? This solution is actually not meant to work together with these options. Rather you should be able to use the l or u options to draw arrows leftwards or upwards. The above solution just decorates a line that starts from any point and goes to another point. It does not really matter in which direction the line is drawn, the arrow tip is always at the end of the line. – Jasper Habicht Jan 10 '23 at 19:00
  • @JasperHalbricht yes I meant that option. In particular, I need a leftright arrow of the type you have designed. You know, Rightarrow actually does something to your arrow, the result looks like a blackboard bold arrow. – encore Jan 10 '23 at 21:18
  • 1
    @encore As I said, it is not intended and merely by chance that the appearance of the arrow is changed when using the Rightarrow option. You should ask a new question and describe how the left-right arrow should look like exactly, because such an arrow by design cannot be thicker on one end in my opinion. – Jasper Habicht Jan 11 '23 at 03:39
  • Ok will do. I was using your design with rectangular tail, same width near head as tail, so then two-sided arrow makes sense. Sorry I misspelled your surname twice :-( – encore Jan 11 '23 at 10:39