8

I would like to draw something like this:

enter image description here

The best I can do so far:

\documentclass{article}
\usepackage{tikz}

\begin{document}
\resizebox{0.95\textwidth}{!}{
\begin{tikzpicture}
\newcommand\Square{+(-1,-1) rectangle +(1,1)}
\draw (0,0) rectangle (8,6);\node at (4,0.5) {$I_1$};
\node[label=$p$]  (p) at (3,4) {};
\draw [orange] plot [only marks, mark size=2.5, mark=*] coordinates {(3,4)};
\draw[fill =blue,fill opacity=0.1] (p)  \Square;

\draw (10,0) rectangle (18,6);\node at (14,0.5) {$I_2$};
\node[label=below:$p'$]  (p') at (12.5,2.7) {};
\draw [orange] plot [only marks, mark size=2.5, mark=*] coordinates {(12.5,2.7)};

\draw[thick,->] (p) edge[bend right] (p');
\draw[fill =blue,fill opacity=0.1,rotate=50] (p') \Square;
\end{tikzpicture}}
\end{document}

enter image description here

The result is not very satisfactory. Hope somebody can help. Thank you in advance.

  • Please make your code compilable (if possible), or at least complete it with \documentclass{...}, the required \usepackage's, \begin{document}, and \end{document}. That may seem tedious to you, but think of the extra work it represents for TeX.SX users willing to give you a hand. Help them help you: remove that one hurdle between you and a solution to your problem. – jub0bs Aug 28 '14 at 12:29
7

This can be done quite trivially by using scopes and coordinate transformations.

First thing, intstead of using the "advanced" coordinates routines, simply do:

\fill[orange] (3,4) circle (2.5pt);

which gives the same.

Then onwards to transformations.

The second rectangle can easily be drawn with the same commands and a scope

% Draw next rectangle, move everything 10cm to the right
\begin{scope}[xshift=10cm]

   \draw (0,0) rectangle (8,6);
   \node at (4,0.5) {$I_2$};
   \node[label=$p'$] (p') at (3,4) {};
   \fill[orange] (p') circle (2.5pt);

\end{scope}

Now for the remaining part.

You can do with another scope and transform the coordinates in that scope.
This can be done using the cm={x,xy,yx,y,(coord)} construct. It lets you create a matrix transformation for (x,y) coordinates.

The full thing becomes:

\begin{tikzpicture}[scale=.7]
  \newcommand\Square{+(-1,-1) rectangle +(1,1)}

  % Draw first rectangle and name
  \draw (0,0) rectangle (8,6);
  \node at (4,0.5) {$I_1$};
  \node[label=$p$]  (p) at (3,4) {};
  % Fill square
  \draw[fill=blue,fill opacity=0.1] (p) \Square;
  \draw[->,>=latex] (p) ++(-1,-1) -- ++(2.5,0);
  \draw[->,>=latex] (p) ++(-1,-1) -- ++(0,2.5);
  \fill[orange] (p) circle (2.5pt);

  % Draw next rectangle
  \begin{scope}[xshift=10cm]

    \draw (0,0) rectangle (8,6);
    \node at (4,0.5) {$I_2$};
    \node[label=$p'$] (p') at (3,4) {};
    \fill[orange] (p') circle (2.5pt);

    \begin{scope}[cm={.74,.74,-.74,.74,(0,0)}]
      \draw[->,>=latex] (p') ++(-1,-1) -- ++(2.5,0);
      \draw[->,>=latex] (p') ++(-1,-1) -- ++(0,2.5);
      \draw[fill=blue,fill opacity=0.1] (p') \Square;

    \end{scope}

  \end{scope}

  \draw[thick,->] (p) edge[bend right] (p');
\end{tikzpicture}

And it produces this:

enter image description here

You can easily adapt the different elements in the transformation.

  • This solves my problem. Thanks a lot, zeroth! – Khue Aug 28 '14 at 13:12
  • 1
    Only one remark: '\fill[orange] (p) circle (2.5pt);' is better than '\fill[orange] (3,4) circle (2.5pt);'. – Khue Aug 28 '14 at 13:25
  • @Khue, sure I must have overlooked it, will update. – zeroth Aug 29 '14 at 13:51
  • Instead of the xshift you can fill in the remaining zero entries of cm which is the affine translation vector. – percusse Aug 29 '14 at 14:56
  • @percusse only if drawing it separately, in this case with the square and node it makes more sense to do two scopes (we do not want the transformation on the rectangle). – zeroth Sep 1 '14 at 6:58
1

Do you mean your result is not satisfactory depending on its code or its looking? If you want to get some code that can be reused you can do the following for example. It uses the scope-environment to do the shift and rotate.

\documentclass[tikz, border=5mm]{standalone}

\begin{document}
 \begin{tikzpicture}[very thick]
 \foreach \xoffset\lbl in {0/1,10/2} {
  \draw (\xoffset,0) rectangle ++(8,6) node [midway,below=2cm] {$I_\lbl$};
 }

 \newcommand{\Square}[4]{
  % Draw a square with {(x,y)}{rotation}{label}{name}
  \begin{scope}[shift={#1}, rotate=#2, >=latex]
   \draw [fill=blue!10!white] (-1,-1) rectangle (1,1) node [midway, circle, fill=orange, inner sep=2pt, label={90:{#3}}] (#4) {};
   \draw [<->] (1.5,-1) -- ++(-2.5,0) -- ++(0,2.5);
  \end{scope}
  }

  % Draw the squares and connect their centers
  \Square{(3,4)}{0}{$p$}{p1}
  \Square{(12,3)}{45}{$p'$}{p2}
  \draw [->] (p1) to [out=-75, in=195] (p2);
 \end{tikzpicture}
\end{document}

This way you can reuse your \Square very easily and reference it as a node. You can add additional parameters (rotation of node label, ...) as you wish. The code produces the following:

Rendered image

  • Hi. Thanks for the answer. I meant the looking was not satisfactory because, as you can see, the obtained result does not look like the one in the picture. The transformation in the picture is an affine transformation (i.e. translation+rotation+shearing) and not just translation+rotation. The command 'cm', as suggested by @zeroth, solves that problem for me. But you are right, my code is neither satisfactory at all :p Thanks for sharing your code. Very helpful. +1. – Khue Aug 28 '14 at 13:22

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.