Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

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

share|improve this question
add comment

3 Answers

up vote 12 down vote accepted

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.

share|improve this answer
3  
Smashing!!! (+1) –  Thorsten Donig Apr 3 '11 at 17:30
    
Nice solution! I was doing something similar, but your implementation is better than mine. –  Gonzalo Medina Apr 3 '11 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 '13 at 16:34
1  
@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 '13 at 7:56
add comment

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.

share|improve this answer
add comment

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

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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