3

I have used the \tikzset{pics ... environment to define a tikz image so that I can repeat and change just a few arguments. However, I would like to have an arrow that connects the two images. I am struggling to do this since I am unsure as to how to make two distinct nodes for each of the images from which the arrow may join.

I have the following image which is created by the MWE below. How can I draw an arrow between the two lines at the top with a label that reads $\theta$.

\documentclass[tikz]{standalone}
\usepackage{pgfplots}
\usetikzlibrary{arrows,shapes,backgrounds,fit,decorations.pathreplacing,chains,snakes,positioning}  
\usepackage{amsmath,amssymb,bm}

\tikzset{
pics/gridd/.style n args={2}{
code = {%
    \def \s{0.5}
    \def \nx{3}
    \def \ny{2}
    \def \dx{3}
    \def \dy{3}
    \def \meshthickness{0.01}
    \pgfmathsetmacro \maxposx {\dx*(\nx-1)/2}   
    \pgfmathsetmacro \maxposy {\dy*(\ny-1)/2}

    \draw[line width = 0.2mm] (0, \maxposy) -- (0, \maxposy + 0.8);

    \filldraw[black] circle (2pt); 

    \draw [dashed, line width = 0.2mm] (-\maxposx,\maxposy) -- (\maxposx,\maxposy);
    \draw [dashed, line width = 0.2mm] (\maxposx,\maxposy) -- (\maxposx,-\maxposy);
    \draw [dashed, line width = 0.2mm] (-\maxposx,-\maxposy) -- (\maxposx,-\maxposy);
    \draw [dashed, line width = 0.2mm] (-\maxposx,-\maxposy) -- (-\maxposx,\maxposy);
    \draw [dashed, line width = 0.2mm] (0,-\maxposy) -- (0,\maxposy);

    \foreach \i in {1,...,\nx}{
        \foreach \j in {1,...,\ny}{
            \pgfmathsetmacro \x {(\i - (\nx + 1)/2)*\dx}        
            \pgfmathsetmacro \y {(\j - (\ny + 1)/2)*\dy}
            \filldraw[#1, draw=black, line width = 0.2mm] (\x,\y) circle (#2);
        }
    }
}}}

\begin{document}

\begin{tikzpicture}

\pic {gridd={fill=blue!20!white}{3mm}};

\begin{scope}[rotate around z=20]
\pic {gridd={fill=red!80!white}{3mm}};
\end{scope}

\end{tikzpicture}

\end{document}

2 Answers 2

2

If you have a node/coordinate named bar in the pic, and the pic itself is named foo, then you can refer to that node as foobar (name of pic plus name of node).

Because the rotation is around the center of the pic, it's probably a bit easier to highlight the angle between the vertical lines, as you can just load the angles and quotes libraries, and then use the predefined angle pic.

Some more explanations:

The additions I made to the code are not extensive. In the pic itself, I added a coordinate at the center, and at each of the vertices:

\filldraw[black] circle (2pt) coordinate (-c); 

Here the coordinate (-c) is new, and similarly in the loop,

\filldraw[#1, draw=black, line width = 0.2mm] (\x,\y) circle (#2) coordinate (-\i-\j);

coordinate (-\i-\j) is new. So for example the bottom left corner has a coordinate named (-1-1), internally in the pic.

When using the pic, I gave them names, a and b:

\pic (a) {gridd={fill=blue!20!white}{3mm}};

Because of how pics work, that means that the coordinate in the bottom left corner of this pic is named a-1-1.

(This is mentioned in chapter 18 of the TikZ manual, where pics are described.)


To draw the angle itself, I loaded the angles and quotes libraries. The first of these defines a pic precisely for drawing such angles. It is used as pic {angle=<coord 1>--<coord 2>--<coord 3>}. You need three named coordinates, and this pic draws the angle between them. It is described in chapter 39 of the TikZ manual (look in the table of contents under the Libraries part).

So what I used was

\pic ["$\theta$",angle radius=1cm,draw,-stealth] {angle={a-2-2--a-c--b-2-2}};

You see that a-2-2 is the middle, top vertex of the a pic, a-c is the center point of the a pic, and b-2-2 is the top middle of the b pic.

The use of "<text>" is a shorthand made possible by the quotes library, for adding labels to a path. (This library is described in section 17.10.4 The quotes syntax of the manual.) angle radius is self explanatory I suppose, and the last part is to specify that the path should be draw, with an arrow tip.

output of code

\documentclass[tikz]{standalone}
\usepackage{pgfplots}
\usetikzlibrary{arrows,shapes,backgrounds,fit,decorations.pathreplacing,chains,snakes,positioning,angles,quotes}  
\usepackage{amsmath,amssymb,bm}

\tikzset{
pics/gridd/.style n args={2}{
code = {%
    \def \s{0.5}
    \def \nx{3}
    \def \ny{2}
    \def \dx{3}
    \def \dy{3}
    \def \meshthickness{0.01}
    \pgfmathsetmacro \maxposx {\dx*(\nx-1)/2}   
    \pgfmathsetmacro \maxposy {\dy*(\ny-1)/2}

    \draw[line width = 0.2mm] (0, \maxposy) -- (0, \maxposy + 0.8);

    \filldraw[black] circle (2pt) coordinate (-c); 

    \draw [dashed, line width = 0.2mm] (-\maxposx,\maxposy) -- (\maxposx,\maxposy);
    \draw [dashed, line width = 0.2mm] (\maxposx,\maxposy) -- (\maxposx,-\maxposy);
    \draw [dashed, line width = 0.2mm] (-\maxposx,-\maxposy) -- (\maxposx,-\maxposy);
    \draw [dashed, line width = 0.2mm] (-\maxposx,-\maxposy) -- (-\maxposx,\maxposy);
    \draw [dashed, line width = 0.2mm] (0,-\maxposy) -- (0,\maxposy);

    \foreach \i in {1,...,\nx}{
        \foreach \j in {1,...,\ny}{
            \pgfmathsetmacro \x {(\i - (\nx + 1)/2)*\dx}        
            \pgfmathsetmacro \y {(\j - (\ny + 1)/2)*\dy}
            \filldraw[#1, draw=black, line width = 0.2mm] (\x,\y) circle (#2) coordinate (-\i-\j);
        }
    }
}}}

\begin{document}

\begin{tikzpicture}

\pic (a) {gridd={fill=blue!20!white}{3mm}};

\begin{scope}[rotate around z=20]
\pic (b) {gridd={fill=red!80!white}{3mm}};
\end{scope}


\pic ["$\theta$",angle radius=1cm,draw,-stealth] {angle={a-2-2--a-c--b-2-2}};
\end{tikzpicture}

\end{document}
3
  • This is great. Although exactly what I wanted, I still don't follow how you managed to use nodes for this. Any suggestions on what I could read to understand this?
    – Sid
    Sep 5, 2017 at 15:33
  • @Sid I don't quite follow, but I can add some more explanations to my answer. Will ping you when I've updated. Sep 5, 2017 at 15:37
  • @Sid Updated answer. Sep 5, 2017 at 15:52
2

Another option with tikz-Euclide.

\documentclass[tikz]{standalone}
\usepackage{pgfplots}
\usetikzlibrary{arrows,shapes,backgrounds,fit,decorations.pathreplacing,chains,snakes,positioning}  
\usepackage{amsmath,amssymb,bm}
\usepackage{tkz-euclide} %%% ADDED
\tikzset{
pics/gridd/.style n args={2}{
code = {%
    \def \s{0.5}
    \def \nx{3}
    \def \ny{2}
    \def \dx{3}
    \def \dy{3}
    \def \meshthickness{0.01}
    \pgfmathsetmacro \maxposx {\dx*(\nx-1)/2}   
    \pgfmathsetmacro \maxposy {\dy*(\ny-1)/2}

    \draw[line width = 0.2mm] (0, \maxposy) -- (0, \maxposy + 0.8);

    \filldraw[black] circle (2pt); 

    \draw [dashed, line width = 0.2mm] (-\maxposx,\maxposy) -- (\maxposx,\maxposy);
    \draw [dashed, line width = 0.2mm] (\maxposx,\maxposy) -- (\maxposx,-\maxposy);
    \draw [dashed, line width = 0.2mm] (-\maxposx,-\maxposy) -- (\maxposx,-\maxposy);
    \draw [dashed, line width = 0.2mm] (-\maxposx,-\maxposy) -- (-\maxposx,\maxposy);
    \draw [dashed, line width = 0.2mm] (0,-\maxposy) -- (0,\maxposy);

    \foreach \i in {1,...,\nx}{
        \foreach \j in {1,...,\ny}{
            \pgfmathsetmacro \x {(\i - (\nx + 1)/2)*\dx}        
            \pgfmathsetmacro \y {(\j - (\ny + 1)/2)*\dy}
            \filldraw[#1, draw=black, line width = 0.2mm] (\x,\y) circle (#2);
        }
    }
}}}

\begin{document}

\begin{tikzpicture}
\tkzDefPoints{-0.8/2.1/A, 0/2.3/B}; %ADDED
\draw[stealth-stealth] (A) -- (B); % ADDED
\tkzLabelSegment[sloped](A,B) {$\theta$}; %ADDED
\pic {gridd={fill=blue!20!white}{3mm}};

\begin{scope}[rotate around z=20]
\pic {gridd={fill=red!80!white}{3mm}};
\end{scope}

\end{tikzpicture}

\end{document}

Defining A en B relative to your dots, could make it work. enter image description here

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .