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?
3 Answers
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.
Update: I added some useful anchors.
-
3
-
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!– JosefFeb 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.– CaramdirFeb 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? Mar 9, 2022 at 15:29
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}
\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}
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}
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}
The grids can be created individually.