重新排序 tikz 矩阵的矩阵行

重新排序 tikz 矩阵的矩阵行

我有一个 tikz 矩阵,我想按从上到下到从下到上的顺序重新排列行

\matrix
{
  a & b & c\\
  d & e & f\\
  g & h & i\\
}

\matrix
{
  g & h & i\\
  d & e & f\\
  a & b & c\\
}

当然,对于简单的情况,我可以手动完成,但我有很多矩阵可能会改变。我想要一些重新排序宏。行尾分隔符是 \,所以这可能相当容易。

答案1

矩阵元素的任意排列

如果您想要置换矩阵条目,可以按如下方式进行。这是一个有效的原理证明。您定义一个矩阵,然后通过以下方式保存它

\matrix[matrix of nodes,save cells=A]
{
  a & b & c\\
  d & e & f\\
  g & h & i\\
};

其中A用作标识符(如果您有多个矩阵)。可以使用以下方法将该矩阵重新转换为置换形式

\matrix[xshift=3cm,matrix of nodes,declare function={mati(\i,\j)=4-\i;
matj(\i,\j)=\j;},reorder cells=A]
{
   &  & \\
   &  & \\
   &  & \\
};

此处的函数mati(\i,\j)和定义了行索引和列索引matj(\i,\j)的映射。在本例中,它只是恢复了行的顺序。\i\j

\documentclass[tikz,border=3mm]{standalone}
\usetikzlibrary{matrix}
\makeatletter
\tikzset{save cells/.style={cells={nodes={execute at begin
node={\ifcsname matrixcellbox#1-\the\pgfmatrixcurrentrow-\the\pgfmatrixcurrentcolumn\endcsname%
\else%
\expandafter\newbox\csname matrixcellbox#1-\the\pgfmatrixcurrentrow-\the\pgfmatrixcurrentcolumn\endcsname%
\fi%
\expandafter\expandafter\global\setbox\csname matrixcellbox#1-\the\pgfmatrixcurrentrow-\the\pgfmatrixcurrentcolumn\endcsname=\hbox\bgroup},
execute at end
node={\egroup%
\expandafter\copy\csname matrixcellbox#1-\the\pgfmatrixcurrentrow-\the\pgfmatrixcurrentcolumn\endcsname%
}}}},
reorder cells/.style={nodes in empty cells,
cells={nodes={execute at begin
node={
\setbox0=\hbox\bgroup},
execute at end
node={\egroup%
\pgfmathtruncatemacro{\myi}{mati(\the\pgfmatrixcurrentrow,\the\pgfmatrixcurrentcolumn)}%
\pgfmathtruncatemacro{\myj}{matj(\the\pgfmatrixcurrentrow,\the\pgfmatrixcurrentcolumn)}%
%\typeout{(\the\pgfmatrixcurrentrow,\the\pgfmatrixcurrentcolumn)->(\myi,\myj)}%
\expandafter\copy\csname matrixcellbox#1-\myi-\myj\endcsname%
}}}}}
\makeatother
\begin{document}
\begin{tikzpicture}
\matrix[matrix of nodes,save cells=A]
{
  a & b & c\\
  d & e & f\\
  g & h & i\\
};
\matrix[xshift=3cm,matrix of nodes,declare function={mati(\i,\j)=4-\i;
matj(\i,\j)=\j;},reorder cells=A]
{
   &  & \\
   &  & \\
   &  & \\
};
\end{tikzpicture}
\end{document}

在此处输入图片描述

以更复杂的样式定义为代价,可以通过使用以下方法避免用户输入空矩阵:这些惯例当然,也可以将节点数学化。此示例中的映射也稍微复杂一些:

\documentclass[tikz,border=3mm]{standalone}
\usepackage{etoolbox}
\usetikzlibrary{matrix}
\newcommand{\CreateEmptyMatrix}[3]{% based on https://tex.stackexchange.com/a/60400
\xdef#3{}%
  \foreach \j in {1,...,#1}{
    \foreach \i in {1,...,\the\numexpr#2-1} {%
      \begingroup\edef\x{\endgroup
         \noexpand\gappto\noexpand#3{ {} \&}}\x
      }%
    \gappto#3{\\}%
  }
}
\makeatletter
\tikzset{save cells/.style={cells={nodes={execute at begin
node={\ifcsname matrixcellbox#1-\the\pgfmatrixcurrentrow-\the\pgfmatrixcurrentcolumn\endcsname%
\else%
\expandafter\newbox\csname matrixcellbox#1-\the\pgfmatrixcurrentrow-\the\pgfmatrixcurrentcolumn\endcsname%
\fi%
\expandafter\expandafter\global\setbox\csname matrixcellbox#1-\the\pgfmatrixcurrentrow-\the\pgfmatrixcurrentcolumn\endcsname=\hbox\bgroup},
execute at end
node={\egroup%
\expandafter\copy\csname matrixcellbox#1-\the\pgfmatrixcurrentrow-\the\pgfmatrixcurrentcolumn\endcsname%
}}},
execute at end matrix={%
\expandafter\xdef\csname matrix@rows@#1\endcsname{\the\pgfmatrixcurrentrow}%
\expandafter\xdef\csname matrix@colss@#1\endcsname{\the\pgfmatrixcurrentcolumn}%
}},
save math cells/.style={cells={nodes={execute at begin
node={\ifcsname matrixcellbox#1-\the\pgfmatrixcurrentrow-\the\pgfmatrixcurrentcolumn\endcsname%
\else%
\expandafter\newbox\csname matrixcellbox#1-\the\pgfmatrixcurrentrow-\the\pgfmatrixcurrentcolumn\endcsname%
\fi%
\expandafter\expandafter\global\setbox\csname matrixcellbox#1-\the\pgfmatrixcurrentrow-\the\pgfmatrixcurrentcolumn\endcsname=\hbox\bgroup$},
execute at end
node={$\egroup%
\expandafter\copy\csname matrixcellbox#1-\the\pgfmatrixcurrentrow-\the\pgfmatrixcurrentcolumn\endcsname%
}}},
execute at end matrix={%
\expandafter\xdef\csname matrix@rows@#1\endcsname{\the\pgfmatrixcurrentrow}%
\expandafter\xdef\csname matrix@cols@#1\endcsname{\the\pgfmatrixcurrentcolumn}%
}},
reorder cells/.style={/utils/exec=%
\edef\myrows{\csname matrix@rows@#1\endcsname}%
\edef\mycols{\csname matrix@cols@#1\endcsname}%
\CreateEmptyMatrix{\myrows}{\mycols}{\myemptymatrix},
ampersand replacement=\&,
node contents=\myemptymatrix,
nodes in empty cells,
cells={nodes={execute at begin
node={
\setbox0=\hbox\bgroup},
execute at end
node={\egroup%
\edef\myrows{\csname matrix@rows@#1\endcsname}%
\edef\mycols{\csname matrix@cols@#1\endcsname}%
\pgfmathtruncatemacro{\myi}{max(1,min(\myrows,mati(\the\pgfmatrixcurrentrow,\the\pgfmatrixcurrentcolumn)))}%
\pgfmathtruncatemacro{\myj}{max(1,min(\mycols,matj(\the\pgfmatrixcurrentrow,\the\pgfmatrixcurrentcolumn)))}%
%\typeout{(\the\pgfmatrixcurrentrow,\the\pgfmatrixcurrentcolumn)->(\myi,\myj)}%
\expandafter\copy\csname matrixcellbox#1-\myi-\myj\endcsname%
}}}}}
\makeatother
\begin{document}
\begin{tikzpicture}
\matrix[matrix of nodes,save math cells=A]
{
  a & b & c\\
  d & e & f\\
  g & h & i\\
};
\matrix[xshift=3cm,matrix of nodes,
declare function={mati(\i,\j)=4-\i;
matj(\i,\j)=4-\j;},reorder cells=A]
{
};
\end{tikzpicture}
\end{document}

在此处输入图片描述

当然,人们可以抑制第一个矩阵的输出,例如,将其放入我们从未使用过的盒子中。

旧答案:拨负数即可达到此效果row sep

\documentclass[tikz,border=3mm]{standalone}
\usetikzlibrary{matrix}
\tikzset{swap rows/.style={row sep=-3em,yshift=1em}}
\begin{document}
\begin{tikzpicture}
\matrix[matrix of math nodes]
{
  a & b & c\\
  d & e & f\\
  g & h & i\\
};
\matrix[xshift=3cm,matrix of math nodes,swap rows]
{
  a & b & c\\
  d & e & f\\
  g & h & i\\
};
\end{tikzpicture}
\end{document}

在此处输入图片描述

类似的伎俩已经被使用这里这里

相关内容