# nested conditionals in pgfmath

The following code throws a division by 0 error when \dx==0 is true:

\pgfmathsetmacro{\rot}{(
\dx==0 ? (\dy > 0 ? 90 : -90) : (\dx>0 ? atan(\dy/\dx) : 180+atan(\dy/\dx))
)}


The code sets \rot correctly, even when \dx==0 is true but it seems that the parser is continuing to analyze the false clause even though the condition was true. Anyone know what I'm doing wrong? Full code below:

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{calc}
\usepgfmodule{oo}
%http://tex.stackexchange.com/questions/33703/extract-x-y-coordinate-of-an-arbitrary-point-in-tikz
\makeatletter
\newcommand{\gettikzxy}[3]{%
\tikz@scan@one@point\pgfutil@firstofone#1\relax
\edef#2{\the\pgf@x}%
\edef#3{\the\pgf@y}%
}
\makeatother

\pgfooclass{rr}{
\method rr(#1,#2) { % The constructor; everything is done in here
% Here I can get named x and y coordinates
\gettikzxy{(#1)}{\spx}{\spy}
\gettikzxy{(#2)}{\epx}{\epy}
% I'd like named points to work with
\coordinate (Start) at (\spx, \spy) node[right]{start};
\coordinate (End) at (\epx, \epy);
% Find the length between start and end. Then the angle between x axis and Diff will be the rotation to apply.
\coordinate (Diff) at ($(End)-(Start)$);
\gettikzxy{(Diff)}{\dx}{\dy}
\pgfmathparse{veclen(\dx, \dy)} \pgfmathresult
\let\length\pgfmathresult
\node[right] at (End) {\length};
\pgfmathsetmacro{\rot}{(
\dx==0 ? (\dy > 0 ? 90 : -90): (\dx>0 ? atan(\dy/\dx) : 180+atan(\dy/\dx))
)}
\begin{scope}   [rotate around = {\rot:(\spx, \spy )}]
\draw ($(Start)+(0,\hi)$) arc(90:270:\hi) -- +(\length pt, 0) arc(-90:90:\hi) -- cycle;
\end{scope}
}
}

\begin{document}
\begin{tikzpicture}
\coordinate (A) at (0,0);
\coordinate (B) at (0,16);
\def\hi{0.25}
\pgfoonew \AB=new rr(A,B);
\fill (A) circle (3pt);
\fill (B) circle (3pt);
\end{tikzpicture}
\end{document}


Yes, all components of the shorthand notation are evaluated, even though only one of the branches will be following. The following simple formula provides the same error:

\pgfmathparse{1==2 ? 3/0 : 4}\pgfmathresult


Since 1 is not 2, the result should be 4, but the compiler still evaluates 3/0.

One easy way around this is to use TeX conditionals which doesn't evaluate unless necessary. So, we first evaluate whether \dx==0 using \pgfmathparse and then condition (using TeX primitives) on \pgfmathresult.

That is,

\pgfmathsetmacro{\rot}{(
\dx == 0 ? (\dy > 0 ? 90 : -90) : (\dx > 0 ? atan(\dy / \dx) : 180 + atan(\dy / \dx))
)}


becomes

\pgfmathparse{\dx == 0}%
\ifnum\pgfmathresult=1 % \dx == 0
\pgfmathsetmacro{\rot}{\dy > 0 ? 90 : -90}
\else% \dx != 0
\pgfmathsetmacro{\rot}{\dx > 0 ? atan(\dy / \dx) : 180 + atan(\dy / \dx)}
\fi