![如何绘制多边形网格,而无需明确指定多边形网格的位置?](https://linux22.com/image/456938/%E5%A6%82%E4%BD%95%E7%BB%98%E5%88%B6%E5%A4%9A%E8%BE%B9%E5%BD%A2%E7%BD%91%E6%A0%BC%EF%BC%8C%E8%80%8C%E6%97%A0%E9%9C%80%E6%98%8E%E7%A1%AE%E6%8C%87%E5%AE%9A%E5%A4%9A%E8%BE%B9%E5%BD%A2%E7%BD%91%E6%A0%BC%E7%9A%84%E4%BD%8D%E7%BD%AE%EF%BC%9F.png)
现在我知道了如何使用 PGF/TikZ 创建网格每个小网格都明确地定位在元网格中,并且元网格的右边距很粗糙,我想知道:当元网格每行内的项目数是固定的并且是预先知道的(比如说,每行 7 个项目)时,有没有更简单的方法可以做到这一点?
我希望能够列出多边形网格而不指定它们在元网格中的位置,并让 PGF/TikZ 自动放置它们,以便首先从左到右填充元网格的第一行(顶部),然后是第二行,依此类推,如下图所示:
答案1
由于原始答案没有提供自动定位解决方案,因此将其移至这里按照 OP 的建议。
第二个版本坚持使用pics
每个特定多边形,但现在使用循环放置foreach
。这样,我们只需要修复图片列表和所需结果的宽度。
为了简化使用,\placepics
我们定义了一个新命令。它有一个可选参数,即在同一行上放置的图片数量(默认为 7),以及一个强制参数,即要绘制的多边形列表。
如果我们手动计算每个命令的正确性,那么可以将多个placepics
命令组合成同一个命令。tikzpicture
shift
scope
\documentclass[border=2mm,tikz]{standalone}
\newcommand{\grid}{\foreach \i in {0,1,2} \foreach \j in {0,1,2}
\fill (\i,\j) circle (1pt);}
\tikzset{
line join=round,
polygon/.style={thick, blue},
empty/.pic={
\grid
},
one/.pic={
\grid
\draw[polygon] (0,0)--(2,2)|-cycle;
},
two/.pic={
\grid
\draw[polygon] (0,0)-|(2,1)--(1,2)--(1,1)--cycle;
},
three/.pic={
\grid
\draw[polygon] (0,0)-|(2,1)--(0,2)--(1,1)--cycle;
},
four/.pic={
\grid
\draw[polygon] (0,0)-|(2,1)-|(1,2)--cycle;
},
five/.pic={
\grid
\draw[polygon] (0,0) rectangle ++(2,1);
},
six/.pic={
\grid
\draw[polygon] (0,0)--(2,0)--(1,2)--(0,2)--(1,1)--cycle;
},
seven/.pic={
\grid
\draw[polygon] (0,0)--(2,0)--(1,2)--(0,1)--(1,1)--cycle;
},
eight/.pic={
\grid
\draw[polygon] (0,0)--(2,0)--(1,2)--cycle;
},
nine/.pic={
\grid
\draw[polygon] (0,0)--(1,0)--(2,1)|-(1,2)--(1,1)--cycle;
},
ten/.pic={
\grid
\draw[polygon] (0,0)--(1,0)--(2,1)--(2,2)--(1,1)--(1,2)--cycle;
},
}
\newcommand{\placepics}[2][7]{
\foreach \i [count=\ni from 0,
evaluate=\ni as \col using {int(mod(\ni,#1))},
evaluate=\ni as \row using {int(\ni/#1)}] in {#2}{
\pic at (3*\col,-3*\row) {\i};}
}
\begin{document}
\begin{tikzpicture}
\placepics{one, two, three, four, five, six, seven, eight, nine, ten, one, two, empty, four, six, nine, ten}
\begin{scope}[yshift=-9cm]
\placepics[5]{one, two, three, four, five, six, seven, eight, nine, ten, one, two, empty, four, six, nine, ten}
\end{scope}
\end{tikzpicture}
\end{document}
答案2
我正在使用的代码回答由 Juan Castaño 针对相关问题提出的观点作为起点。
改编
- 定义的环境
polygongrid
会自动设置范围的位置 - 使用计数器
pgx
和pgy
位置 - 用于
\polygongridsPerLine
定义一行中应有多少个多边形 - 定义样式
polygon
以减少冗余代码
结果
代码
\documentclass[tikz,border=2mm]{standalone}
\usepackage{etoolbox}
% grid
\newcommand{\mygrid}{
\foreach\i in {0,...,2} \foreach\j in {0,...,2}
\fill (\i,\j) circle (1pt);
}
\newcommand{\polygongridsPerLine}{3}
\newcounter{pgx}
\newcounter{pgy}
\newenvironment{polygongrid}{
\begin{scope}[shift={(3*\value{pgx}, -3*\value{pgy})}]
}{
\mygrid
\end{scope}
\stepcounter{pgx}
\ifnumgreater{\value{pgx}}{\polygongridsPerLine-1}{
\stepcounter{pgy}
\setcounter{pgx}{0}
}{}
}
\begin{document}
\begin{tikzpicture}
[% options
line join=round,
polygon/.style={thick,blue},
]
% first polygon
\begin{polygongrid}
\draw[polygon] (0,0) -- (2,2) |- cycle;
\end{polygongrid}
% second polygon
\begin{polygongrid}
\draw[polygon] (0,0) -- (1,1) -- (1,2) -- (2,1) |- cycle;
\end{polygongrid}
% third polygon
\begin{polygongrid}
\draw[polygon] (0,0) -- (1,1) -- (0,2) -- (2,1) |- cycle;
\end{polygongrid}
% fourth polygon
\begin{polygongrid}
\draw[polygon] (0,0) -- (1,1) -- (0,2) -- (1,2) -- (2,0) -- cycle;
\end{polygongrid}
\end{tikzpicture}
\end{document}
答案3
您可以将每张图片创建为\hbox
并将这些\hbox
图片放入段落模式(由 开始\noindent
)。如果您正确设置\hsize
、\spaceskip
和\baselineskip
,那么您将获得包含图片且等于所需网格的段落。
下面的示例使用\printpolyg
创建单个多边形的宏。其参数中的数字对应于多边形可能的边的标签:
1 2 3
4 5 6
7 8 9
整个示例在这里。您不需要 TikZ,只需\pdfliteral
使用原始引擎。即,您可以通过pdftex
或\pdfliteral
为另一个使用的引擎定义来尝试此示例。
\def\sdef#1{\expandafter\def\csname #1\endcsname}
\def\cs#1{\csname #1\endcsname}
\sdef{ppol:1}{0 20} \sdef{ppol:2}{10 20} \sdef{ppol:3}{20 20}
\sdef{ppol:4}{0 10} \sdef{ppol:5}{10 10} \sdef{ppol:6}{20 10}
\sdef{ppol:7}{0 0} \sdef{ppol:8}{10 0} \sdef{ppol:9}{20 0}
\def\printpolyg#1{%
\hbox to20bp{\vbox to20bp{}\pdfliteral{q 1 w \printpolygA#1; Q}\hss}%
}
\def\printpolygA#1{\cs{ppol:#1} m \printpolygB}
\def\printpolygB#1{\ifx;#1h S\else \cs{ppol:#1} l \expandafter\printpolygB\fi}
\bgroup
\rightskip=0pt plus1fil
\spaceskip=10bp \hsize=200bp
\baselineskip=30bp
\noindent
\printpolyg{397}
\printpolyg{26975}
\printpolyg{16975}
\printpolyg{25697}
\printpolyg{4697}
\printpolyg{12975}
\printpolyg{29754}
\printpolyg{297}
\printpolyg{236875}
\printpolyg{253687}
\printpolyg{126875}
\printpolyg{268754}
\printpolyg{2687}
\printpolyg{268745}
\printpolyg{168754}
\printpolyg{168745}
\printpolyg{356874}
\printpolyg{356872}
\printpolyg{256874}
\printpolyg{2387}
\printpolyg{238745}
\printpolyg{387}
\printpolyg{2684}
\par
\egroup
结果: