First of all, I think that the otherwise great pgfmanual is not entirely correct. The manual section 107.4.2 states
% \pgf@x will contain the radius angle
% \pgf@y will contain the distance
\pgfmathsincos@{\pgf@sys@tonumber\pgf@x}%
% pgfmathresultx is now the cosine of radius angle and
% pgfmathresulty is the sine of radius angle
\pgf@x=\pgfmathresultx\pgf@y%
\pgf@y=\pgfmathresulty\pgf@y%
What the code in the pgfmanual is probably doing is to express the x
coordinate in pt, then take the cos and sin of x/pt
(i.e. if x=50pt then it will return cos(50)), and to multiply the outcome by the y
coordinate, i.e.
(x_new,y_new) = (y_old cos(x_old/pt), y_old sin(x_old/pt))
This leads to the code:
\documentclass{article}
\usepackage{tikz}
\usepgfmodule{nonlineartransformations}
\tikzset{declare function={mymod(\x)=\x-int(\x);}}
\makeatletter
\def\slowtransformation{% modified version of the manual 103.4.2 Installing Nonlinear Transformation
\typeout{before:\space\the\pgf@x\space\the\pgf@y}%
\edef\oriX{\the\pgf@x}%
\edef\oriY{\the\pgf@y}%
\pgfmathsetmacro{\myAngle}{mod(360+atan2(\oriY,\oriX),360)}
\pgfmathsetmacro{\myRadius}{veclen(\oriX,\oriY)}
\typeout{original\space x=\oriX\space y=\oriY}
\typeout{radius=\myRadius\space angle=\myAngle}
\setlength{\pgf@x}{\myAngle pt}
\setlength{\pgf@y}{\myRadius pt}
}
\def\fastertransformation{% modified version of the manual 103.4.2 Installing Nonlinear Transformation
\pgfmathsetmacro{\myAngle}{mod(720+atan2(\pgf@y,\pgf@x),360)}
\pgfmathsetmacro{\myRadius}{veclen(\pgf@x,\pgf@y)}
\setlength{\pgf@x}{\myAngle pt}
\setlength{\pgf@y}{\myRadius pt}
}
\makeatother
\begin{document}
\begin{tikzpicture}
\draw[-latex] (-2.3,-2) -- (3.5,-2) node[below]{$x$};
\draw[-latex] (0,-2.3) -- (0,4.5) node[left]{$y$};
\draw[blue] (-2, -1) -- (3, 4);
\end{tikzpicture}\\
\begin{tikzpicture}
\draw[-latex] (-0.3,0) -- (7.5,0) node[below]{$\varphi$};
\draw[-latex] (0,-0.3) -- (0,4.5) node[left]{$r$};
\pgftransformnonlinear{\slowtransformation}
\draw[blue] (-2, -1) -- (3, 4);
\end{tikzpicture}
\begin{tikzpicture}
\draw[-latex] (-0.3,0) -- (7.5,0) node[below]{$\varphi$};
\draw[-latex] (0,-0.3) -- (0,4.5) node[left]{$r$};
\pgftransformnonlinear{\fastertransformation}
\draw[blue] (-2, -1) -- (3, 4);
\end{tikzpicture}
\end{document}
There are two identical transformations, the first one (\slowtransformation
) is more explicit and issues \typeout
s to understand what's going on, whereas the second one (\fastertransformation
) is a bit faster.
NOTE:
One has to be careful with options like scale=...
and the like. This transformation will take the very coordinates after all scale
and so on transformations, and then map them to polar coordinates. Therefore, if one has, say, [yscale=0.5]
and draws a circle around the origin, the coordinates are those of an ellipse, and the transformation does then not map them to a horizontal line (which it does without any such additional transformations).
The current code will produce angles between 0 and 360 degrees, and this is controlled by mod(360+atan2(\oriY,\oriX),360)
. If you use different conventions, you need to adjust this bit of code accordingly.
UPDATES: Fixed two a stupid mistake in the computation of the angle (atan2(y,x)
vs atan2(x,y)
) and made the axes labels more appropriate. I also removed all scale
directives and added more explanations.