如何更简单地绘制这幅图

如何更简单地绘制这幅图

如何更简单地(用更少的代码,或者更可重用)绘制此图?

在此处输入图片描述

图片点击这里

\documentclass[border=10pt]{standalone}
\usepackage{tikz, tkz-graph}
\usetikzlibrary{arrows,positioning}
\thispagestyle{empty}
\begin{document}
\begin{tikzpicture}

\foreach \p/\w in {0/2, 2/2, 4/1, 5/2, 7/2, 9/1, 10/1} {
    \draw[] (\p, 0) rectangle (\p+\w, 3-\w);
}

\foreach \p/\w in {0/1, 1/2, 3/1, 5/1, 6/2, 8/1} {
    \draw[] (\p, 1) rectangle (\p+\w, 4-\w);
}

\foreach \p/\w in {4/1, 9/2} {
    \draw[] (\p, 2) rectangle (\p+\w, 5-\w);
}

\foreach \p/\w in {0/2, 2/2, 5/2, 7/1, 8/1, 9/2} {
    \draw[] (\p, 3) rectangle (\p+\w, 6-\w);
}

\foreach \p/\w in {0/1, 1/2, 3/2, 5/2, 9/1, 10/1} {
    \draw[] (\p, 4) rectangle (\p+\w, 7-\w);
}

\foreach \p/\w in {1/2, 3/1, 4/1, 5/2, 7/2} {
    \draw[] (\p, 5) rectangle (\p+\w, 8-\w);
}

\foreach \p/\w in {0/2, 2/1, 5/2, 7/1, 8/2, 10/1} {
    \draw[] (\p, 6) rectangle (\p+\w, 9-\w);
}

\foreach \p/\w in {0/1, 1/1, 3/1, 4/2, 6/1, 8/2} {
    \draw[] (\p, 7) rectangle (\p+\w, 10-\w);
}

\foreach \p/\w in {2/1, 4/2, 7/1, 8/1, 9/2} {
    \draw[] (\p, 8) rectangle (\p+\w, 11-\w);
}

\foreach \p/\w in {0/2, 3/2, 5/2, 9/2} {
    \draw[] (\p, 9) rectangle (\p+\w, 12-\w);
}

\end{tikzpicture}
\end{document}

答案1

你可以嵌套两个\foreach循环:

\documentclass[border=10pt,tikz]{standalone}
\begin{document}
\begin{tikzpicture}
\foreach \a/\b in {
 0/{0/2, 2/2, 4/1, 5/2, 7/2, 9/1, 10/1}, 
 1/{0/1, 1/2, 3/1, 5/1, 6/2, 8/1}, 
 2/{1/2, 4/1, 6/2, 9/2}, 
 3/{0/2, 2/2, 5/2, 7/1, 8/1, 9/2}, 
 4/{0/1, 1/2, 3/2, 5/2, 9/1, 10/1},
 5/{1/2, 3/1, 4/1, 5/2, 7/2}, 
 6/{0/2, 2/1, 5/2, 7/1, 8/2, 10/1},
 7/{0/1, 1/1, 3/1, 4/2, 6/1, 8/2},
 8/{2/1, 4/2, 7/1, 8/1, 9/2},
 9/{0/2, 3/2, 5/2, 9/2},
} {
  \foreach \p/\w in \b {
    \draw (\p, \a) rectangle (\p+\w, 3+\a-\w);
  }
}
\end{tikzpicture}
\end{document}

我添加了第 2 行中明显缺失的两个矩形。当然,您可以跳过其他人隐式绘制的那些矩形。


利用计数器的变体(感谢提示!):

\documentclass[border=10pt,tikz]{standalone}
\begin{document}
\begin{tikzpicture}
\foreach \a [count=\i from 0] in {
 {0/2, 2/2, 4/1, 5/2, 7/2, 9/1, 10/1}, 
 {0/1, 1/2, 3/1, 5/1, 6/2, 8/1}, 
 {1/2, 4/1, 6/2, 9/2}, 
 {0/2, 2/2, 5/2, 7/1, 8/1, 9/2}, 
 {0/1, 1/2, 3/2, 5/2, 9/1, 10/1},
 {1/2, 3/1, 4/1, 5/2, 7/2}, 
 {0/2, 2/1, 5/2, 7/1, 8/2, 10/1},
 {0/1, 1/1, 3/1, 4/2, 6/1, 8/2},
 {2/1, 4/2, 7/1, 8/1, 9/2},
 {0/2, 3/2, 5/2, 9/2},
} {
  \foreach \p/\w in \a {
    \draw[fill=yellow] (\p, \i) rectangle (\p+\w, 3+\i-\w);
  }
}
\end{tikzpicture}
\end{document}

另一个使用pics 的变体:

\documentclass[border=10pt,tikz]{standalone}
\begin{document}
\begin{tikzpicture}[
 h/.pic = { \draw (0,0) rectangle ++(2,1); },
 v/.pic = { \draw (0,0) rectangle ++(1,2); }
]
\foreach \a [count=\i from 0] in {
 {0/h, 2/h, 4/v, 5/h, 7/h, 9/v, 10/v}, 
 {0/v, 1/h, 3/v, 5/v, 6/h, 8/v}, 
 {1/h, 4/v, 6/h, 9/h}, 
 {0/h, 2/h, 5/h, 7/v, 8/v, 9/h},
 {0/v, 1/h, 3/h, 5/h, 9/v, 10/v},
 {1/h, 3/v, 4/v, 5/h, 7/h}, 
 {0/h, 2/v, 5/h, 7/v, 8/h, 10/v},
 {0/v, 1/v, 3/, 4/h, 6/v, 8/h},
 {2/v, 4/h, 7/v, 8/v, 9/h},
 {0/h, 3/h, 5/h, 9/h},
} {
  \foreach \p/\w in \a {
    \path pic at (\p, \i) {\w};
  }
}
\end{tikzpicture}
\end{document}

下次尝试,输入s跳过 1 个地方、h放置一个水平矩形和v放置一个垂直矩形。

\documentclass[border=10pt,tikz]{standalone}
\begin{document}
\begin{tikzpicture}[
 h/.pic = { \draw (0,0) rectangle ++(2,1); },
 v/.pic = { \draw (0,0) rectangle ++(1,2); }
]
\newcounter{p}
\foreach \a [count=\i from 0] in {
 {h, h, v, h, h, v, v},
 {v, h, v, s, v, h, v},
 {s, h, s, v, s, h, s, h},
 {h, h, s, h, v, v, h},
 {v, h, h, h, s, s, v, v},
 {s, h, v, v, h, h},
 {h, v, s, s, h, v, h, v},
 {v, v, s, v, h, v, s, h},
 {s, s, v, s, h, s, v, v, h},
 {h, s, h, h, s, s, h},
} {
  \setcounter{p}{0}
  \edef\theh{h}
  \edef\thes{s}
  \foreach \b in \a {
    \ifx\b\thes\else\path pic at (\thep, \i) {\b};\fi
    \ifx\b\theh\addtocounter{p}{2}\else\stepcounter{p}\fi
  }
}
\end{tikzpicture}
\end{document}

相关内容