0

Edit new question formulation

I wan't to distort an image so it fits within 4 poins defining a plane.

@abcdefg suggested an answer and I took a look at it: Text in TikZ with perspective (not just slant)

Which seems to do what I wan't, but I have no idea how to transform this into an image being bounded by 4 3D points.

I have tried the following:

\documentclass{standalone}

\usepackage{tikz} \usepackage[skins]{tcolorbox} \usepackage{graphicx} \usepackage{duckuments} \usetikzlibrary{3d,calc,positioning,perspective}

\makeatother % \begin{document} \begin{tikzpicture}

%Creating the points I want the image to fill withh the image
\coordinate (ll) at (4,-1,0) ;%The lower left corner of the image should go here
\coordinate (lr) at (6,-2,-1) ;%The lower right corner of the image should go here
\coordinate (ur) at (6,1,1) ;%The upper left corner of the image should go here
\coordinate (ul) at (4,1,2) ;%The upper right corner of the image should go here

\foreach \co in {ll,lr,ur,ul}{
    \fill[red] (\co) circle (0.1);
}

%Failing at filling the image within the points
\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)}}
\pgfmathdeclarefunction{gx}{2}{\pgfmathparse{1*#1}}
    \pgfmathdeclarefunction{gy}{2}{\pgfmathparse{1*#2}}
    \pgfmathdeclarefunction{gz}{2}{\pgfmathparse{#1+13}}
    \pgfmathdeclarefunction{fx}{2}{\pgfmathparse{gx(#1,#2)*6/gz(#1,#2)}}
    \pgfmathdeclarefunction{fy}{2}{\pgfmathparse{gy(#1,#2)*6/gz(#1,#2)}}
    \foreach\i in{4,...,6}{
    \foreach\j in{-2,...,1}{
        \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}
        }{
            \clip(1,0)--(0,0)--(0,1)--cycle;
            \draw(1,0)--(0,0)--(0,1)--cycle;
            \tikzset{shift={(-\i,-\j)}}
    \path(0.5,.5)node{\includegraphics{example-image-a}};
        }
        \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;
            \draw(0,0)--(-1,0)--(0,-1)--cycle;
            \tikzset{shift={(-\i-1,-\j-1)}}
    \path(0.5,.5)node{\includegraphics{example-image-a}};
        }
    }
}

\draw[step=5mm] (1,-2) grid (7,1);

\end{tikzpicture}

\end{document} \end{document}

And as you can see, It has been to no avail ;-(

enter image description here

The ideal situation would off course be having a command like:

\graphicsto3dsurface{(ll),(lr),(ur),(ul),\includegraphics{example-image-a}

That puts the image within my 4 red points.

Edit : previous formulation

titled: fill stretch image in non rectangular shapes (for 3D)

I'm drawing some stuff in 3D, and I'm trying to add an image of some data to a 3d surface.

To do this, I found the [fill stretch image=example-image-duck] command from the tcolorbox package here: How to create a rectangle filled with image using TikZ?

This works great in 2D, but it seems to have problems with 3D systems: It cannot disstort (turn) the image (or stretch it in different amounts in different areas). I tried to fix this by turning the image myself. As seen below, it did not go well ;-(

This is seen in the MWE below:

\documentclass{standalone}

\usepackage{tikz} \usepackage[skins]{tcolorbox} \usepackage{graphicx} \usepackage{duckuments} \usetikzlibrary{3d,calc,positioning}

\begin{document} \begin{tikzpicture}[z={(90:30mm)},x={(190:30mm)},y ={(-45:24mm)},line join=round]

    \path[overlay] (0,0,0) coordinate (O) (1,0,0) coordinate (ex)
          (0,1,0) coordinate (ey) (0,0,1) coordinate (ez);
    \tikzset{yzx space/.style={x={(ey)},y={(ez)},z={(ex)}}} 
    \tikzset{xzy space/.style={x={(ex)},y={(ez)},z={(ey)}}} 
    \tikzset{xyz space/.style={x={(ex)},y={(ey)},z={(ez)}}} 

    \path[fill stretch image=example-image-duck] (0,0,0) -- ++(0,0,1) -- ++(0,1,0) node[midway,above, sloped] {3D distortion} -- ++(0,0,-1) -- cycle;


    \begin{scope}[x={(0:30mm)},y={(90:30mm)}]
        \path[fill stretch image=example-image-duck] (-1.2,-0.2) rectangle ++(1,1);
        \node[anchor = south] at (-0.7,1) {correct in flat 2D};
        \path[fill stretch image=example-image-duck] (-2.3,-0.4) -- ++(1,-0.2) -- ++(0,1.4) -- ++(-1,-0.2)  -- cycle;
        \node[anchor = south] at (-1.7,1) {2D distortion};
    \end{scope}

    \path[fill stretch image*={angle=-45}{example-image-duck}] (3,0,0.5) -- ++(0,0,1) -- ++(0,1,0) node[midway,above, sloped] {my Correction attempt} -- ++(0,0,-1)  -- cycle;
\end{tikzpicture}

\end{document}

Which produces:

enter image description here

To me it looks like tcolorbox is just cutting out the part of the image that would be outside the path. But this means that the image is facing the not correct way.

To make the image face the direction of the 3d surface it is on, the diagonals of the example-image-duck should end up at the corners of the shape it is filling. Is there a way to ensure this happens in tikz? I havn't been able to find one in the tcolorbox documentation, but that's no guarantee for it not being there.

Inspired by @abcdefg I tried Curving the cylinder in a periodic fashion (I also went to example-image-a to better see if I was getting any perspective, sorry ducks)

I might have completly misunderstood the answers, but It doesn't seem like the image itself is getting any perspective.

My problem wasn't really related to the perspective of 3d objects in my picture (the tikz3d library took care of that) But in distorting the image so that its four corners end up where I want them (as defined by the \path)

here's what I tried:

\documentclass{standalone}

\usepackage{tikz} \usepackage[skins]{tcolorbox} \usepackage{graphicx} \usepackage{duckuments} \usetikzlibrary{3d,calc,positioning,perspective}

\makeatletter \tikzset{switch on perspective/.code={\def\tikz@parse@splitxyz##1##2##3,##4,{% \def\pgfutil@next{\tikz@scan@one@point##1(tpp cs:x={##2},y={##3},z={##4})}% https://tex.stackexchange.com/a/365418/194703 }}} \makeatother

\begin{document} \begin{tikzpicture}[3d view={140}{30},line join=round]

\begin{scope}[perspective={p={(0.1,0,0),q=(0,40,0),r=0,0,100)}},switch on perspective]
    \path[fill stretch image=example-image-a] (0,0,0) -- ++(0,0,1) -- ++(0,1,0) node[midway,above, sloped] {3D distortion} -- ++(0,0,-1) -- cycle;
\end{scope}

\end{tikzpicture}

\end{document}

And the resulting (perspectiveless) picture: enter image description here

Having played around a bit more with the perspective library and the switch on perspective command I can see that they work. They just don't add perspective to images.

  • You can project external graphics on a plane. If you want to have a perspective effect, you can use https://tex.stackexchange.com/a/479188. Of course, for the duck you can just use tikzducks and install a perspective view from the tpp library to achieve this effect. You will need something along the lines of this answer to achieve this without looking at the tikzducks source. –  Nov 17 '20 at 18:14
  • This is an explicit example that installs perspective coordinates without the need to use the (tpp cs:x=....) syntax explicitly. –  Nov 17 '20 at 18:19
  • @abcdefg It seems like tpp cs:... only adds perspective to drawings, and not to images. Guess I was looking at the wrong answer from your list :-) – Thorbjørn E. K. Christensen Nov 18 '20 at 08:40
  • @abcdefg In tex.stackexchange.com/a/479188 how would I parse my 3d coordinates to the system? – Thorbjørn E. K. Christensen Nov 18 '20 at 08:42
  • This is encoded in the function gx, gy and gz. I am not sure if anyone has worked out explicitly a code that infers these functions from a given projection, but I might be wrong. If this is your aim, please ask a separate question on this, or reword this question. Please note also that https://tex.stackexchange.com/a/319222 goes in the same direction, but again the application is not immediate in my opinion. –  Nov 18 '20 at 16:04

0 Answers0