[Tex/LaTex] Change style of arrowhead in decorations.markings

tikz-pgf

I would like to draw a line with an arrow head in the middle of it and found the decoration.markings library together with the \arrow command available only there.

However I found little information which options and arrow heads are available for the \arrow command.

With trial and error I was able to produce a simple arrow in the middle of the line with

\tikzset{kb/.style={postaction={decorate,decoration={markings,mark=at position .5 with {\arrow{angle 90};}}}}}

But how can I change the style of the arrow head, i.e. to have it with a circle around it or to have two arrow heads just one after another?

Best Answer

So your question is how to define new kinds of arrow tips to use them as a decoration?

The definition of new arrowtips is independent of where you'll use them, either as part of a \draw[->] command, or as part of the \arrow command inside a decoration. The part of the manual which covers the definition of new arrow kinds is page 784.

In general, defining arbitrary shapes for the arrows is difficult, since you have to use low-level pgf* commands. In addition, if you want the arrow to accept styles and to be scalable, you have to learn about meta-arrows (pág 785).

However, in your question you gave two particular examples, which are easy to produce, since they are combinations of previously existing arrow tips.

  1. One arrow head with a circle around. You can combine the existing latex arrow with the existing o (circle) arrowtip, through \pgfarrowsdeclarecombine. This command by default puts one arrowtip after the other, but you can specify an offset which moves the second one. In this case, I've found (by trial and error) that -5pt produces the desired result.

  2. Two arrow heads one just after another. Command \pgfarrowsdeclaredouble is designed exactly for this.

Look at the following code:

\documentclass[11pt]{article}
\usepackage{tikz}
\usetikzlibrary{decorations.pathreplacing,decorations.markings,arrows}

\pgfarrowsdeclarecombine[-5pt]{circled}{circled}{latex}{latex}{o}{o}
\pgfarrowsdeclaredouble{doubled}{doubled}{stealth}{stealth}

\tikzset{
kb1/.style={postaction={decorate,
   decoration={markings,mark=at position .5 with {\arrow{circled};}}}
   },
kb2/.style={postaction={decorate,
   decoration={markings,mark=at position .5 with {\arrow{doubled};}}}
   },   
}

\begin{document}
\begin{tikzpicture}%
    \draw[kb1] (0,0) -- + (2,0);
    \draw[kb2] (0,.5) -- + (2,0);
\end{tikzpicture}
\end{document}

which produces:

result

Update

The OP pointed out in a comment that, if the kind of arrow is angle 90, then the circle is too small.

Fixing it is a bit difficult and hackish.

Standard arrows are not customizable, in order to do so you have to use "meta arrows". These kind require the latest version of pgf/tikz and package arrows.meta, where new names for the arrow tips are defined. For example the "hollow circle" arrow is named Circle[open] instead of o, and the Straight Barb arrow replaces the angle 90 one. See page 202 of the latest pgfmanual.

However, I don't know if it is possible to pass different options to the different parts of a "composite arrow". We need to give a different size to the "angle 90" and the "circle", and I don't know how to do so.

But I've found a hack. If you use the new meta-arrows only for the circle, leaving the older arrow 90 for the tip, then the options you pass to \arrow are used only for the "meta" part of the composite arrow, and this way only the circle part is resized.

Using this idea:

\documentclass[11pt]{article}
\usepackage{tikz}
\usetikzlibrary{decorations.pathreplacing,decorations.markings,arrows,arrows.meta}

\pgfarrowsdeclarecombine[-2mm]{circled}{circled}{angle 90}{angle 90}{Circle[open]}{Circle[open]}
\pgfarrowsdeclaredouble{doubled}{doubled}{angle 90}{angle 90}

\tikzset{
kb1/.style={postaction={decorate,
   decoration={markings,mark=at position .5 with {\arrow{circled[width=3mm,length=3mm]};}}}
   },
kb2/.style={postaction={decorate,
   decoration={markings,mark=at position .5 with {\arrow{doubled};}}}
   },   
}

\begin{document}
\begin{tikzpicture}%
    \draw[kb1] (0,0) -- + (2,0);
    \draw[kb2] (0,.5) -- + (2,0);
\end{tikzpicture}
\end{document}

Result:

Result