# PGFkeys problem. Meta arrow tips with parameters works only when I use different line width. Why?

The solution given here has a problem. Let re-write a minimum example

\documentclass{standalone}

\usepackage{tikz}

\makeatletter
\tikzset{arrow length/.initial = 6pt,
arrow angle/.initial  = 45}

\pgfarrowsleftextend{0pt}
\pgfarrowsrightextend{.5\pgflinewidth}
}
{
\pgfkeys{/tikz/arrow length/.get=\arrow@length}
\pgfkeys{/tikz/arrow angle/.get=\arrow@angle}
\pgfmathsetlengthmacro{\arrow@angle}{\arrow@length*tan(\arrow@angle)}
\pgfsetdash{}{0pt} % do not dash
\pgfsetroundcap % fix cap
\pgfpathmoveto{\pgfpointorigin}%{\pgfpoint{-4\arrowsize}{4\arrowsize}}
\pgfpathlineto{\pgfpoint{-\arrow@length}{\arrow@angle}}
\pgfpathmoveto{\pgfpointorigin}%{\pgfpoint{-4\arrowsize}{4\arrowsize}}
\pgfpathlineto{\pgfpoint{-\arrow@length}{-\arrow@angle}}
\pgfusepathqstroke
}
\makeatother

\begin{document}
\begin{tikzpicture}

\draw[help lines] (-3,0)grid(3,4);

% Arrow 1
\draw[arrow length = 24pt,
arrow angle  = 15,
node[above,midway]{First arrow};

% Arrow 2 - Doesn't change anything (same line width then before)
\draw[arrow length = 400cm, %<- Big value to show you it doesn't work
arrow angle  = 720,   %<- Big value to show you it doesn't work
node[above,midway]{Arrows not changed};

% Arrow 3 - Change arrow because the line width is changed
node[above,midway]{Arrows changed};

\end{tikzpicture}
\end{document}


which gives the following result

The problem is that the arrow length and arrow angle style effect the arrow on line of different line width. In the Arrow 2(see the above listing) I apply very big values of them but there is no effects because the line width is the same of the previous line. The following one, instead, I apply a line width of 0.001pt more than before and the options changes the arrow tips.

Did I use wrong the pgfkeys? How can I solve it?

-

According to p.611 of the PGF manual:

• The code will be executed only once, namely the first time the arrow tip needs to be drawn. The resulting low-level driver commands are protocolled and stored away. In all subsequent uses of the arrow tip, the protocolled code is directly inserted.

• However, the code will be executed anew for each line width. Thus, an arrow of line width 2pt may result in a different protocol than the same arrow for a line width of 0.4pt.

...in other words, it looks like this is an intentional feature. I'm not sure why you need multiple different arrow sizes for a single line width to solve your original problem, but if you do, it might be better to define these as different arrow types.

-

Ant is right, normally arrow tips are figured out once for each line width and then saved. This speeds up the rendering considerably. (PGF calls this prototyping.) But it is possible to specify other options which should also trigger a recomputation. This is done using the commands \pgfsetarrowoptions and \pgfgetarrowoptions. The manual explains this on p613 (version 2.10) and gives an example in the following text.

I used this in an answer at TikZ: changing colour of a path half way along to specify the angle at which the two lines meet (something that has to be specified on a per-use basis). The link there is to the actual answer where this is used (given that I gave several answers to that question!). I think it's close enough to your case that it should be possible to adapt, but if not just ask!

-

I don't know why but this listing respond well to my needs

\documentclass{standalone}

\usepackage{tikz}

\begin{document}
\begin{tikzpicture}
\makeatletter
\tikzset{arrow angle/.code     = \def\arrow@angle{#1},
arrow angle/.default  = 45,
arrow length/.code    = \pgfsetarrowoptions{adj}{#1},
arrow length/.default = 4pt
}

\pgfarrowsrightextend{.5\pgflinewidth}
}
{
\pgfsetdash{}{0pt} % do not dash
\pgfsetroundcap % fix cap
%\pgfsetstrokecolor{red}
\pgfpathmoveto{\pgfpointorigin}
\pgfpathmoveto{\pgfpointorigin}
\pgfusepathqstroke
}
\makeatother

\draw[help lines] (-3,0)grid(3,4);

% Arrow 1 - Default value
\draw[line width   = 1.5pt, %<---- HERE I SET 1.5pt
arrow length, % 4pt
arrow angle,  % 45
node[above,midway]{1.5pt};

% Arrow 2
\draw[line width   = 2pt,
arrow length = 10pt,
arrow angle  = 15,
node[above,midway]{2pt};

% Arrow 3
\draw[line width   = 1.5pt, %<---- HERE I SET 1.5pt AGAIN
arrow length=1cm,
arrow angle=15,
node[above,midway]{1.5pt again but different parameters};

\end{tikzpicture}
\end{document}


The result is the following:

It seems to work.

I want a meta arrow tip because when you draw a very tiny part and you want to zoom it with tikz library spy, the result is not good. To understand what I mean, see here the picture I posted. With this solution I have the total control on the very small drawing and it is good. The result, applied to my drawing, is the following

I hope it helps!!

-