Произнесите следующий код:
\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
решение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.