[Tex/LaTex] Fixed Point Arithmetic: Why does the fp work sometimes but others it errors

calculationsfptikz-pgf

Why does fixed point arithmetic like to error on parts of the code that aren't doing any math?

I am using the package to improve the calculation of some angles I have it printing out, but it is evaluating a node that is just a number and returning an error:

ERROR: FP error: Illegal character \c@pgf@counta  found in float number!.

--- TeX said ---
\FP@errmessage #1->\errmessage {FP error: #1!}

l.13   {};

--- HELP ---
From the .log file...

This error message was generated by an \errmessage
command, so I can't give any explicit help.
Pretend that you're Hercule Poirot: Examine all clues,
and deduce the truth by order and method.

\documentclass[convert = false, tikz]{standalone}
\usepackage{fp}
\usetikzlibrary{fixedpointarithmetic}
\begin{document}
\begin{tikzpicture}[fixed point arithmetic]
  \node[label = x] {};
\end{tikzpicture}
\end{document}

From the code above, we see that fp has an issue with this node. If I remove fp, there isn't a problem, but I want the package to be used later on in the code where there is an actual calculation.

Best Answer

What happened?

When TikZ processes a label it needs to find the appropriate point on the border of the labeled node. A direction of left sets the anchor to the angle of 180. Later down in this process the macro \pgf@sh@reanchor is used to find the actual coordinates of this point on the border.

This macro first checks if 180 is a named anchor for this shape (like north west or base), if it isn’t it is checked whether the anchor is a generic one. If it isn’t even a generic anchor it only can be a angular point on the border. 180 is then evaluated by \pgfmathsetcounter). The result is stored in the count register \c@pgf@counta (i.e. the LaTeX counter pgf@counta).

\c@pgf@counta is then directly used on \pgfqpointpolar. The q denotes a “quick” version of the \pgfpointplar macro which (the quick version that is) does not parse its arguments but directly sends them to the the trigonometric functions. Usually this parsing and evaluating is done by PGF math which automatically detects registers like counts/counters, dimens and lengths/skips and properly expands them to their value (stripping away any units).

But the fixedpointarithmetic library and its option directly maps these trigonometric functions to their fp counterparts. fp does not tolerate registers.

A bug?

I consider this a bug in the definition of \pgf@sh@reanchor as seemingly every other use of \pgfqpointpolar of PGF uses directly numbers or content that expands to a number.

How to fix it?

A simple fix using the etoolbox package is:

\usepackage{etoolbox}
% You should have loaded tikz before this line!
\patchcmd\pgf@sh@reanchor{\c@pgf@counta}{\the\c@pgf@counta}{}{}

This also fixes the direct use of angular anchors as in (keeping with your example):

\node at (P.90) {}; % or
\node[anchor=270] {};

west instead of left

For circular unrotated nodes you can actually use the compass anchors without a problem as they map directly to the directions. So instead of left you can use west. This will trigger the named anchors and avoids \pgfqpointpolar.

This usually does not work for other shapes, at least for the diagonal directions, as can be seen in the second TikZ picture.

Or you don’t use fixed point arithmetic for labels.

Of course, for this little task the fp package and its precision are not needed, so if you can avoid it, use fixed point arithmetic only on paths where you actually need it, say

\path[fixed point arithmetic] let <fancy calculations> in …;

If needed, you can construct a short-cut to that long option, say:

\tikzset{fp/.style={fixed point arithmetic={#1}},fp/.default=}

Code

\documentclass[convert = false, tikz]{standalone}
\usepackage{fp}
\usetikzlibrary{fixedpointarithmetic}
\usepackage{etoolbox}
\makeatletter
\patchcmd\pgf@sh@reanchor{\c@pgf@counta}{\the\c@pgf@counta}{}{}
\makeatother
\begin{document}
\begin{tikzpicture}[fixed point arithmetic,
  every label/.append style = {font = \scriptsize},
  dot/.style = {inner sep = +0pt, shape = circle,
    draw = black, label = {#1}},
  small dot/.style = {minimum size = .05cm, dot = {#1}},
  big dot/.style = {minimum size = .1cm, dot = {#1}},
  ]
  \node[font = \scriptsize, small dot = {left: \(1\)}] (P) at (203.16381:3cm)
  {};
\end{tikzpicture}

\begin{tikzpicture}
  \node[fill,minimum width=1cm,label = {[red]north west:nw}, label = {[green]above left:al}, label=north:n] (a){};
  \foreach \sty/\an in {white/north, green/135, red/north west}\path[draw=\sty,fill=black] (a.\an) circle [radius=.8pt];
\end{tikzpicture}
\end{document}

Output

enter image description here

enter image description here

Related Question