13

I need to draw a game tree that is similar to the image below. Is there any way to do this using the Tikz package so that the grids can simply be added as nodes?

Tree of grids

0

3 Answers 3

14

TikZ doesn't have a node shape of this form. But since it is just a rectangle with some added lines, it is relatively straightforward to define (once knowing how to define shapes).

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{positioning}

\makeatletter
\pgfkeys{/pgf/grid lines/.initial=2}

\pgfdeclareshape{grid}{
    % inherit most things from the rectangle shape
    \inheritsavedanchors[from=rectangle]
    \inheritanchorborder[from=rectangle]
    \inheritanchor[from=rectangle]{center}
    \inheritanchor[from=rectangle]{north}
    \inheritanchor[from=rectangle]{south}
    \inheritanchor[from=rectangle]{west}
    \inheritanchor[from=rectangle]{east}
    \inheritanchor[from=rectangle]{south east}
    \inheritanchor[from=rectangle]{south west}
    \inheritanchor[from=rectangle]{north east}
    \inheritanchor[from=rectangle]{north west}
    \inheritbackgroundpath[from=rectangle]

    \savedmacro\lines{%
        \pgfmathtruncatemacro\lines{\pgfkeysvalueof{/pgf/grid lines}}%
    }

    % draw the grid
    \beforebackgroundpath{
        % store lower right in xa/ya and upper right in xb/yb
        \southwest \pgf@xa=\pgf@x \pgf@ya=\pgf@y
        \northeast \pgf@xb=\pgf@x \pgf@yb=\pgf@y

        % compute distance between the lines
        \pgfmathparse{(\the\pgf@xb-\the\pgf@xa)/(\lines + 1)}
        \pgf@xc=\pgfmathresult pt
        \pgfmathparse{(\the\pgf@yb-\the\pgf@ya)/(\lines + 1)}
        \pgf@yc=\pgfmathresult pt

        % draw grid
        \c@pgf@counta=0
        \c@pgf@countb\lines\relax
        \pgf@xb=\pgf@xa
        \advance\pgf@xb\pgf@xc\relax
        \pgfmathloop
            \ifnum\c@pgf@counta<\c@pgf@countb
                \pgfpathmoveto{\pgfpoint{\pgf@xb}{\pgf@ya}}
                \pgfpathlineto{\pgfpoint{\pgf@xb}{\pgf@yb}}
                \advance\c@pgf@counta 1\relax
                \advance\pgf@xb\pgf@xc\relax
        \repeatpgfmathloop
        % set \pgf@xb to the right side
        \c@pgf@counta=0
        \pgf@yb=\pgf@ya
        \advance\pgf@yb\pgf@yc\relax
        \pgfmathloop
            \ifnum\c@pgf@counta<\c@pgf@countb
                \pgfpathmoveto{\pgfpoint{\pgf@xa}{\pgf@yb}}
                \pgfpathlineto{\pgfpoint{\pgf@xb}{\pgf@yb}}
                \advance\c@pgf@counta 1\relax
                \advance\pgf@yb\pgf@yc\relax
        \repeatpgfmathloop
        \pgfusepath{stroke}
    }

    % add anchors for vertices (intersections of grid lines)
    % and center points (centers of the small rectangles).
    %
    % vertex anchors are simply called 'x y' with '0 0' being the lower left
    % vertex.
    % center anchors are called 'center x y' with 'center 1 1' being the center
    % of the lower left rectangle
    \pgfutil@g@addto@macro\pgf@sh@s@grid{%
        \c@pgf@counta\lines
        \advance\c@pgf@counta 1\relax
        \pgfmathloop\ifnum\c@pgf@counta>-1
            {% group to allow nesting of loops
                \c@pgf@countb\lines
                \advance\c@pgf@countb 1\relax
                \pgfmathloop\ifnum\c@pgf@countb>-1
                    \pgfutil@ifundefined{pgf@anchor@grid@\the\c@pgf@counta\space\the\c@pgf@countb}{%
                        % need to use xdef, so that \c@pgf@counta/b are expanded
                        % vertices
                        \expandafter\xdef\csname pgf@anchor@grid@\the\c@pgf@counta\space\the\c@pgf@countb\endcsname{%
                            \noexpand\southwest \noexpand\pgf@xa=\noexpand\pgf@x \noexpand\pgf@ya=\noexpand\pgf@y
                            \noexpand\northeast \noexpand\pgf@xb=\noexpand\pgf@x \noexpand\pgf@yb=\noexpand\pgf@y
                            \noexpand\pgfmathparse{(\noexpand\the\noexpand\pgf@xb-\noexpand\the\noexpand\pgf@xa)/(\noexpand\lines + 1)*\the\c@pgf@counta}
                            \noexpand\pgf@x=\noexpand\pgf@xa\noexpand\relax
                            \noexpand\advance\noexpand\pgf@x\noexpand\pgfmathresult pt\noexpand\relax
                            \noexpand\pgfmathparse{(\noexpand\the\noexpand\pgf@yb-\noexpand\the\noexpand\pgf@ya)/(\noexpand\lines + 1)*\the\c@pgf@countb}
                            \noexpand\pgf@y=\noexpand\pgf@ya\noexpand\relax
                            \noexpand\advance\noexpand\pgf@y\noexpand\pgfmathresult pt\noexpand\relax
                        }
                        % centers
                        \expandafter\xdef\csname pgf@anchor@grid@center\space\the\c@pgf@counta\space\the\c@pgf@countb\endcsname{%
                            \noexpand\southwest \noexpand\pgf@xa=\noexpand\pgf@x \noexpand\pgf@ya=\noexpand\pgf@y
                            \noexpand\northeast \noexpand\pgf@xb=\noexpand\pgf@x \noexpand\pgf@yb=\noexpand\pgf@y
                            \noexpand\pgfmathparse{(\noexpand\the\noexpand\pgf@xb-\noexpand\the\noexpand\pgf@xa)/(2*(\noexpand\lines + 1))*(2*\the\c@pgf@counta-1)}
                            \noexpand\pgf@x=\noexpand\pgf@xa\noexpand\relax
                            \noexpand\advance\noexpand\pgf@x\noexpand\pgfmathresult pt\noexpand\relax
                            \noexpand\pgfmathparse{(\noexpand\the\noexpand\pgf@yb-\noexpand\the\noexpand\pgf@ya)/(2*(\noexpand\lines + 1))*(2*\the\c@pgf@countb-1)}
                            \noexpand\pgf@y=\noexpand\pgf@ya\noexpand\relax
                            \noexpand\advance\noexpand\pgf@y\noexpand\pgfmathresult pt\noexpand\relax
                        }
                    }{\c@pgf@countb0\relax}
                    \advance\c@pgf@countb-1\relax
                \repeatpgfmathloop
            }
            \advance\c@pgf@counta-1\relax
        \repeatpgfmathloop
    }
}
\makeatother

\begin{document}
\begin{tikzpicture}[
        mygrid/.style={
            draw,
            grid,
            grid lines=2,
            minimum width=2cm,
            minimum height=2cm}
        ]
    \node [mygrid,fill=red] (A) at (0,0) {};
    \node [mygrid,below=0.66cm of A] (B) {};
    \node [mygrid,right=0.66cm of B] (C) {};
    \draw[thick] (A) -- (B);
    \draw[thick] (A.south) -- (C.north);
    \node at (A.0 0) {(0,0)};
    \node at (A.1 3) {(1,3)};
    \node at (A.2 2) {(2,2)};
    \node at (A.3 3) {(3,3)};
    \node at (B.1 1) {(1,1)};
    \node at (B.center 1 3) {(1,3)};
    \node at (B.center 2 2) {(2,2)};
    \node at (B.center 3 3) {(3,3)};
    \fill[blue] (C.1 1) rectangle (C.2 2);
\end{tikzpicture}
\end{document}

The above code defines a node shape named grid that is basically a rectangle with a grid. It also defines a grid lines key (with default value 2) to set the number of grid lines inside the rectangle.

result of code above

Update: I added some useful anchors.

5
  • 3
    Smashing!!! (+1) Apr 3, 2011 at 17:30
  • Nice solution! I was doing something similar, but your implementation is better than mine. Apr 3, 2011 at 17:45
  • @Caramdir A very interesting solution. I need something simular, but a non quadratic grid. Would it be possible to change your code to allow lets say a (6,8) grid? Maybe by introducing 'grid hlines' and 'grid vlines'. I tried myself but your code is too complicated for me, as i'm not a tikz expert!
    – Josef
    Feb 4, 2013 at 16:34
  • 2
    @Josef: I actually did this a while ago: Download bazaar.launchpad.net/~tex-sx/tex-sx/development/download/head:/… and run pdflatex on it. You should get two files [pgf|tikz]libraryshapes.tex-sx.code.tex and a .pdf. Copy the .tex files into your document directory (or the tex path) and follow the usage instructions in the pdf.
    – Caramdir
    Feb 6, 2013 at 7:56
  • @Caramdir I, too, am requiring a non quadratic grid. I tried your link but pdflatex fails because of some undefined reference. Seeing the age of this comment: Do you have a more up to date, fixed version by any chance?
    – phdoerfler
    Mar 9, 2022 at 15:29
5

An idea but there is a problem with size like 3 cm. This modified version is easier but I always a problem with grids like 3*3

  \documentclass{scrartcl}
  \usepackage[utf8]{inputenc}
  \usepackage[T1]{fontenc}  
  \usepackage{tikz}  

 \begin{document}
 \begin{tikzpicture}[mygrid/.style={draw,minimum height=#1,minimum width=#1,
   path picture={\draw[black] (-#1,-#1) grid (#1,#1);}}] 
  \node[draw,mygrid=4 cm] (a) at (0,0) {};    
  \node[draw,mygrid=2 cm] (b) at (6,6) {};  
  \draw (a.north east)--(b.west);  
\end{tikzpicture}  
    \end{document}

With the next code 3*3 grids work

\documentclass{scrartcl}
\usepackage{tikz} 

\begin{document}
\begin{tikzpicture}[mygrid/.style={%
           draw,
           minimum height=#1 cm,
           minimum width=#1 cm,
           path picture={%
           \pgfmathsetmacro{\a}{-#1/2}
           \pgfmathsetmacro{\b}{#1/2}
  \foreach \i in {\a,...,\b}{%
   \draw[black] (\i,-#1) -- (\i,#1);
   \draw[black] (-#1,\i) -- (#1,\i);
   }
 }
}] 
\node[mygrid=4] (a) at (0,0) {};    
\node[mygrid=3] (b) at (6,6) {};
\node[mygrid=2] (c) at (2,6) {};  
\draw[>=stealth,->] (a.north east)--([yshift=.5cm]b.west);
\draw[>=stealth,->] (a.north)--(c.south);  
\end{tikzpicture}
\end{document}

enter image description here

\begin{tikzpicture}[mycircle/.style={%
           circle,draw,
           minimum width=#1 cm,
           path picture={%
  \pgfmathsetmacro{\b}{#1/2}
  \foreach \i in {0,0.5,...,\b}{%
   \draw[black] (0,0) circle (\i cm);
   }
 }
}] 
\node[mycircle=4] (a) at (0,0) {};    
\node[mycircle=3] (b) at (6,3) {};
\node[mycircle=2] (c) at (2,6) {};  
\draw[>=stealth,->] (a.north east)--(b.west);
\draw[>=stealth,->] (a.north)--(c.south);  
\end{tikzpicture}

enter image description here

0
3

I see two possible solutions.

This one with the trees library.

\documentclass{minimal}
\usepackage{pgfplots}
\usetikzlibrary{trees}

\begin{document}
  \begin{tikzpicture}[
    edge from parent fork down,
    level distance=6cm,
    sibling distance=6cm
  ]
    \node {\tikz\draw (0,0) grid (3,3);}
      child {node {\tikz\draw (0,0) grid (3,3);}}
      child {node {\tikz\draw (0,0) grid (3,3);}};
  \end{tikzpicture}
\end{document}

enter image description here


And this one with the automata and positoning libraries.

\documentclass{minimal}
\usepackage{pgfplots}
\usetikzlibrary{automata,positioning}

\begin{document}
  \begin{tikzpicture}[%
    auto,
    on grid,
    node distance=6cm
  ]
   \node (1)                    {\tikz\draw (0,0) grid (3,3);};
   \node (2) [below left of=1]  {\tikz\draw (0,0) grid (3,3);};
   \node (3) [below right of=1] {\tikz\draw (0,0) grid (3,3);};

   \path (1.south) edge (2.north)
         (1.south) edge (3.north);
  \end{tikzpicture}
\end{document}

enter image description here


The grids can be created individually.

You must log in to answer this question.

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