2

I've written a non linear transform and am able to transform figures drawn in TiKZ correctly (transformed the rectangle on the left to the arc on the right) but doing the same on \includegraphics doesn't work. How can I apply the same transformation on it ? Here's the code I have for transformation

%!tikz editor 1.0
\documentclass[tikz]{standalone}
\usepackage{tikz}
\usepackage[graphics, active, tightpage]{preview}
\PreviewEnvironment{tikzpicture}

%!tikz preamble begin
\usepgfmodule{nonlineartransformations}
\usepgfmodule[nonlineartransformations]
\usepackage{mathtools}

\makeatletter
\newcommand*{\length}{50}%
\newcommand*{\width}{20}%
\newcommand*{\PI}{3.14}%
\newcommand*{\Rad}{30}%
\newcommand*{\rad}{27.5}%
\newcommand*{\slant}{20}%

\pgfmathsetmacro{\alpha}{(2*\PI*(\Rad-\rad))/\slant}%
\pgfmathsetmacro{\tconst}{(\rad*\slant)/(\Rad-\rad)}%

\tikzset{declare function={zeta(\x,\y) = \tconst + ((\x*\slant)/\length);}}
\tikzset{declare function={theta(\x,\y)=(\alpha*\y)/\width;}}
\tikzset{declare function={shi(\x)=\x+60;}}

\def\polartransformation
{   
    \pgfmathsetmacro{\costheta}{cos(deg(theta(\pgf@x,\pgf@y)))}

    \pgfmathsetmacro{\sintheta}{sin(deg(theta(\pgf@x,\pgf@y)))}

    \pgfmathsetmacro{\resz}{zeta(\pgf@x,\pgf@y)}


    \pgfmathsetmacro{\xcoord}{\resz*\costheta}

    \pgfmathsetmacro{\ycoord}{\resz*\sintheta}

    \setlength{\pgf@x}{\xcoord pt}
    \setlength{\pgf@y}{\ycoord pt}
}
\makeatother
%!tikz preamble end


\begin{document}

%!tikz source begin
\begin{tikzpicture}
\draw [black, left color=white, right color=gray ] (100pt,20pt) rectangle (150pt,0pt);
{
        \pgftransformnonlinear{\polartransformation}
        \pgfsettransformnonlinearflatness{0.2pt}
        \draw [black, left color=white, right color=gray ] (0pt,20pt) rectangle (50pt,0pt);
}
\end{tikzpicture}
%!tikz source end
\end{document}

enter image description here

lorem97
  • 23
  • 1
    Welcome! Any chance your question is related to https://tex.stackexchange.com/q/524837/194703? In any case, one needs to see an explicit code that shows what you have tried. –  Jan 19 '20 at 15:58
  • The answer you refer to, has been removed from SX, and it is no longer available for anyone. – TeX Apprentice Oct 24 '22 at 04:23

1 Answers1

2

This is almost completely copied from this very nice answer except that I changed the map to a polar transformation.

In order to explain the changes, recall first that fx and fy are the images of the transformation, i.e.

(x,y) \mapsto (fx(x,y),fy(x,y)) .

The other functions fxx, fxy, fyx and fyy are derived from these functions (and are just the derivatives of the function in the lattice sense). In order to obtain a polar transformation, one may interpret x as the angle and y as the radius. Then a possible choice for a polar transformation is

fx(x,y) = -(y+10)*cos(x*5) ,
fy(x,y) = (y+10)*sin(x+y) ,

where the numerical constants 10 and 5 are just chosen by hand to get a reasonable output. If you shift the argument of the trigonometric function you will rotate the image, and so on and so forth.

\documentclass[border=9,tikz]{standalone}
\begin{document}

\pgfmathdeclarefunction{fx}{2}{\pgfmathparse{-(#2+10)*sin(#1*5)}}
\pgfmathdeclarefunction{fy}{2}{\pgfmathparse{(#2+10)*cos(#1*5)}}

\pgfmathdeclarefunction{fxx}{2}{\pgfmathparse{fx(#1+1,#2)-fx(#1,#2)}}
\pgfmathdeclarefunction{fxy}{2}{\pgfmathparse{fy(#1+1,#2)-fy(#1,#2)}}
\pgfmathdeclarefunction{fyx}{2}{\pgfmathparse{fx(#1,#2+1)-fx(#1,#2)}}
\pgfmathdeclarefunction{fyy}{2}{\pgfmathparse{fy(#1,#2+1)-fy(#1,#2)}}


\begin{tikzpicture}

    \path(-15,-5)(15,18);
    \foreach\i in{-10,...,9}{
        \foreach\j in{-5,...,4}{
            \pgfmathsetmacro\aa{fxx(\i,\j)}
            \pgfmathsetmacro\ab{fxy(\i,\j)}
            \pgfmathsetmacro\ba{fyx(\i,\j)}
            \pgfmathsetmacro\bb{fyy(\i,\j)}
            \pgfmathsetmacro\xx{fx (\i,\j)}
            \pgfmathsetmacro\yy{fy (\i,\j)}
            \pgflowlevelobj{
                \pgfsettransformentries{\aa}{\ab}{\ba}{\bb}{\xx cm}{\yy cm}
            }{
                \fill[black!10](1,0)--(0,0)--(0,1);
                \clip(1,0)--(0,0)--(0,1)--cycle;
                \tikzset{shift={(-\i,-\j)}}
                \path(0,0)node{\includegraphics[width=20cm,height=10cm]{example-image-duck}};
            }
            \pgfmathsetmacro\aa{fxx(\i  ,\j+1)}
            \pgfmathsetmacro\ab{fxy(\i  ,\j+1)}
            \pgfmathsetmacro\ba{fyx(\i+1,\j  )}
            \pgfmathsetmacro\bb{fyy(\i+1,\j  )}
            \pgfmathsetmacro\xx{fx (\i+1,\j+1)}
            \pgfmathsetmacro\yy{fy (\i+1,\j+1)}
            \pgflowlevelobj{
                \pgfsettransformentries{\aa}{\ab}{\ba}{\bb}{\xx cm}{\yy cm}
            }{
                \clip(0,0)--(-1,0)--(0,-1)--cycle;
                \tikzset{shift={(-\i-1,-\j-1)}}
                \path(0,0)node{\includegraphics[width=20cm,height=10cm]{example-image-duck}};
            }
        }
    }
\end{tikzpicture}

\end{document}

enter image description here

  • Yes, I saw this answer. This is a piecewise linear transform approximation to a non linear transform, if I understood correctly. But I was unable to calculate the functions required to calculate the pgfsettransformetries' parameters. I added my code to give you an idea of what I'm trying to do. Can you tell me how to calculate the parameters ? – lorem97 Jan 19 '20 at 16:36
  • @lorem97 The nonlinear transformations that come with the pgf module of the same name do not allow you to transform external graphics. I also do not understand what you want to tell me with "But I was unable to calculate the functions required to calculate the pgfsettransformetries' parameters.". –  Jan 19 '20 at 16:39
  • I want to know how to calculate the map functions (fx, fy, fxx...) for the transform I want to do. – lorem97 Jan 19 '20 at 16:51
  • @lorem97 The functions fxx, fxy, fyx and fyy are computed from fx and fy automatically. The functions fx and fy are the image of x and y, i.e. (x,y)\mapsto(fx,fy), and they to be chosen such that you get the desired output. The above code contains an example of a polar transformation. It interprets x as the angle and y as the radius. Of course, you need to make some choices like the factor 5 in sin(#1*5) and 10 in (#2+10). –  Jan 19 '20 at 16:56
  • Thank you very much, I get it now. – lorem97 Jan 19 '20 at 17:02