1

Adapted from my "answer" to this question: Why are the units messed up? I'm sure there's a quick fix. Many thanks!

\documentclass[tikz, border=1cm]{standalone}

\usepgfmodule{nonlineartransformations} 

\makeatletter
\def\customtransformation{
    \pgfmathsetmacro{\xnew}{
        (2.7^\pgf@x)*cos(\pgf@y) % u = e^x * cos(y)
    }
    \pgfmathsetmacro{\ynew}{
        (2.7^\pgf@x)*sin(\pgf@y) % v = e^x * sin(y)
    }
    \pgf@x=\xnew pt
    \pgf@y=\ynew pt
}
\makeatother

\begin{document}

\begin{tikzpicture}
    \begin{scope}[xshift=-6cm]
        \draw[xstep=.5pt,ystep=5pt,black!25,thin] (0,0) grid (4pt,250pt);
    \end{scope}
    \pgftransformnonlinear{\customtransformation}
    \draw[xstep=.5pt,ystep=5pt,black!25,thin] (0,0) grid (4pt,250pt);
\end{tikzpicture}

\end{document}

enter image description here

steve
  • 2,154
  • 1
    What do you mean by "units are messed up"? As far as I can see, you just did not take into account that the distances are measured in pt. –  Apr 19 '20 at 18:21
  • @Schrödinger'scat Okay, that might be very true, but what I mean is that, if I have (0,0) grid (1,1), I'd expect the transformed grid to reach (e*cos(1),e*sin(1)) and no more; where would I have to change the units (or multiply by a conversion factor) to achieve this? – steve Apr 19 '20 at 19:05

1 Answers1

1

You seem to be looking for the conversion to cm. This can be achieved by dividing the lengths \pgf@x and \pgf@y by 1cm. From your last comment I also take that you want to transform back to cm units at the end of the computation.

\documentclass[tikz, border=1cm]{standalone}

\usepgfmodule{nonlineartransformations} 
\usetikzlibrary{fpu}
\makeatletter
\newcommand{\PgfmathsetmacroFPU}[2]{\begingroup% https://tex.stackexchange.com/a/503835
\pgfkeys{/pgf/fpu,/pgf/fpu/output format=fixed}%
\pgfmathsetmacro{#1}{#2}%
\pgfmathsmuggle#1\endgroup}%

\def\customtransformation{%
\PgfmathsetmacroFPU{\xnew}{%
    (exp(\pgf@x/1cm))*cos(deg(\pgf@y/1cm))*1cm % u = e^x * cos(y)
}%
\PgfmathsetmacroFPU{\ynew}{%
    (exp(\pgf@x/1cm))*sin(deg(\pgf@y/1cm))*1cm % v = e^x * sin(y)
}%
\pgf@x=\xnew pt%
\pgf@y=\ynew pt%
}
\makeatother

\begin{document}

\begin{tikzpicture}
    \begin{scope}[xshift=-7cm]
        \draw[black!25,thin] (0,0) grid (4,4);
    \end{scope}
    \draw[red] ({exp(1)*cos(deg(1))},{exp(1)*sin(deg(1))}) circle[radius=.1];
    \pgfsettransformnonlinearflatness{3pt}
    \pgftransformnonlinear{\customtransformation}
    \draw[black!25,thin] (0,0) grid[step=0.25] (1,4);
    \draw[blue,dashed] (1,1) circle[radius=.1];
\end{tikzpicture}

\end{document}

screenshot

Here I switched on the fpu library as here in case you go to more extensive applications. Note also that the density of sampling is controlled by a dimension \pgftransformnonlinearflatness, which can be set with \pgfsettransformnonlinearflatness, see the pgfmanual v3.1.5 on p. 1164:

screenshot

So if you wish to decrease the grid steps, you may also want to decrease the flatness. Needless to say that decreasing the flatness increases the compilation time.

steve
  • 2,154
  • That's exactly what I wanted, thank you! Just one more thing: now the resulting plot looks very "edged", and if I add some more steps to the grids (e.g. step=.25), some of the centrifugal lines escape the circle; how can I add more sampling points to this figure? (Seeing as it doesn't seem to be with the classic samples= option.) – steve Apr 19 '20 at 19:39
  • 1
    @ABlueChameleon You need to decrease the flatness. I added more explanations to the answer. –  Apr 19 '20 at 19:49
  • Sorry, I should've checked the manual before asking. Thanks so much for the answer though, it looks fantastic! – steve Apr 19 '20 at 19:52
  • 1
    @ABlueChameleon I actually did not check the manual. I read pgfmodulenonlineartransformations.code.tex and then searched for the flatness in the manual. This is usually more efficient. –  Apr 19 '20 at 19:56
  • Hmm... playing around some more with the answer, there's still one thing that confuses me; why is the scale of the transformed grid changed? I.e., if I write \fill (1.47,2.29) circle (.1); just before the transformation (approximate coordinates of (exp(1)*cos(1), exp(1)*sin(1))), and then write \fill (1,1) circle (.1); after the transformation, the circles are at different positions and of different sizes. – steve Apr 19 '20 at 20:25
  • 1
    @ABlueChameleon I think I finally understand what you wish to achieve. Then you need to multiply the result by 1cm. I completely rewrote the answer. –  Apr 19 '20 at 20:41
  • This is just perfect, thank you! I updated my "answer" to the question from which mine originated with your code, hope that's cool. – steve Apr 19 '20 at 21:31
  • 1
    @ABlueChameleon Sure, why not? –  Apr 19 '20 at 21:31