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 周围的图片块的行为与 C 周围的节点 D 的行为相同。我发现了一些类似的问题,但仍然没有找到正确的方法。

在此处输入图片描述

答案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 Aright=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\mydimij范围从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}

旧答案:

与节点不同,pic 具有固定锚点。该锚点位于(0, 0)其绘图命令内部。请参阅 pgf 手册第 18.2 节第图片位置

在您的 pic 定义中,(0, 0)位于填充正方形的西南角。因此,tikz 将 pic 的每个西南角放置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.

相关内容