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.
Antwort1
pic
Ich 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 pic
in eine Matrix einfügen möchten, aber dort können Sie die selbst verwenden pic
oder 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}
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}
Antwort2
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
\i
den Bereich von1
bis\mydimi
undj
den Bereich von1
bis\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 pic
Definition 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 mypic
an 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 shift
Option 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.