绘制网格树

绘制网格树

我需要绘制一个类似于下图的游戏树。有没有办法使用 Tikz 包来做到这一点,以便可以简单地将网格添加为节点?

网格树

答案1

TikZ 没有这种形式的节点形状。但由于它只是一个添加了一些线条的矩形,因此定义起来相对简单(一旦知道如何定义形状)。

\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}

上述代码定义了一个名为的节点形状grid,它基本上是一个带有网格的矩形。它还定义了一个grid lines键(默认值为 2)来设置矩形内的网格线数量。

上述代码的结果

更新:我添加了一些有用的锚点。

答案2

一个想法,但尺寸有问题,比如 3 厘米。这个修改后的版本更简单,但我总是遇到像 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}

使用下一个代码 3*3 网格工作

\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}

在此处输入图片描述

答案3

我看到两种可能的解决方案。

这个是trees图书馆的。

\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}

在此处输入图片描述


这个有automatapositoning库。

\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}

在此处输入图片描述


可以单独创建网格。

相关内容