我需要绘制一个类似于下图的游戏树。有没有办法使用 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}
这个有automata
和positoning
库。
\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}
可以单独创建网格。