# How does the angle key from arrows.meta TikZ library work?

The title says it all. How does angle=<angle>:<first dimen> <second dimen> works. More exactly, what do the first length and the second length mean?

\usetikzlibrary{arrows.meta}
\tikzset{mparr/.tip={Triangle[round,angle=45:4bp 0bp]}}


I was trying to copy the style from MetaPost, which I like. So the main idea is to find the correct values for <first dimen> and <second dimen> so it resembles the arrows from MetaPost.

In any case, if you have any suggestions to imitate the style of MetaPost, they are welcome. (The bend option from bending library doesn't convince me, the result is always less beautiful than MetaPost arrows.)

Here's an example with a MetaPost figure. Those weird \relaxes are there because I played with \rlap and \llap to see if the figures had similar results when playing with the values.

%!TEX TS-program = lualatex

\documentclass{scrartcl}

\usepackage{tikz,luamplib,tkz-euclide}
\usetikzlibrary{arrows.meta,bending,decorations.markings}

\tikzset{mparr/.tip={Triangle[round,angle=45:5bp]}} % 5bp being 4bp+2\pgflinewidth
\tikzset{mpstyle/.style={line width=.5bp,line join=round,line cap=round,>=mparr,every node/.append style={inner sep=2bp}}}

\begin{document}

\indent\relax{\begin{tikzpicture}[mpstyle]
\draw[<->] (2,0) -- (0,0) -- (0,2);
\draw[->] (0,0) .. controls (1,0) and (1,2) .. (2,2);
\end{tikzpicture}}%
\relax{\begin{mplibcode}
%ahlength := 4bp;
%ahangle := 45;
beginfig(1);
drawdblarrow (2cm,0) -- (0,0) -- (0,2cm);
drawarrow (0,0) .. controls (1cm,0) and (1cm,2cm) .. (2cm,2cm)
%withpen pencircle scaled 10bp
;
endfig;
\end{mplibcode}}

\end{document}


There are a few things that I don't completely understand: I can't draw the arrows in TikZ with any line width, it seems fixed, the round option doesn't take in account if the line width is , e.g., 11cm; if I change the ahangle := 20 then the similarity is lost even if I do angle=20:5bp, I don't really know how it works.

P.S.: I know there are nice answers to the question in the title, but I stated in the question that my goal was to copy the arrows (and style in general) from MetaPost, so I will wait a little bit longer in case someone comes with a nice solution.

In fact, angle accepts four arguments: (notice the spaces)

angle=⟨angle⟩:⟨dimension⟩␣⟨line width factor⟩␣⟨outer factor⟩


These arguments are introduced for only one reason: flexibility.

## (1 2 3)

First of all we would like to assign the shape and the size of an arrow tip directly. This leads to a simple convention:

angle=⟨angle⟩:⟨dimension⟩


which fails to be an arrow if lines are too thick. Especially in case (3), the line is as big the tip.

\draw[line width= 2pt,arrows={-Triangle[lw0r,angle=60:10pt   ]}]( 1,0)--+(0,1)node{ 1};
\draw[line width= 5pt,arrows={-Triangle[lw0r,angle=60:10pt   ]}]( 2,0)--+(0,1)node{ 2};
\draw[line width=10pt,arrows={-Triangle[lw0r,angle=60:10pt   ]}]( 3,0)--+(0,1)node{ 3};


## (4 5 6)

So we then have a more elaborated protocol:

angle=⟨angle⟩:⟨dimension⟩␣⟨line width factor⟩


Such that in these cases, tips are twice as big as the lines are.

\draw[line width= 2pt,arrows={-Triangle[lw0r,angle=60 :0pt  2]}]( 4,0)--+(0,1)node{ 4};
\draw[line width= 5pt,arrows={-Triangle[lw0r,angle=60 :0pt  2]}]( 5,0)--+(0,1)node{ 5};
\draw[line width=10pt,arrows={-Triangle[lw0r,angle=60 :0pt  2]}]( 6,0)--+(0,1)node{ 6};


## (7 8 9)

You can also, illustrated below, set the size of tips to be larger than that of the lines by exactly 5pt.

\draw[line width= 2pt,arrows={-Triangle[lw0r,angle=60 :5pt  1]}]( 7,0)--+(0,1)node{ 7};
\draw[line width= 5pt,arrows={-Triangle[lw0r,angle=60 :5pt  1]}]( 8,0)--+(0,1)node{ 8};
\draw[line width=10pt,arrows={-Triangle[lw0r,angle=60 :5pt  1]}]( 9,0)--+(0,1)node{ 9};


## Even more complicated

Things become insane once the lines become doubled.

## (4 5 6 7 8 9)

The first six arrows look OK: The tip size is a linear function in line width.

\draw[line width= 2pt,arrows={-Triangle[lw0r,angle=60 :0pt  2  ]}]( 4,0)--+(0,3)node{ 4};
\draw[line width= 5pt,arrows={-Triangle[lw0r,angle=60 :0pt  2  ]}]( 5,0)--+(0,3)node{ 5};
\draw[line width=10pt,arrows={-Triangle[lw0r,angle=60 :0pt  2  ]}]( 6,0)--+(0,3)node{ 6};
\draw[line width= 2pt,arrows={-Triangle[lw0r,angle=60 :5pt  1  ]}]( 7,0)--+(0,3)node{ 7};
\draw[line width= 5pt,arrows={-Triangle[lw0r,angle=60 :5pt  1  ]}]( 8,0)--+(0,3)node{ 8};
\draw[line width=10pt,arrows={-Triangle[lw0r,angle=60 :5pt  1  ]}]( 9,0)--+(0,3)node{ 9};


## (10 11 12)

And then a problem arise: can the tip size grows with respect to the outer line width? So the forth argument involves.

\draw[line width= 2pt,arrows={-Triangle[lw0r,angle=60 :0pt  1 1]}](10,0)--+(0,3)node{10};
\draw[line width= 5pt,arrows={-Triangle[lw0r,angle=60 :0pt  1 1]}](11,0)--+(0,3)node{11};
\draw[line width=10pt,arrows={-Triangle[lw0r,angle=60 :0pt  1 1]}](12,0)--+(0,3)node{12};


By default, outer factor, the forth argument, is set to be 0. Hence the weighted line width, the dimension to be multiplied by the line width factor, is equal to the total line width. That is, the sum of the widths of the black-white-black lines. Or equally inner + 2·outer.

On the other hand if outer factor is 1, the weighted line width is the outer line width, i.e. the width of the black line. For any other values, the weighted line width will be the linear interpolation of the total and outer line widths.

## (13 14 15)

So... Can the tip size grows with respect to the inner line width? The answer require some math:

\draw[line width= 2pt,arrows={-Triangle[lw0r,angle=60 :0pt -1 2]}](13,0)--+(0,3)node{13};
\draw[line width= 5pt,arrows={-Triangle[lw0r,angle=60 :0pt -1 2]}](14,0)--+(0,3)node{14};
\draw[line width=10pt,arrows={-Triangle[lw0r,angle=60 :0pt -1 2]}](15,0)--+(0,3)node{15};


## Full code and side marks

• In the definition of lw0r, the line width=0 aims to cancel the counter path of tips.
• Strangely draw=none gives the do not know the key 'draw' error.
• If you are good at math, you will found that we cannot set the weighted line width to be inner + outer.
• For later referencing, the main calculation is done by \pgfarrowslinewidthdependent in pgfcorearrows.code.tex.

tip length = size·cos(angle/2)
tip width = size·2·sin(angle/2)
size = ⟨dimension⟩ + ⟨line width factor⟩·weighted
weighted = ⟨outer factor⟩·outer + (1-⟨outer factor⟩)·total
weighted = (2-⟨outer factor⟩)·outer + (1-⟨outer factor⟩)·inner

• In the same file there is also a \pgfarrowslengthdependent taking three arguments : ⟨dimension⟩, ⟨length factor⟩, ⟨line width factor⟩.

tip width = ⟨dimension⟩ + ⟨length factor⟩·tip length + ⟨line width factor⟩·line width

• No more dependent-like macros as far as I know.

Code:

\documentclass[border=9,tikz]{standalone}
\usetikzlibrary{arrows.meta}

\begin{document}

\tikzset{/pgf/arrow keys/lw0r/.style={line width=0,red}}

\begin{tikzpicture}[nodes=above]
\draw[line width= 2pt,arrows={-Triangle[lw0r,angle=60:10pt   ]}]( 1,0)--+(0,1)node{ 1};
\draw[line width= 5pt,arrows={-Triangle[lw0r,angle=60:10pt   ]}]( 2,0)--+(0,1)node{ 2};
\draw[line width=10pt,arrows={-Triangle[lw0r,angle=60:10pt   ]}]( 3,0)--+(0,1)node{ 3};
\draw[line width= 2pt,arrows={-Triangle[lw0r,angle=60 :0pt  2]}]( 4,0)--+(0,1)node{ 4};
\draw[line width= 5pt,arrows={-Triangle[lw0r,angle=60 :0pt  2]}]( 5,0)--+(0,1)node{ 5};
\draw[line width=10pt,arrows={-Triangle[lw0r,angle=60 :0pt  2]}]( 6,0)--+(0,1)node{ 6};
\draw[line width= 2pt,arrows={-Triangle[lw0r,angle=60 :5pt  1]}]( 7,0)--+(0,1)node{ 7};
\draw[line width= 5pt,arrows={-Triangle[lw0r,angle=60 :5pt  1]}]( 8,0)--+(0,1)node{ 8};
\draw[line width=10pt,arrows={-Triangle[lw0r,angle=60 :5pt  1]}]( 9,0)--+(0,1)node{ 9};
\end{tikzpicture}

\begin{tikzpicture}[nodes=above,every path/.style=double,double distance=10pt]
\draw[line width= 2pt,arrows={-Triangle[lw0r,angle=60 :0pt  2  ]}]( 4,0)--+(0,3)node{ 4};
\draw[line width= 5pt,arrows={-Triangle[lw0r,angle=60 :0pt  2  ]}]( 5,0)--+(0,3)node{ 5};
\draw[line width=10pt,arrows={-Triangle[lw0r,angle=60 :0pt  2  ]}]( 6,0)--+(0,3)node{ 6};
\draw[line width= 2pt,arrows={-Triangle[lw0r,angle=60 :5pt  1  ]}]( 7,0)--+(0,3)node{ 7};
\draw[line width= 5pt,arrows={-Triangle[lw0r,angle=60 :5pt  1  ]}]( 8,0)--+(0,3)node{ 8};
\draw[line width=10pt,arrows={-Triangle[lw0r,angle=60 :5pt  1  ]}]( 9,0)--+(0,3)node{ 9};
\draw[line width= 2pt,arrows={-Triangle[lw0r,angle=60 :0pt  1 1]}](10,0)--+(0,3)node{10};
\draw[line width= 5pt,arrows={-Triangle[lw0r,angle=60 :0pt  1 1]}](11,0)--+(0,3)node{11};
\draw[line width=10pt,arrows={-Triangle[lw0r,angle=60 :0pt  1 1]}](12,0)--+(0,3)node{12};
\draw[line width= 2pt,arrows={-Triangle[lw0r,angle=60 :0pt -1 2]}](13,0)--+(0,3)node{13};
\draw[line width= 5pt,arrows={-Triangle[lw0r,angle=60 :0pt -1 2]}](14,0)--+(0,3)node{14};
\draw[line width=10pt,arrows={-Triangle[lw0r,angle=60 :0pt -1 2]}](15,0)--+(0,3)node{15};
\end{tikzpicture}

\end{document}

• That's detailed. One thing I can't get right is that (it seems that) the arrows from MetaPost are 4bp + 2·⟨linewidth⟩ and, in the code I can't use it. Any way I could define the arrow with angle=45:4bp+2\pgflinewidth,? By the way, you have an extra : after (4 5 6) in the code angle=⟨angle⟩:⟨dimension⟩:␣⟨line width factor⟩. – Manuel Mar 27 '15 at 10:27
• @Manuel As you want 45 degrees, there is a sin(22.5) factor somewhere. You probably have to figure it out yourself since I know nothing about MetaPost. And do not forget the line width of the tip itself. – Symbol 1 Mar 27 '15 at 14:53
• Mmm… I still don't know how it works. I expected the Triangle to be drawn “theoretically” and then \drawfilled. So I expected the arrow to grow when using ultra thick and that's not the case. – Manuel Mar 27 '15 at 16:31
• Forget doubled lines, you may try angle=45:4bp 2, which is the official version of angle=45:4bp+2\pgflinewidth. But as I just said, even the latter may not be what you want. (Consider to give a MetaPost MWE?) – Symbol 1 Mar 27 '15 at 16:40

From pgfmanual, page 186

And a little example

\documentclass{scrartcl}

\usepackage{tikz}
\usetikzlibrary{arrows.meta,bending}

\tikzset{mparr/.tip={Triangle[round,angle=45:4bp]}}
\tikzset{mpstyle/.style={line width=.5bp,line join=round,line cap=round,>=mparr}}

\begin{document}

\begin{tikzpicture}
\begin{scope}[mpstyle]
\draw[->] (0,0) .. controls (1,0) and (1,2) .. (2,2) ;
\draw[<->] (2,0) -- (0,0) -- (0,2);
\end{scope}

\begin{scope}[mparr/.tip={Triangle[round,angle=45:4bp 4]},
mpstyle, xshift=3cm]
\draw[->] (0,0) .. controls (1,0) and (1,2) .. (2,2) ;
\draw[<->] (2,0) -- (0,0) -- (0,2);
\end{scope}
\end{tikzpicture}

\end{document}


• I missed this one, and I found no reference to it in the arrows.meta section. – Manuel Mar 27 '15 at 10:23