4

My initial problem occurred with this code:

\def\a{pi/2}
\pgfmathparse{\a r}\pgfmathresult
output : 89.99937

When I modified the macro \a thus \def\a{pi}

I get the error: Package PGF Math Error: Unknown function 'pir' (in 'pir'). In this case an unsatisfactory solution is \def\a{pi/1}

Also possible

\edef\tp{\noexpand \pgfmathparse{pi r}}\tp%
\pgfmathresult

output: 179.99962

The problem also arises when trying to modify this Jake code in how to calculate coordinates in radians.

Jake gives this answer :

\tikz \draw (1,0) -- ({cos(pi/4 r)}, {sin(pi/4 r)});

but

\def\a{pi}
 \tikz \draw (1,0) -- ({cos(\a r)}, {sin(\a r)});

presents the same problem.

The first question is: how to avoid this problem simply? or how to convert radians to degrees in a safe way?

Another question is : is possible to use xfp to get the conversion or another tool ?

4
  • You need \def\a{pi\space}. Commented Apr 17, 2022 at 22:01
  • Yes I know but it's like \def\a{pi/1} (\space is better). Are there other possibilities? Commented Apr 17, 2022 at 22:18
  • There’s also the equivalent math function deg. I’m on mobile device, hence sorry I didn’t run tests before adding comments. Maybe related: github.com/pgf-tikz/pgf/issues/1077. Commented Apr 17, 2022 at 22:35
  • @muzimuzhiZ yes deg is a possiblity Commented Apr 18, 2022 at 11:19

1 Answer 1

5

With \def\a{pi}, \pgfmathparse{\a r} or \draw (1,0) -- ({cos(\a r)}, {sin(\a r)}) will raise errors because i) pgfmath does \edef to the expression before parsing it and ii) the space after \a, a control word (a backslash followed by one or more characters with catcode 11), is skipped. Therefore the expression ready to be parsed always contain pir, not pi r.

In question comments,

  • My first suggestion \def\a{pi\space} makes sure that after \edef a space is left in between pi and r (\space expands to a normal space char). Other tricks commonly used to reserve space char after a control word may not work here:
    • \def\a{pi\ } doesn't work because \ is not expandable and the pgfmath parser can't handler it.
    • \def\a{pi} with \pgfmathparse{\a{} r} doesn't work either because {} won't disappear after \edef and curly braces denote array-like structures in pgfmath expression.
  • The second suggestion is replacing the postfix operator r with its function form deg: cos(\a r) -> cos(deg(pi)).

Here's a third one: You could define pseudo-constant as a zero-arg pgfmath function.

\documentclass{article}
\usepackage{tikz}

\makeatletter
% option 1
\tikzset{
  declare function={
    constA=pi;
  }
}

% option 2
\pgfmathdeclarefunction{constB}{0}{%
  \begingroup
    \pgfmathparse{pi}%
    \pgfmathreturn{\pgfmathresult pt}% assign to a length is the most robust way
  \endgroup%
}%
\makeatother

\begin{document}
\pgfmathprint{constA r},
\pgfmathprint{constB r}

\tikz \draw (1,0) -- ({cos(constA r)}, {sin(constB r)}) ;
\end{document}

Note if the function has a single-letter name, like a in declare function={ a=pi; }, then you'll encounter the not-yet resolved pgf issue https://github.com/pgf-tikz/pgf/issues/1077.

BTW, \pgfmathparse is not fully expandable, hence writing \edef\tp{\pgfmathparse{...}} is dangerous and there's no warranty that this \edef and the following use of \tp will work without errors in future versions.


Another question is : is possible to use xfp to get the conversion or another tool ?

Yes it's possible. xfp's \fpeval (or the equivalent latex3 function \fp_eval:n) is fully expandable (and sometimes more accurate than pgfmath), hence it's valid to use \fpeval in a pgfmath expression, except it's a bit strange.

LaTeX3 module l3fp defines pi as the normal 3.1415... constant, but deg as another constant denoting radians per degree. Therefore \pgfmathprint{pi r} and \fpeval{pi/deg} do the same radian-to-degree conversion.

\documentclass{article}
\usepackage{pgfmath}
\usepackage{xfp}

\begin{document}
\def\a{pi}

\pgfmathprint{sin(\fpeval{\a/deg})}, % =  0.0
\pgfmathprint{cos(\fpeval{\a/deg})}  % = -1.0
\end{document}

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.