我想制作一个 TikZ 对象矩阵,然后绘制一些垂直和水平线。例如,我想将多边形分割表格环境中的示例。到目前为止,我检查了 20 多个类似的问题,但没有一个能真正帮助我。
我创建了以下我想要的最小工作示例。这个想法是创建所有可能的 3 个顶点的简单网络,并根据它们的边数 (m) 将它们绘制成大行,并根据顶部顶点的度数 (k) 分组为列。在每一行中,我把存在水平较粗边的情况放在顶部,把不存在的情况放在底部。每个大列都由左上角顶点的度数定义,每个较小的单独子列分别具有左上角和右上角顶点的度数对。
\documentclass{minimal}
\usepackage{tikz}
\usetikzlibrary{matrix}
\begin{document}
\def\side{0.5} % Define the size of the triangle's side
\newcommand{\slice}[1]{% Inverted triangle network
\filldraw (-\side/2, {sqrt(3)*\side/2}) circle (1pt) (\side/2, {sqrt(3)*\side/2}) circle (1pt) (0, 0) circle (1pt);
\filldraw \foreach \x/\y in {#1} {(\x) -- (\y)};
}
\begin{tikzpicture}
% Define the inverted triangle coordinates
\coordinate (A) at (-\side/2, {sqrt(3)*\side/2});
\coordinate (B) at (\side/2, {sqrt(3)*\side/2});
\coordinate (C) at (0, 0);
% Start the matrix
\matrix (M) [matrix of nodes, nodes={text width=7mm}, row sep=\side*0.3cm]
{
{} & 0 & {} & {} & 1 & {} & {} & 2 & $k_i$ \\
{} & $[0,0]$ & $[0,1]$ & $[1,0]$ & $[1,1]$ & $[1,2]$ & $[2,1]$ & $[2,2]$ & $[k_i,k_j]$ \\
0 & \slice{} & {} & {} & {} & {} & {} & {} & {} \\
{} & {} & {} & {} & \slice{A/B} \draw[ultra thick] (A) -- (B); & {} & {} & {} & {} \\
1 & {} & \slice{B/C} & \slice{A/C} & {} & {} & {} & {} & {} \\
{} & {} & {} & {} & {} & \slice{A/B, B/C} \draw[ultra thick] (A) -- (B); & \slice{A/B, A/C} \draw[ultra thick] (A) -- (B); & {} & {} & {} \\
2 & {} & {} & {} & \slice{A/C, B/C} & {} & {} & {} & {} \\
3 & {} & {} & {} & {} & {} & {} & \slice{A/B, A/C, B/C} \draw[ultra thick] (A) -- (B); & {} \\
{} & {} & {} & {} & {} & {} & {} & {} & {} \\
$m$ & {} & {} & {} & {} & {} & {} & {} & {} \\
};
% vertical lines
\foreach \i in {2,...,9}{
\draw (M-2-\i.north west) -- (M-9-\i.south west);
}
\draw[ultra thick]
(M-1-2.north west) -- (M-9-2.south west)
(M-1-4.north west) -- (M-9-4.south west)
(M-1-7.north west) -- (M-9-7.south west)
(M-1-9.north west) -- (M-9-9.south west)
;
% horizontal lines
\draw
(M-2-2.south west) -- (M-2-8.south east)
(M-3-1.south west) -- (M-3-8.south east)
(M-5-1.south west) -- (M-5-8.south east)
(M-7-1.south west) -- (M-7-8.south east)
(M-9-1.south west) -- (M-9-8.south east)
;
\end{tikzpicture}
\end{document}
我面临的问题是:
- 绘制垂直线和水平线时,我被迫添加额外的行或列,因为其他方式我收到了类似的错误
包 pgf 错误:没有已知名为 Mij 的形状……
其中 ij 当然代表我的对象(三角网络)的位置。一个很好的例子是我添加的倒数第二行。只要矩阵节点中没有对象,即使有像 {} 这样的空元素,一切就都正常。
- 我不知道将行号或列号居中的最佳方法是什么。对于括号内的度数对来说,这甚至很难做到,所以我手动使用命令
文本宽度,
对于网络对象,我必须手动调整它们的坐标位置。
- 我不太明白为什么较粗的垂直线大小不一样。总的来说,我想轻松控制和绘制线条。任何使其类似于表格环境的建议都将不胜感激。
- 我把 m 和 k 留在它们实际位置的原因是我在 1. 中解释过的内容,所以如果有人能帮助我把它们很好地放在矩阵的左上角,那就太棒了。
提前谢谢了,
乔治
答案1
- 错误
shape unknown
出现是因为你没有告诉 T我您想要的 kZnodes in empty cells
。 - 您的方法存在的问题之一是嵌套
tikzpicture
s。这有点直观,text width
与嵌套tikzpicture
s 冲突。您可以使用minimum size
和align=center
。 - 我不明白您的第三个问题,但在下面的答案中,线条具有指定的宽度。
- 我也不明白第 4 个问题,但也许你可以告诉我(哪个?)
k
应该在哪里。
这是更新后的代码。还请注意,为了在单元格之间画线,还必须在给south east
定单元格之间(而不是单元格的左右)画线。这行不通,因为单元格之间有间隙。这就是我使用所有语法的原因($(...)!0.5!(...)$)
,这些语法只计算两个坐标的平均值。我还努力在代码中添加了解释。
\documentclass[border=3.14mm]{standalone}
\usepackage{tikz}
\usetikzlibrary{matrix,calc,fit}
\newcounter{slicenum}
\begin{document}
\def\side{0.5} % Define the size of the triangle's side
% in order to avoid nesting nodes, we draw the triangles as path pictures
% another option would be to store the triangles in \savebox es and use those
% for the nodes. But this approach is more flexible.
% Also, in order to avoid confusion, I introduced a counter to discriminate
% the nodes. Of course, this is not strictly necessary, and one may make this
% slightly more elegant by using prefixes, but for the moment this will do.
\tikzset{slice/.style={path picture={
\stepcounter{slicenum}
% \draw (path picture bounding box.south west) rectangle
% (path picture bounding box.north east);
\coordinate (O-\theslicenum) at ($(path picture bounding box.south
west)!0.5!(path picture bounding box.north east)$);
\pgfmathsetmacro{\myshift}{2*(1-sqrt(3)/2)*\side}
\coordinate (A-\theslicenum) at
($(O-\theslicenum)+(150:\side)+(0,{\myshift})$);
\coordinate (B-\theslicenum) at ($(O-\theslicenum)+(30:\side)+(0,{\myshift})$);
\coordinate (C-\theslicenum) at ($(O-\theslicenum)+(-90:\side)+(0,{\myshift})$);
\filldraw (A-\theslicenum) circle (1pt) (B-\theslicenum) circle (1pt) (C-\theslicenum) circle (1pt);
\foreach \x/\y/\z in {#1} {\draw[\z] (\x-\theslicenum) -- (\y-\theslicenum);}
}}}
\begin{tikzpicture}
% Start the matrix
\matrix (M) [matrix of nodes,nodes in empty cells,nodes={
minimum width=2.4*\side*1cm,minimum height=2*\side*1cm,align=center}]
{
& & & & & & & & \\
\makebox[0.8cm][r]{$[k_i,k_j]$} & $[0,0]$ & $[0,1]$ & $[1,0]$ & $[1,1]$ & $[1,2]$ & $[2,1]$ & $[2,2]$ &
\\
& |[slice=]| & & & & & & & \\
& & & & |[slice={A/B/ultra thick}]| & & & & \\
& & |[slice={B/C/}]| & |[slice={A/C/}]| & & & & & \\
& & & & & |[slice={A/B/ultra thick, B/C/}]| & |[slice={A/B/ultra thick, A/C/}]|
& & & \\
& & & & |[slice={A/C/, B/C/}]| & & & & \\
& & & & & & & |[slice={A/B/ultra thick, A/C/, B/C/}]| & \\
& & & & & & & & \\
& & & & & & & & \\
};
\path (M-1-2) -- (M-1-3) node[midway]{0} (M-1-4) -- (M-1-6) node[midway]{1}
(M-1-7) -- (M-1-8) node[midway]{2} (M-1-1) node[right]{$k_i$};
\path (M-3-1) node(0){$0$} (M-4-1)-- (M-5-1) node[midway](1){$1$}
(M-6-1)-- (M-7-1) node[midway](2){$2$} (M-8-1)-- (M-9-1) node[midway](3){$3$} ;
% horizontal lines
\path (0) -- (3) node[midway,left=6mm] (m) {$m$};
\foreach \X in {0,...,3}
{\draw[-latex] (m) to[out=90-\X*60,in=180] (\X);}
\newcommand{\DrawHorizontalLineInMatrix}[3][]{
\xdef\Lst{(M-#2-2)}
\foreach \XX in {3,...,8}
{\xdef\Lst{\Lst (M-#2-\XX)}}
\node [fit=\Lst,inner sep=0pt] (fit-#2) {};
\xdef\Lst{(M-#3-2)}
\foreach \XX in {3,...,8}
{\xdef\Lst{\Lst (M-#3-\XX)}}
\node [fit=\Lst,inner sep=0pt] (fit-#3) {};
\draw[#1] ($(fit-#2.south west)!0.5!(fit-#3.north west)$)
-- ($(fit-#2.south east)!0.5!(fit-#3.north east)$);
}
\foreach \X[evaluate=\X as \Y using {int(\X-1)}] in {2,4,...,10}
{
\DrawHorizontalLineInMatrix[]{\Y}{\X}
}
% vertical lines
\newcommand{\DrawVerticalLineInMatrix}[3][]{
\xdef\Lst{(M-1-#2)}
\foreach \XX in {2,...,9}
{\xdef\Lst{\Lst (M-\XX-#2)}}
\node [fit=\Lst,inner sep=0pt] (fit-#2) {};
\xdef\Lst{(M-1-#3)}
\foreach \XX in {2,...,9}
{\xdef\Lst{\Lst (M-\XX-#3)}}
\node [fit=\Lst,inner sep=0pt] (fit-#3) {};
\draw[#1] ($(fit-#2.north east)!0.5!(fit-#3.north west)$)
-- ($(fit-#2.south east)!0.5!(fit-#3.south west)$);
}
\DrawVerticalLineInMatrix{1}{2}
\foreach \X[evaluate=\X as \Y using {int(\X-1)}] in {2,4,7,9}
{
\DrawVerticalLineInMatrix[ultra thick]{\Y}{\X}
}
\end{tikzpicture}
\end{document}
答案2
使用范围来定位相应矩阵节点中心内的定义图的选项。
梅威瑟:
\documentclass[tikz,border=14pt]{standalone}
\usepackage{tikz}
\usetikzlibrary{matrix,arrows.meta, positioning,fit,shapes}
\begin{document}
\begin{tikzpicture}[
%Environment config
>={Stealth[inset=0pt,length=6pt]},
%Environment Styles
MyMatrix/.style={
matrix of nodes,
font=\scriptsize,
line width=0.75pt,
column sep=-0.5pt,
row sep=-0.5pt,
text height=18pt,
text width =24pt,
text depth =12pt,
align=center,
nodes={draw=none},
nodes in empty cells
}
]
% Start Drawing the thing
\matrix[
MyMatrix,
column 1/.style={nodes={draw=none},text width =12pt},
row 1/.style={text height =9pt,text depth =6pt},
row 2/.style={text height =9pt,text depth =4pt}
] at (0,0) (M1){%Matrix contents
&&&&&&&&\\
&$[0,0]$&$[0,1]$&$[1,0]$&$[1,1]$&$[1,2]$&$[2,1]$&$[2,2]$&$[k_i,k_j]$\\
&&&&&&&&\\
&&&&&&&&\\
&&&&&&&&\\
&&&&&&&&\\
&&&&&&&&\\
&&&&&&&&\\
&&&&&&&&\\
&&&&&&&&\\
};
%Draw thick vertical lines
\foreach \x in {1,3,5,7,9}{
\draw[line width=2pt](M1-1-\x.north east) -- (M1-10-\x.south east);
}
%Draw horizontal lines
\foreach \x in {1,2,...,10}{
\draw[line width=0.5pt](M1-\x-1.south east) -- (M1-\x-9.south east);
}
%Label row1
\foreach \x [count=\k from 1, evaluate=\k as \m using {int(\k*2)}] in {0,1,2,$k_i$}{
\node at (M1-1-\m.0){\x};
}
%Label col1
\foreach \x [count=\k from 1, evaluate=\k as \m using {int(1+\k*2)}] in {0,1,2,3}{
\node at (M1-\m-1.center){\x};
}
\def\slice(#1)[#2][#3][#4]{
\begin{scope}[shift={(#1)}]
\node[circle,fill,inner sep=1pt](c1) at (30:10pt){};
\node[circle,fill,inner sep=1pt](c2) at (150:10pt){};
\node[circle,fill,inner sep=1pt](c3) at (270:10pt){};
\path[#2](c1.center)--(c2.center);
\path[#3](c2.center)--(c3.center);
\path[#4](c3.center)--(c1.center);
\end{scope}
}
\slice(M1-3-2.center)[][][]
\slice(M1-5-3.center)[][][draw]
\slice(M1-5-4.center)[][draw][]
\slice(M1-4-5.center)[draw,very thick][][]
\slice(M1-6-6.center)[draw,very thick][][draw]
\slice(M1-6-7.center)[draw,very thick][draw][]
\slice(M1-7-5.center)[][draw][draw]
\slice(M1-9-8.center)[draw,very thick][draw][draw]
\end{tikzpicture}
\end{document}
答案3
我的 J Leon V. 代码版本是
\documentclass[tikz,border=14pt]{standalone}
\usepackage{tikz}
\usetikzlibrary{matrix,arrows.meta, positioning,fit,shapes}
\begin{document}
\begin{tikzpicture}[
%Environment config
>={Stealth[inset=0pt,length=6pt]},
%Environment Styles
MyMatrix/.style={
matrix of nodes,
font=\scriptsize,
line width=0.75pt,
column sep=-0.5pt,
row sep=-0.5pt,
text height=18pt,
text width =24pt,
text depth =12pt,
align=center,
nodes={draw=none},
nodes in empty cells
}
]
% Start Drawing the thing
\matrix[
MyMatrix,
column 1/.style={nodes={draw=none},text width =12pt},
row 1/.style={text height =9pt,text depth =6pt},
row 2/.style={text height =9pt,text depth =4pt}
] at (0,0) (M1){%Matrix contents
&&&&&&&&\\
&&&&&&&&\\
&&&&&&&&\\
&&&&&&&&\\
&&&&&&&&\\
&&&&&&&&\\
&&&&&&&&\\
&&&&&&&&\\
&&&&&&&&\\
};
%Draw thick vertical lines
\foreach \x in {1,3,6,8}{
\draw[line width=2pt](M1-1-\x.north east) -- (M1-8-\x.south east);
}
%Draw vertical lines
\foreach \x in {1,2,...,8}{
\draw[line width=0.5pt](M1-2-\x.north east) -- (M1-8-\x.south east);
}
%Draw horizontal lines
\foreach \x in {2,3,5,7,8}{
\draw[line width=0.5pt](M1-\x-1.south east) -- (M1-\x-8.south east);
}
%Label row1
\node at (M1-1-2.0){0};
\node at (M1-1-5.center){1};
\node at (M1-1-7.0){2};
\node at (M1-1-9.center){$k_i$};
\node at (M1-2-2.center){$[0,0]$};
\node at (M1-2-3.center){$[0,1]$};
\node at (M1-2-4.center){$[1,0]$};
\node at (M1-2-5.center){$[1,1]$};
\node at (M1-2-6.center){$[1,2]$};
\node at (M1-2-7.center){$[2,1]$};
\node at (M1-2-8.center){$[2,2]$};
\node at (M1-2-9.center){$[k_i,k_j]$};
%Label col1
\node at (M1-3-1.center){0};
\node at (M1-5-1.north){1};
\node at (M1-7-1.north){2};
\node at (M1-8-1.center){3};
\node at (M1-9-1.center){$m$};
\def\slice(#1)[#2][#3][#4]{
\begin{scope}[shift={(#1)}]
\node[circle,fill,inner sep=1pt](c1) at (30:10pt){};
\node[circle,fill,inner sep=1pt](c2) at (150:10pt){};
\node[circle,fill,inner sep=1pt](c3) at (270:10pt){};
\path[#2](c1.center)--(c2.center);
\path[#3](c2.center)--(c3.center);
\path[#4](c3.center)--(c1.center);
\end{scope}
}
\slice(M1-3-2.center)[][][]
\slice(M1-5-3.center)[][][draw]
\slice(M1-5-4.center)[][draw][]
\slice(M1-4-5.center)[draw,very thick][][]
\slice(M1-6-6.center)[draw,very thick][][draw]
\slice(M1-6-7.center)[draw,very thick][draw][]
\slice(M1-7-5.center)[][draw][draw]
\slice(M1-8-8.center)[draw,very thick][draw][draw]
\end{tikzpicture}
\end{document}
答案4
我的@marmot 代码版本是
\documentclass[border=3.14mm]{standalone}
\usepackage{tikz}
\usetikzlibrary{matrix,calc,fit}
\newcounter{slicenum}
\begin{document}
\def\side{0.5} % Define the size of the triangle's side
\tikzset{slice/.style={path picture={
\stepcounter{slicenum}
\coordinate (O-\theslicenum) at ($(path picture bounding box.south
west)!0.5!(path picture bounding box.north east)$);
\pgfmathsetmacro{\myshift}{2*(1-sqrt(3)/2)*\side}
\coordinate (A-\theslicenum) at
($(O-\theslicenum)+(150:\side)+(0,{\myshift})$);
\coordinate (B-\theslicenum) at ($(O-\theslicenum)+(30:\side)+(0,{\myshift})$);
\coordinate (C-\theslicenum) at ($(O-\theslicenum)+(-90:\side)+(0,{\myshift})$);
\filldraw (A-\theslicenum) circle (1pt) (B-\theslicenum) circle (1pt) (C-\theslicenum) circle (1pt);
\foreach \x/\y/\z in {#1} {\draw[\z] (\x-\theslicenum) -- (\y-\theslicenum);}
}}}
\begin{tikzpicture}
% Start the matrix
\matrix (M) [matrix of nodes, nodes in empty cells, nodes={minimum width=2.4*\side*1cm, minimum height=2*\side*1cm, align=center}]
{
& & & & & & & & \\
& $[0,0]$ & $[0,1]$ & $[1,0]$ & $[1,1]$ & $[1,2]$ & $[2,1]$ & $[2,2]$ & \\
& |[slice=]| & & & & & & & \\
& & & & |[slice={A/B/ultra thick}]| & & & & \\
& & |[slice={B/C/}]| & |[slice={A/C/}]| & & & & & \\
& & & & & |[slice={A/B/ultra thick, B/C/}]| & |[slice={A/B/ultra thick, A/C/}]|
& & & \\
& & & & |[slice={A/C/, B/C/}]| & & & & \\
& & & & & & & |[slice={A/B/ultra thick, A/C/, B/C/}]| & \\
& & & & & & & & \\
};
\path (M-1-2) -- (M-1-3) node[midway]{0} (M-1-4) -- (M-1-6) node[midway]{1} (M-1-7) -- (M-1-8) node[midway]{2} (M-1-1) node[right]{$k_i$};
\path (M-2-1) node[]{$[k_i,k_j]$};
\path (M-3-1) node(0){$0$} (M-4-1) -- (M-5-1) node[midway](1){$1$} (M-6-1) -- (M-7-1) node[midway](2){$2$} (M-8-1) node(3){$3$} ;
% horizontal lines
\path (0) -- (3) node[midway,left=6mm] (m) {$m$};
\foreach \X in {0,...,3}
{\draw[-latex] (m) to[out=90-\X*60,in=180] (\X);}
\newcommand{\DrawHorizontalLineInMatrix}[3][]{
\xdef\Lst{(M-#2-2)}
\foreach \XX in {3,...,8}
{\xdef\Lst{\Lst (M-#2-\XX)}}
\node [fit=\Lst,inner sep=0pt] (fit-#2) {};
\xdef\Lst{(M-#3-2)}
\foreach \XX in {3,...,8}
{\xdef\Lst{\Lst (M-#3-\XX)}}
\node [fit=\Lst,inner sep=0pt] (fit-#3) {};
\draw[#1] ($(fit-#2.south west)!0.5!(fit-#3.north west)$)
-- ($(fit-#2.south east)!0.5!(fit-#3.north east)$);
}
\foreach \X[evaluate=\X as \Y using {int(\X-1)}] in {3,4,6,8,9}
{
\DrawHorizontalLineInMatrix[]{\Y}{\X}
}
% thick vertical lines
\newcommand{\DrawThickVerticalLineInMatrix}[3][]{
\xdef\Lst{(M-1-#2)}
\foreach \XX in {2,...,8}
{\xdef\Lst{\Lst (M-\XX-#2)}}
\node [fit=\Lst,inner sep=0pt] (fit-#2) {};
\xdef\Lst{(M-1-#3)}
\foreach \XX in {2,...,8}
{\xdef\Lst{\Lst (M-\XX-#3)}}
\node [fit=\Lst,inner sep=0pt] (fit-#3) {};
\draw[#1] ($(fit-#2.north east)!0.5!(fit-#3.north west)$)
-- ($(fit-#2.south east)!0.5!(fit-#3.south west)$);
}
\DrawThickVerticalLineInMatrix{1}{2}
\foreach \X[evaluate=\X as \Y using {int(\X-1)}] in {2,4,7,9}
{
\DrawThickVerticalLineInMatrix[ultra thick]{\Y}{\X}
}
% vertical lines
\newcommand{\DrawVerticalLineInMatrix}[3][]{
\xdef\Lst{(M-2-#2)}
\foreach \XX in {2,...,8}
{\xdef\Lst{\Lst (M-\XX-#2)}}
\node [fit=\Lst,inner sep=0pt] (fit-#2) {};
\xdef\Lst{(M-2-#3)}
\foreach \XX in {2,...,8}
{\xdef\Lst{\Lst (M-\XX-#3)}}
\node [fit=\Lst,inner sep=0pt] (fit-#3) {};
\draw[#1] ($(fit-#2.north east)!0.5!(fit-#3.north west)$)
-- ($(fit-#2.south east)!0.5!(fit-#3.south west)$);
}
\foreach \X[evaluate=\X as \Y using {int(\X-1)}] in {3,5,6,8}
{
\DrawVerticalLineInMatrix[]{\Y}{\X}
}
\end{tikzpicture}
\end{document}
结果是