tikz - Bilder positionieren wie ein Knoten

tikz - Bilder positionieren wie ein Knoten

Sagen Sie den folgenden Code:

\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}

Ich möchte, dass sich der Bildblock um A genauso verhält wie Knoten D um C. Ich habe einige ähnliche Fragen gefunden, weiß aber noch nicht, wie es richtig geht.

Bildbeschreibung hier eingeben

Antwort1

picIch glaube, diese Frage wurde schon einmal gestellt. Der Trick besteht darin, die in einen Knoten einzuschließen matrix(um es klarzustellen, dies ist eine 1x1-Matrix). Dies funktioniert, sofern Sie die nicht picin eine Matrix einfügen möchten, aber dort können Sie die selbst verwenden picoder eine Matrix in der verwenden möchten pic, zumindest im Moment.

\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}

Bildbeschreibung hier eingeben

Eine einfache Möglichkeit, mit größeren Bildern umzugehen, besteht darin, die Einträge zu zählen und sie symmetrisch zu machen.

\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}

Bildbeschreibung hier eingeben

Antwort2

So was?

Bildbeschreibung hier eingeben

Ändern Sie es einfach right=1 of Ain right=0 of A, also:

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

Eine weitere Möglichkeit ist in tikzpictureden Optionen (oder in tikzset) zu definieren

node distance=0cm

und dann schreiben

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

Antwort3

Aktualisiert:

Mit dem Zeichnungscode

\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);
  }
}
  • Jedes ausgefüllte Quadrat hat seine südwestliche Ecke bei (\i*\w, \j*\w)und seine nordöstliche Ecke bei (\i*\w + \w, \j*\w + \w).
  • Für \iden Bereich von 1bis \mydimiund jden Bereich von 1bis \mydimj(einschließlich) hat das konstruierte größere Rechteck seine südwestliche Ecke bei (1*\w, 1*\w)und seine nordöstliche Ecke bei (\mydimi*\w + \w, \mydimj*\w + \w).
  • Daher liegt der Mittelpunkt des größeren Rechtecks ​​bei (.5*\mydimi*\w + \w, 0.*\mydimj*\w + \w). Um diesen Mittelpunkt auf den Ursprung zu setzen (0, 0), verschieben wir die Koordinate mit
shift={(-0.5*\mydimi*\w - \w, -0.5*\mydimj*\w - \w)}

Ein vollständiges Beispiel. Beachten Sie, dass ich die picDefinition etwas vereinfacht habe.

\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}

Alte Antwort:

Im Gegensatz zu Node hat ein Pic einen festen Anker. Dieser Anker befindet sich (0, 0)innerhalb seiner Zeichenbefehle. Siehe PGF-Handbuch, Abschnitt 18.2, AbsatzDer Standort eines Bildes.

In Ihrer Bilddefinition (0, 0)befindet sich die südwestliche Ecke des ausgefüllten Quadrats. Daher platziert Tikz jede südwestliche Ecke des Bilds mypican Positionen wie left=1 of A.

Innerhalb der Definition von pic (0, 0)löst das Verschieben in die Mitte des ausgefüllten Quadrats Ihr Problem. Hier verwende ich eine shiftOption zum Versetzen. Es ist besser, die in den Zeichenbefehlen von verwendeten Koordinaten anzupassen mypic, um die Mitte am Ursprung zu behalten.

% 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.

verwandte Informationen