tikz - позиционирование фотографий как узла

tikz - позиционирование фотографий как узла

Произнесите следующий код:

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

Я хотел бы, чтобы блок изображений вокруг A вел себя так же, как узел D вокруг C. Я нашел несколько похожих вопросов, но все еще не понимаю, как это сделать правильно.

введите описание изображения здесь

решение1

Я думаю, этот вопрос уже поднимался. Хитрость заключается в том, чтобы обернуть picв matrixузел (чтобы было ясно, это матрица 1x1). Это работает, если только вы не хотите поместить picв матрицу, но там вы можете использовать picсаму или хотите использовать матрицу в pic, по крайней мере, на данный момент.

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

введите описание изображения здесь

Один из простых способов работы с большими фотографиями — подсчитать количество записей и сделать их симметричными.

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

введите описание изображения здесь

решение2

Так?

введите описание изображения здесь

Просто измените right=1 of Aна right=0 of A, например:

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

Другая возможность — в tikzpictureопциях (или в tikzset) определить

node distance=0cm

а затем напишите

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

решение3

Обновлено:

С кодом чертежа

\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);
  }
}
  • каждый закрашенный квадрат имеет юго-западный угол в точке (\i*\w, \j*\w)и северо-восточный угол в точке (\i*\w + \w, \j*\w + \w).
  • Для \iзначений от 1до \mydimiи jот 1до \mydimj(включительно) построенный больший прямоугольник имеет юго-западный угол в точке , (1*\w, 1*\w)а северо-восточный угол в точке (\mydimi*\w + \w, \mydimj*\w + \w).
  • Следовательно, центр этого большего прямоугольника находится в (.5*\mydimi*\w + \w, 0.*\mydimj*\w + \w). Чтобы поместить этот центр в начало координат (0, 0), мы сдвигаем координату, используя
shift={(-0.5*\mydimi*\w - \w, -0.5*\mydimj*\w - \w)}

Полный пример. Обратите внимание, что я немного упростил определение pic.

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

Старый ответ:

В отличие от узла, пик имеет фиксированный якорь. Этот якорь -(0, 0) внутри его команд рисования. См. руководство pgf, раздел 18.2, параграфМестоположение фотографии.

В вашем определении пиктограммы (0, 0)находится в юго-западном углу заполненного квадрата. Поэтому tikz помещает каждый юго-западный угол пиктограммы mypicв такие позиции, как left=1 of A.

Внутри определения pic перемещение (0, 0)в центр заполненного квадрата решает вашу проблему. Здесь я использую shiftопцию смещения. Лучше настроить координаты, используемые в командах рисования mypic, чтобы сохранить его центр в начале координат.

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

Связанный контент