Controlando o desenho da borda do nó em uma matriz tikz

Controlando o desenho da borda do nó em uma matriz tikz

Estou tentando desenhar uma grade de nós de tamanho específico. Além disso, estou abrindo buracos nesta grade tentando deixar as células e, em particular, suas bordas internas brancas. Para tornar isso concreto, considere o seguinte:

\documentclass[tikz]{standalone}
\usetikzlibrary{fit, matrix}

\begin{document}

\begin{tikzpicture}
\matrix [
    matrix of nodes,
    inner sep=0pt,                % no padding around the cells
    row sep=-\pgflinewidth,
    column sep=-\pgflinewidth,
    nodes={
        rectangle, draw=black, minimum height=11mm, minimum width=11mm,
        anchor=center, inner sep=0pt, outer sep=0pt
    },
    nodes in empty cells,
    name=table
] {
& & & & \\
& & |[white]| & & \\
& |[white]| & |[white]| & & \\
& & |[white]| & |[white]| & \\
& & & & \\
};

\end{tikzpicture}
\end{document}

Em geral, suponha que temos “ilhas” arbitrárias de células brancas na matriz; neste caso, temos apenas uma ilha (de tamanho 5), o que significa que as células brancas abrangem um subgráfico conectado da grade hospedeira, mas pode haver várias dessas ilhas.

Queremos que as fronteiras internas não sejam traçadas, mas as fronteiras externas devem permanecer intactas. Do jeito que estão, as bordas externas são desenhadas apenas com as bordas aparecendo, fazendo com que pareçam acinzentadas. Veja abaixo a saída não desejada:

insira a descrição da imagem aqui

Como podemos controlar melhor como os nós e suas arestas são desenhados? Eu também vejoessa questãoo que pode me ajudar a desenhá-los de uma maneira mais agradável: estou fazendo isso programaticamente, então parece bom poder especificar as coordenadas da ilha em forma de lista.

Responder1

Em vez de desenhar uma borda branca, simplesmente não desenhe nenhuma borda. Dessa forma, você não obterá linhas cinzas (que na verdade são brancas sobre pretas).

No código abaixo, matrix of grid nodes = <rows> x <columns>configura uma matriz TikZ com os números especificados de linhas e colunas onde cada célula contém apenas \node{};. Por padrão, cada um desses nós será um arquivo grid node.

Usando as island(s)chaves, as células onde a grid island nodedeve ser usado podem ser especificadas. A grid island nodeé simplesmente path only(ou seja, draw = none, fill = node, …), mas pode ser qualquer coisa, talvez apenas uma coordenada (mas isso exigiria que você fizesse a row sepou , caso column sepcontrário between origins, você obteria uma linha ou coluna de tamanho zero se uma linha ou coluna inteira contivesse ilhas.

Em vez disso, \node{};poderíamos colocar \tikzgridnodeem cada célula o que \node[grid node]{};normalmente acontece, mas simplesmente não podemos colocar nada em uma célula se for uma ilha (nem mesmo uma coordenada).

Código

\documentclass[tikz]{standalone}
\makeatletter
\newcommand*\utilrepeat[2]{%
  \ifnum#1=1 \expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi
    {#2}{#2\expandafter\utilrepeat\expandafter{\the\numexpr#1-1\relax}{#2}}}
\makeatother
\tikzset{
  grid node/.style={
    shape=rectangle, draw=black, fill=lightgray, anchor=center,
    minimum size=+11mm, inner sep=+0pt, outer sep=+0pt},
%  grid island node/.style={shape=coordinate}, % no node, just a coordinate
  grid island node/.style=path only,         % node but no output
  tight matrices/.style={every outer matrix/.append style={inner sep=+0pt}},
  matrix of grid nodes/.style args={#1x#2}{
    matrix, tight matrices, nodes=grid node,
    row sep=+-\pgflinewidth, column sep=+-\pgflinewidth,
    execute at empty cell=\node{};,
    node contents=%
      \utilrepeat{#1}{%
        \utilrepeat{\pgfinteval{#2-1}}{\pgfmatrixnextcell}\pgfmatrixendrow}},
  island/.style args={#1-#2}{
    row #1 column #2/.append style={nodes=grid island node}},
  islands/.style={island/.list={#1}}}
\begin{document}
\tikz\node[matrix of grid nodes = 5 x 5, islands = {2-3, 3-2, 3-3, 4-3, 4-4}];
\end{document}

Saída

insira a descrição da imagem aqui

Responder2

Uma solução simples, talvez um pouco grosseira, definindo o estilo das células sem bordas:

\documentclass[border=6pt]{standalone}
\usepackage{tikz}
\usetikzlibrary{matrix}

\begin{document}
    \begin{tikzpicture}
\newcommand\nx{|[draw=none]|}
\matrix (m) [matrix of nodes,
             row sep=-\pgflinewidth,
             column sep=-\pgflinewidth,
             nodes = {draw,
                      minimum size=11mm, anchor=center,
                      inner sep=0pt, outer sep=0pt}
             ] 
{
a & b & c & d & e\\
f & g & \nx
        h & i & j\\
k & \nx l 
      & \nx m
          & n & o\\
p & q & \nx r 
          &  \nx s 
              & t\\
u & v & w & x & y\\
};
    \end{tikzpicture}
\end{document}

insira a descrição da imagem aqui

Responder3

O comando \islandsabaixo leva 3 argumentos. O primeiro argumento é o número de linhas, o segundo argumento é o número de colunas e o terceiro argumento é uma lista de células no formato (<row>,<column>).

Este comando desenha linhas horizontais e verticais. Uma linha horizontal não é desenhada se a célula acima e abaixo estiver contida na lista do terceiro argumento. Da mesma forma para linhas verticais.

insira a descrição da imagem aqui

\documentclass[border=6pt]{standalone}
\usepackage{tikz}
\usetikzlibrary{matrix}
\ExplSyntaxOn
\cs_generate_variant:Nn \str_if_in:nnT { neT }
\bool_new:N \l__islands_bool
\NewDocumentCommand { \islands } { mmm }
% #1 number of rows
% #2 number of columns
% #3 list of cells in the form (<row>,<column>)
  {
    \begin { scope }
      [
        shift = { ( mymatrix-1-1.north~west ) } ,
        x = 11 mm ,
        y = -11 mm
      ]
      \int_step_inline:nnn { 0 } {#1}
        {
          \int_step_inline:nn {#2}
            {
              \bool_set_true:N \l__islands_bool
              \str_if_in:neT {#3} { ( ##1 , ####1 ) }
                {
                  \str_if_in:neT {#3} { ( \int_eval:n { ##1 + 1 } , ####1 ) }
                    {
                      \bool_set_false:N \l__islands_bool
                    }
                }
              \bool_if:NT \l__islands_bool
                { \draw ( { ####1 - 1 } , ##1 ) --++ ( 1 , 0 ) ; }
            }
        }
      \int_step_inline:nnn { 0 } {#2}
        {
          \int_step_inline:nn {#1}
            {
              \bool_set_true:N \l__islands_bool
              \str_if_in:neT {#3} { ( ####1 , ##1 ) }
                {
                  \str_if_in:neT {#3} { ( ####1 , \int_eval:n { ##1 + 1 } ) }
                    {
                      \bool_set_false:N \l__islands_bool
                    }
                }
              \bool_if:NT \l__islands_bool
                { \draw ( ##1 , { ####1 - 1 } ) --++ ( 0 , 1 ) ; }
            }
        }
    \end { scope }
  }
\ExplSyntaxOff
\begin{document}
\begin{tikzpicture}
\matrix (mymatrix) [
  matrix of nodes,
  inner sep=0pt,
  row sep=-\pgflinewidth,
  column sep=-\pgflinewidth,
  nodes={
    rectangle,
    minimum height=11mm,
    minimum width=11mm,
    anchor=center,
    inner sep=0pt,
    outer sep=0pt
  }
]
  {
    a & b & c & d & e\\
    f & g & h & i & j\\
    k & l & m & n & o\\
    p & q & r & s & t\\
    u & v & w & x & y\\
  };
\islands{5}{5}{(2,3),(3,2),(3,3),(4,3),(4,4)}
\end{tikzpicture}
\end{document}

informação relacionada