以下のコードを言います:
\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 の周りの pic ブロックが 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}
大きな画像を扱う簡単な方法の 1 つは、エントリを数えて対称にすることです。
\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}
古い回答:
ノードとは異なり、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.