tikz: posicionar fotografías como un nodo

tikz: posicionar fotografías como un nodo

Diga el siguiente código:

\documentclass[tikz,border=2mm]{standalone}
\usetikzlibrary{positioning}
\tikzset{
        % colmat
pics/colmat/.style={code={
        \tikzset{colmat/.cd,#1}  \def\pv##1{\pgfkeysvalueof{/tikz/colmat/##1}}%
        \edef\m{\pv{m}}%
        \edef\w{2}%
        \foreach \row [count=\j] in \m  {
            \foreach \r/\g/\b [count=\i] in \row {
                \fill[fill={rgb,255:red,\r; green,\g; blue,\b}] (\i*\w,\j*\w) rectangle ++(\w,\w);
            }%foreach
        }%foreach
}},colmat/.cd,m/.initial={{255/0/0}},/tikz/.cd,
    %
}
\begin{document}
    \begin{tikzpicture}
    \tikzset{
        box/.style={draw,minimum width=1cm,minimum height=1cm}
    }
    \def\clst{
        {200/10/10},
        {10/10/200},
        {10/200/200}%
    }
    \node[box] (A) at (0,0) {A};
    \foreach \pos in {left,right,above,below} {
        \node[\pos=1 of A,matrix] (B-\pos) {\pic{colmat={m=\clst}};\\};
    }

    \node[left=6 of A,box] (C) at (0,0) {C};
    \foreach \pos in {left,right,above,below} {
        \node[\pos=1 of C,box] (D) {D};
    }
    \end{tikzpicture}
\end{document}

Deseo que el bloque de imágenes alrededor de A se comporte igual que el nodo D alrededor de C. Encontré algunas preguntas similares pero todavía no descubro la forma correcta de hacerlo.

ingrese la descripción de la imagen aquí

Respuesta1

Creo que esta pregunta surgió antes. El truco consiste en envolver el picen un matrixnodo (para ser claros, esta es una matriz de 1x1). Esto funciona a menos que quieras poner el picen una matriz, pero allí puedes usarlo en picsí mismo, o quieres usar una matriz en el pic, al menos a partir de ahora.

\documentclass[tikz,border=2mm]{standalone}
\usetikzlibrary{positioning}
\tikzset{
pics/mypic/.style={code={
        \tikzset{mypic/.cd,#1}  \def\pv##1{\pgfkeysvalueof{/tikz/mypic/##1}}%
        \edef\m{\pv{m}}%
        \foreach \row [count=\j] in \m  {
            \foreach \r/\g/\b [count=\i] in \row {
                \fill[fill={rgb,255:red,\r; green,\g; blue,\b}] (\i-1,\j-1) rectangle ++(1,1);
            }%foreach
        }%foreach
    }},mypic/.cd,m/.initial={{255/0/0}},/tikz/.cd,
%
}
\begin{document}
    \begin{tikzpicture}
    \tikzset{
        box/.style={draw,minimum width=1cm,minimum height=1cm}
    }
    \def\clst{
{31/18/12}%
    }
  \node[box] (A) at (0,0) {A};
  \foreach \pos in {left,right,above,below} {
    \node[\pos=1 of A,matrix] (B-\pos) {\pic{mypic={m=\clst}};\\};
  }

\node[left=6 of A,box] (C) at (0,0) {C};
\foreach \pos in {left,right,above,below} {
    \node[\pos=1 of C,box] (D) {D};
}
    \end{tikzpicture}
\end{document}

ingrese la descripción de la imagen aquí

Una forma sencilla de lidiar con fotografías más grandes es contar las entradas y hacerlas simétricas.

\documentclass[tikz,border=2mm]{standalone}
\usetikzlibrary{positioning}
\tikzset{
        % colmat
pics/colmat/.style={code={
        \tikzset{colmat/.cd,#1}  
        \def\pv##1{\pgfkeysvalueof{/tikz/colmat/##1}}%
        \edef\m{\pv{m}}%
        \foreach \row [count=\j] in \m  {\xdef\mydimj{\j}
            \foreach \r/\g/\b [count=\i] in \row {\xdef\mydimi{\i}}}
        \typeout{\m,\mydimi,\mydimj}
        \edef\w{2}%
        \foreach \row [count=\j] in \m  {
            \foreach \r/\g/\b [count=\i] in \row {
                \fill[fill={rgb,255:red,\r; green,\g; blue,\b}]
                 (\i*\w-\mydimi/2,\j*\w-\mydimj/2) rectangle ++(\w,\w);
            }%foreach
        }%foreach
}},colmat/.cd,m/.initial={{255/0/0}},/tikz/.cd,
    %
}
\begin{document}
    \begin{tikzpicture}
    \tikzset{
        box/.style={draw,minimum width=1cm,minimum height=1cm}
    }
    \def\clst{
        {200/10/10},
        {10/10/200},
        {10/200/200}%
    }
    \node[box] (A) at (0,0) {A};
    \foreach \pos in {left,right,above,below} {
        \node[\pos=1 of A,matrix] (B-\pos) {\pic{colmat={m=\clst}};\\};
    }

    \node[left=6 of A,box] (C) at (0,0) {C};
    \foreach \pos in {left,right,above,below} {
        \node[\pos=1 of C,box] (D) {D};
    }
    \end{tikzpicture}
\end{document}

ingrese la descripción de la imagen aquí

Respuesta2

¿Como esto?

ingrese la descripción de la imagen aquí

Simplemente cambie right=1 of Aa right=0 of A, es decir:

\pic[right=0 of A] (B) {mypic={m=\clst}};

Otra posibilidad está en tikzpictureopciones (o en tikzset) definir

node distance=0cm

y luego escribir

\pic[right=of A] (B) {mypic={m=\clst}};

Respuesta3

Actualizado:

Con el código de dibujo

\foreach \row [count=\j] in \m {
  \foreach \r/\g/\b [count=\i] in \row {
    \fill[fill={rgb,255:red,\r; green,\g; blue,\b}]
      (\i * \w, \j * \w) rectangle ++(\w,\w);
  }
}
  • cada cuadrado lleno tiene su esquina suroeste en (\i*\w, \j*\w)y la esquina noreste en (\i*\w + \w, \j*\w + \w).
  • Para \iel rango desde 1hasta \mydimiy jdesde 1hasta \mydimj(inclusive), el rectángulo más grande construido tiene su esquina suroeste en (1*\w, 1*\w)y la esquina noreste en (\mydimi*\w + \w, \mydimj*\w + \w).
  • Por lo tanto, el centro de ese rectángulo más grande está en (.5*\mydimi*\w + \w, 0.*\mydimj*\w + \w). Para poner ese centro en el origen (0, 0), desplazamos la coordenada usando
shift={(-0.5*\mydimi*\w - \w, -0.5*\mydimj*\w - \w)}

Un ejemplo completo, tenga en cuenta que he simplificado ligeramente la picdefinición.

\documentclass[tikz,border=2mm]{standalone}
\usetikzlibrary{positioning}

\makeatletter
\tikzset{
  % colmat
  pics/colmat/.style={code={
    \tikzset{colmat/#1}
    \foreach \row [count=\j] in \pic@colmat@m {
      \xdef\mydimj{\j}
      \foreach \r/\g/\b [count=\i] in \row {\xdef\mydimi{\i}}
    }
    \edef\w{2}%
    \foreach \row [count=\j] in \pic@colmat@m {
      \foreach \r/\g/\b [count=\i] in \row {
        \fill[fill={rgb,255:red,\r; green,\g; blue,\b},
         shift={(-0.5*\mydimi*\w - \w, -0.5*\mydimj*\w - \w)}]
          (\i * \w, \j * \w) rectangle ++(\w,\w);
      }%foreach
    }%foreach
  }},
  colmat/m/.estore in=\pic@colmat@m,
  colmat/m/.initial={{255/0/0}}
}
\makeatother

\begin{document}
\begin{tikzpicture}
  \tikzset{
    box/.style={draw,minimum width=1cm,minimum height=1cm}
  }
  \def\clst{
    {200/10/10},
    {10/10/200},
    {10/200/200}%
  }
  \node[box] (A) at (0,0) {A};
  \foreach \pos in {left,right,above,below} {
    \pic[\pos=2 of A] (B-\pos) {colmat={m=\clst}};
  }

  \node[left=6 of A,box] (C) at (0,0) {C};
  \foreach \pos in {left,right,above,below} {
    \node[\pos=1 of C,box] (D-\pos) {D};
  }
\end{tikzpicture}
\end{document}

Antigua respuesta:

A diferencia del nodo, una imagen tiene un ancla fija. Esa ancla es la(0, 0) interior de sus comandos de dibujo. Ver manual pgf, sec. 18.2, párrafoLa ubicación de una foto..

En la definición de tu foto, (0, 0)está en la esquina suroeste del cuadrado lleno. Por lo tanto, tikz coloca cada esquina suroeste de la imagen mypicen posiciones como left=1 of A.

Dentro de la definición de imagen, moverse (0, 0)al centro del cuadrado relleno resuelve su problema. Aquí utilizo una shiftopción para compensar. Es mejor ajustar las coordenadas utilizadas en los comandos de dibujo de mypicpara mantener su centro en el origen.

% before
\fill[fill={...},                   ] (\i-1,\j-1) rectangle ++(1,1);
% after
\fill[fill={...}, shift={(-.5, -.5)}] (\i-1,\j-1) rectangle ++(1,1);
% for updated example in question, a shift of (0, -3) is required.

información relacionada