# using commands in pgfkeys not working

The following latex code works as expected. It allows to draw a line parallel to the z axis:

\documentclass[border=10pt]{standalone}
\usepackage{tikz}
\begin{document}

\tikzset{
parallel to z axis/.code={
\pgfmathanglebetweenpoints{\pgfpointorigin}{
\pgfpointxyz{0}{0}{1}
}
\edef\lineangle{\pgfmathresult}
}
}

\begin{tikzpicture}[rotate around x=30,rotate around y=50]
\begin{scope}[->]
\draw(0,0)--(1,0)node[right]{$x$};
\draw (0,0)--(0,1)node[left]{$y$};
\draw[blue] (0,0)--(0,0,1)node[ right]{$z$};
\end{scope}

\draw[blue, parallel to z axis ] (-1cm,0cm)--+(\lineangle:1.5cm);

\end{tikzpicture}

\end{document}


In an attempt to make some improvement I defined a new macro \newcommand{\zangle}{...} as follows:

\documentclass[border=10pt]{standalone}
\usepackage{tikz}
\begin{document}
\newcommand{\zangle}{
\expandafter\pgfmathanglebetweenpoints{\pgfpointorigin}{
\pgfpointxyz{0}{0}{1}}
\pgfmathresult}

\tikzset{
parallel to z axis/.code={
\edef\lineangle{\zangle}
}
}

\begin{tikzpicture}[rotate around x=30,rotate around y=50]
\begin{scope}[->]
\draw(0,0)--(1,0)node[right]{$x$};
\draw (0,0)--(0,1)node[left]{$y$};
\draw[blue] (0,0)--(0,0,1)node[ right]{$z$};
\end{scope}

\draw[blue, parallel to z axis ] (-1cm,0cm)--+(\lineangle:1.5cm);

\end{tikzpicture}

\end{document}


But it does not work because of compilation errors!

I think that the problem is related to the macro expansion but I have no idea how to fix it. So please Help!

• Why do you consider your second version an improvement? You could set the zangle once and for all with execute at begin picture or execute at begin scope instead of repeatedly computing it. This might be an improvement IMHO. – marmot Oct 13 '18 at 21:16
• because I plan to use the same code in another part of the document. I think it is better to define a macro. – Hafid Boukhoulda Oct 13 '18 at 21:22
• @marmot solution is very interesting but I wonder if it is possible and not very difficult to make the \lineangle command expand to the value computed by the \zangle command? – Hafid Boukhoulda Oct 13 '18 at 22:31
• Yes, of course, with the usual tricks: \newcommand{\zangle}[1]{ \pgfmathanglebetweenpoints{\pgfpointorigin}{ \pgfpointxyz{0}{0}{1}} \edef#1{\pgfmathresult}} \tikzset{ parallel to z axis/.code={ \zangle{\lineangle} } }. But why would one do that? – marmot Oct 13 '18 at 22:36

\documentclass[border=10pt]{standalone}
\usepackage{tikz}
\begin{document}
\newcommand{\zangle}[1]{
\pgfmathanglebetweenpoints{\pgfpointorigin}{
\pgfpointxyz{0}{0}{1}}
\edef#1{\pgfmathresult}}

\tikzset{
parallel to z axis/.code={
\zangle{\lineangle}
}
}

\begin{tikzpicture}[rotate around x=30,rotate around y=50]
\begin{scope}[->]
\draw(0,0)--(1,0)node[right]{$x$};
\draw (0,0)--(0,1)node[left]{$y$};
\draw[blue] (0,0)--(0,0,1)node[ right]{$z$};
\end{scope}
\draw[blue, parallel to z axis ] (-1cm,0cm)--+(\lineangle:1.5cm);
\end{tikzpicture}
\end{document}


But I wouldn't do that. Here is what I would do. I don't see why you can't use this in other parts of the document, too. I'd set the z angle once in a scope and then just use it as often as I need it.

\documentclass[tikz,border=3.14mm]{standalone}
\begin{document}

\tikzset{
get z angle/.style={execute at begin scope={
\pgfmathanglebetweenpoints{\pgfpointorigin}{
\pgfpointxyz{0}{0}{1}
}
\edef#1{\pgfmathresult}
}
}}

\begin{tikzpicture}[rotate around x=30,rotate around y=50,get z angle=\zangle]
\begin{scope}[->]
\draw(0,0)--(1,0)node[right]{$x$};
\draw (0,0)--(0,1)node[left]{$y$};
\draw[blue] (0,0)--(0,0,1)node[ right]{$z$};
\end{scope}
\draw[blue] (-1cm,0cm)--+(\zangle:1.5cm);
\draw[red] (1cm,0cm)--+(0,0,1.5);
\end{tikzpicture}
\end{document}


I am also not sure if I understand the purpose of all this, --+(\zangle:1.5cm) is equivalent to --+(0,0,1.5), see the red plot. If you tell us what you really have in mind, this may lead to another view of things. Yet if it is only to "remember" the angle, you only need to say \xdef\rememberedzangle{\zangle} inside the tikzpicture to remember this value, i.e. \rememberedzangle may be used in future pictures.

• I want to draw a line that makes a determinated angle with the horizontal line. the angle can be specified either by an angle value or by a letter x, y or z that means parralel to x , y or z. I don't know if it is comprehensible what I say. I am not used to speak english. – Hafid Boukhoulda Oct 13 '18 at 23:04
• @HafidBoukhoulda That's all fine. However, I'd like to draw your attention to the calc library, which is described in section 13.5 of the pgfmanual. The reason why you won't find too many posts using \pgfmathanglebetweenpoints and so on is that everything can be done with calc in an arguably more elegant way. So it is possible to write macros like you propose, but on the long run I believe you will be better off switching to calc. Of course, I might be wrong. – marmot Oct 13 '18 at 23:12
• Ok I will take a look at calc – Hafid Boukhoulda Oct 13 '18 at 23:16