给定多边形网格,绘制多边形的边界

给定多边形网格,绘制多边形的边界

我有一些代码可以根据用户输入的二进制矩阵自动绘制多边形网格(由边到边连接的正方形构成的形状)。二进制矩阵用于多边形的边界矩形,其中 1 表示多边形的填充正方形,而 0 表示空正方形(即不属于多边形的正方形)。我想用比网格线更粗的线绘制多边形的边界。理想情况下,我希望网格线和边界线的线粗度都是可调的(网格线宽度已经是可调的)。请参阅下面的代码和相应的图。

\documentclass{article}
\usepackage{tikz}
\usepackage{xcolor}

\newcommand{\drawPolyomino}[3]{
    \begin{tikzpicture}[scale=#2]

        % Draw the squares
        \foreach[count=\jR from 0] \row in {#1} {
            \pgfmathtruncatemacro\j{abs(\jR - 3)}
            \foreach[count=\i from 0] \cell in \row {
                \ifnum\cell=1
                    \draw[#3] (\i, \j) rectangle ++(1,1);
                \fi
            }
        }
    \end{tikzpicture}
}

\begin{document}

\begin{figure}
\centering
\drawPolyomino{{0,1,0,0,0},{1,1,1,1,0},{0,0,1,1,1},{0,0,0,1,0}}{1.0}{thin} 
% Input the polyomino, followed by arguments for scale and line width respectively.
\caption{A polyomino constructed from an input binary matrix.}
\end{figure}

\end{document}

多格骨牌网格

答案1

存储您提供的矩阵使得稍后在循环中检索它们变得更加容易。(现在它基本上是一个二维数组。)

这样,就可以检查每个绘制的矩形周围是否有另一个矩形,如果没有(或者数组基本上超出范围→检查\relax),则绘制边框段。(这也意味着存储该矩阵,即使用键store matrix,应该始终在不使用其他键的范围内进行store matrix。否则\relax作弊将不再有效。)

这不会构造封闭路径。将整个构造放在一条路径上使我们能够填充/阴影整个形状,而无需实际使用轮廓。这也有助于将 s 放在edge形状的顶部。

这使用与在另一个答案中它可能对行和列的解释与您不同 (?)。在某个时候我有点困惑,但polyomino/picture其密钥yscale=-1似乎已经解决了这个问题。

代码

\documentclass[tikz]{standalone}
\tikzset{
  polyomino/rect/.style={thin},
  polyomino/border/.style={very thick, line cap=rect},
  polyomino/picture/.style={yscale=-1},
  polyomino/.code=\pgfqkeys{/tikz/polyomino}{#1},
  store matrix/.style={
    /utils/exec=\def\listrow{0},
    /utils/rows/.style={
      /utils/exec=\def\listcol{0}%
                  \edef\listrow{\the\numexpr\listrow+1\relax},
      /utils/cols/.estyle={
        /utils/exec=\edef\noexpand\listcol{\noexpand\the\numexpr\noexpand\listcol+1\relax},
        /tikz/matrix/storage \listrow-\noexpand\listcol/.initial={####1}
      },
      /utils/cols/.list={##1},
    },
    /utils/rows/.list={#1}
  },
  matrix check/.code args={#1:#2=#3}{%
    \pgfkeysgetvalue{/tikz/matrix/storage \pgfinteval{#1}-\pgfinteval{#2}}{#3}%
    \ifx#3\relax \def#3{0}\fi},
}

\newcommand{\drawPolyomino}[2][]{
  \begin{tikzpicture}[store matrix={#2},polyomino/picture,polyomino={#1}]
    % Draw the squares
  \draw[polyomino/rect] foreach \col in {1,...,\listcol}{
    foreach \row in {1,...,\listrow}{
    [matrix check/.list={\row:\col=\cell,
                         \row:\col-1=\cellPrev,
                         \row:\col+1=\cellNext,
                         \row+1:\col=\cellAbove,
                         \row-1:\col=\cellBelow}]
      \ifnum\cell=1
                              (\col  , \row  ) rectangle +(1,1)
          \ifnum\cellPrev=0   (\col  , \row  ) edge[polyomino/border] +(up:1)   \fi
          \ifnum\cellAbove=0  (\col  , \row+1) edge[polyomino/border] +(right:1)\fi
          \ifnum\cellBelow=0  (\col  , \row  ) edge[polyomino/border] +(right:1)\fi
          \ifnum\cellNext=0   (\col+1, \row  ) edge[polyomino/border] +(up:1)   \fi
      \fi
    }};
  \end{tikzpicture}}

\begin{document}
\drawPolyomino{
  {0,1,0,0,0},
  {1,1,1,1,0},
  {0,0,1,1,1},
  {0,0,0,1,0}
}
\drawPolyomino[
  rect/.append style={draw=none, top color=green!50, bottom color=blue!50},
  border/.append style={ultra thick, draw=red, dash=on 3mm off 4mm phase 0mm}]{
  {0,1,0,0,0},
  {1,1,1,1,0},
  {0,0,1,1,1},
  {0,0,0,1,0}
}
\end{document}

输出

在此处输入图片描述 在此处输入图片描述

答案2

您可以绘制两次并使用 [fill=white] 擦除内部的粗边框。请注意,线条以边缘为中心,因此填充时您将损失近一半的外部厚度。

\documentclass{article}
\usepackage{xcolor}
\usepackage{tikz}

\newcommand{\drawPolyomino}[2]{% #1=binary array, #2=scale
    \begin{tikzpicture}[scale=#2]

        % Draw the squares
        \foreach[count=\jR from 0] \row in {#1} {
            \pgfmathtruncatemacro\j{abs(\jR - 3)}
            \foreach[count=\i from 0] \cell in \row {
                \ifnum\cell=1
                    \draw[very thick] (\i, \j) rectangle ++(1,1);
                \fi
            }
        }
        \foreach[count=\jR from 0] \row in {#1} {
            \pgfmathtruncatemacro\j{abs(\jR - 3)}
            \foreach[count=\i from 0] \cell in \row {
                \ifnum\cell=1
                    \draw[thin, fill=white] (\i, \j) rectangle ++(1,1);
                \fi
            }
        }
    \end{tikzpicture}%
}

\begin{document}

\begin{figure}
\centering
\drawPolyomino{{0,1,0,0,0},{1,1,1,1,0},{0,0,1,1,1},{0,0,0,1,0}}{1.0}
% Input the polyomino, followed by arguments for scale
\caption{A polyomino constructed from an input binary matrix.}
\end{figure}

\end{document}

演示

相关内容