使用 TiKZ 数学节点矩阵模拟 amsmath 矩阵的障碍

使用 TiKZ 数学节点矩阵模拟 amsmath 矩阵的障碍

我正在尝试找出一个TiKZ基于的解决方案这个问题涉及矩阵行之间的箭头。为此,我希望至少能够制作一个模拟环境matrix of math nodes行为的程序。matrixamsmath

我在这样做的过程中遇到了几个问题。其中之一是矩阵本身的外观及其与周围文本的关系。请考虑以下示例:

\documentclass{article}
\usepackage{amsmath,tikz}
\usetikzlibrary{matrix}

\newlength\mtxrowsep   \setlength\mtxrowsep{2ex}
\newlength\mtxcolsep   \setlength\mtxcolsep{\arraycolsep}

\begin{document}
\begin{gather*}
    4 \times
    \left[\begin{matrix} a & b \\ c & d \end{matrix}\right]
\qquad
    4 \times
    \left[\begin{tikzpicture}
      \matrix [matrix of math nodes, ampersand replacement=\&,
               inner sep=0pt, column sep=\mtxcolsep, row sep=\mtxrowsep]
          { a \& b \\ c \& d \\ };
    \end{tikzpicture}\right]
\qquad
    4 \times
    \left[\begin{minipage}{1.7em}
      {}\hfill\begin{tikzpicture}
        \matrix [matrix of math nodes, ampersand replacement=\&,
                 inner sep=0pt, column sep=\mtxcolsep, row sep=\mtxrowsep]
                { a \& b \\ c \& d \\   };
      \end{tikzpicture}\hfill{}
    \end{minipage}\right]
\end{gather*}
\end{document}

这将产生以下输出:

矩阵比较

真正的amsmath矩阵在左边。中间的矩阵存在一个问题,即环境matrix of math nodes中的tikzpicture似乎位于周围数学基线的顶部。右侧的矩阵对齐正确,因为它位于 内,其宽度是手动指定的。(图中未显示使用或 的minipage任何内容,它们本身存在间距问题,并且存在相同的垂直对齐问题。)left delimiterright delimiter

主要问题。

  1. 是否有任何本机方法可以tikz改变tikzpicture中间矩阵的垂直对齐方式?(我在扫描手册时没有发现任何东西......)

  2. 有什么方法可以自动提取图像的宽度,以允许自动调整minipage右侧矩阵的大小?

答案1

好的,这是我的第一次尝试。它需要对两边的间距进行一些调整,而且我只使用给定的 2x2 矩阵进行了测试,并且没有任何字体大小更改,因此长度的一些选择可能不正确。

baseline通过在封闭的 上设置选项来处理垂直居中tikzpicture。我们希望矩阵的实际中心略高于基线(=我猜大约是 的中间)。反复试验后,我得到了一个高度.7ex。接下来是分隔符。TikZ 可以自己处理它们,所以我认为最好让它处理它们,而不是把东西放在框或小页面中(节点文本已经在框中了,等等,所以放更多似乎有点小题大做)。我发现分隔符在垂直方向上有点偏离,所以我把它们向下移动了一个点,也向外移动了一点。我不想触碰 ,因为inner sep这会同时改变垂直和水平方向,所以我只是把它们稍微往内移动了一点。这些是样式every (left|right|) delimiter。我想要矩阵本身一点inner sep,但不想要条目本身。我还稍微调整了行和列的分隔以更好地匹配 AMS 样式。

接下来是 & 符号。我对此有点担心,但我要做的是将其更改为活动字符。它会检查它是否在 TikZ 矩阵内。如果是,则生成,\pgfmatrixnextcell如果不是,则生成旧的 & 符号。这可以通过仅检查我们是否在我们的一个中来使其更强大一些特别的TikZ 矩阵。我不知道这是否是一个好的解决方案。

此后,只需将所有内容放入环境中即可。

让我们从结果开始。在每一行中,第一行是tikzpicture,第二行相同但包装到环境中,第三行是 AMS 原始行。

tikz 矩阵替换

现在代码是:

\documentclass{standalone}
%\url{http://tex.stackexchange.com/q/26866/86}
\usepackage{amsmath,tikz}
\usetikzlibrary{matrix}

\newlength\mtxrowsep   \setlength\mtxrowsep{1.5ex}
\newlength\mtxcolsep   \setlength\mtxcolsep{2\arraycolsep}

\tikzset{
  ams/.style={
    baseline=-.7ex,
    every delimiter/.style={yshift=-1pt},
    every left delimiter/.style={xshift=2pt},
    every right delimiter/.style={xshift=-2pt},
    every node/.style={inner sep=0pt},
  },
  ams matrix/.style={
    inner sep=1pt,
    column sep=\mtxcolsep,
    row sep=\mtxrowsep,
%    ampersand replacement=\&,
    matrix of math nodes,
  },
  bmatrix/.style={
    ams,
    every matrix/.style={
      ams matrix,
      left delimiter={[},
      right delimiter={]},
    }
  },
  Bmatrix/.style={
    ams,
    every matrix/.style={
      ams matrix,
      left delimiter={\lbrace},
      right delimiter={\rbrace},
    }
  },
  pmatrix/.style={
    ams,
    every matrix/.style={
      ams matrix,
      left delimiter={(},
      right delimiter={)},
    }
  },
  vmatrix/.style={
    ams,
    every matrix/.style={
      ams matrix,
      left delimiter={|},
      right delimiter={|},
    }
  },
  Vmatrix/.style={
    ams,
    every matrix/.style={
      ams matrix,
      left delimiter={\|},
      right delimiter={\|},
    }
  },
}

\let\matamp=&

\catcode`\&=13
\makeatletter
\def&{\iftikz@is@matrix
  \pgfmatrixnextcell
  \else
  \matamp
  \fi}
\makeatother

%\usepackage{environ}
\def\endtikzmatrix{\\\egroup;\end{tikzpicture}}
\foreach \mtype in {b,B,p,v,V} {

\expandafter\xdef\csname tikz\mtype matrix\endcsname{%
    \noexpand\begin{tikzpicture}[\mtype matrix]
    \noexpand\matrix \noexpand\bgroup}
\expandafter\global\expandafter\let\csname endtikz\mtype matrix\endcsname=\endtikzmatrix
}

\begin{document}
\foreach \mtype in {b,B,p,v,V} {
  \edef\metype{\mtype matrix}
  \edef\tmetype{tikz\mtype matrix}
\begin{gather*}
\begin{tikzpicture}[\metype]
\matrix (m) {
  a & b \\ c & d \\};
\end{tikzpicture}
\begin{\tmetype} a & b \\ c & d \end{\tmetype}
\begin{\metype} a & b \\ c & d \end{\metype}
\end{gather*}
}

\end{document}

\foreach循环只是为了节省我大量的剪切和粘贴操作。)

答案2

要修改图片的对齐方式,问题在于 Tikz 会根据其计算出的边界框对齐对象。可以手动设置边界框,然后根据边界框对齐对象。例如,

\begin{tikzpicture}

\path[use as bounding box] (0,0) rectangle (1,1);
\fill[blue] (0,0) circle[radius=2pt];
%shift matrix with respect to bounding box 
\matrix [matrix of math nodes, ampersand replacement=\&,
         inner sep=0pt, column sep=\mtxcolsep, row sep=\mtxrowsep,
         left delimiter={[},right delimiter={]},shift={(0,1)}] (m)
          { a \& b \\ c \& d \\ };

\end{tikzpicture}

或者

\begin{tikzpicture}

%shift bounding box
\path[use as bounding box] (0,1) rectangle (1,2);
\fill[blue] (0,0) circle[radius=2pt];

          \matrix [matrix of math nodes, ampersand replacement=\&,
               inner sep=0pt, column sep=\mtxcolsep, row sep=\mtxrowsep,
                 left delimiter={[},right delimiter={]}] (m)
          { a \& b \\ c \& d \\ };

\end{tikzpicture}

结果是

在此处输入图片描述

答案3

我不太了解 TikZ,但是

\left[\vcenter{\hbox{\begin{tikzpicture}
  <TikZ code>\end{tikzpicture}}}\right]

给出“几乎正确”的括号。

答案4

该包nicematrix提供了环境{pNiceMatrix}{bNiceMatrix}等,类似于经典环境{pmatrix}{bmatrix}等,amsmath但它们在数组的单元格下创建 PGF/Tikz 节点。可以在所谓的\CodeAfter环境中将这些节点与 Tikz 一起使用。当为矩阵命名时(使用键),也可以在环境之外使用这些节点name

\documentclass{article}
\usepackage{nicematrix,tikz}

\begin{document}

$A = \begin{pNiceMatrix}
A_{11} & A_{12} & A_{13} \\
A_{21} & A_{22} & A_{23} \\
A_{31} & A_{32} & A_{33}
\CodeAfter
  \tikz \draw [red,->,shorten > = 4pt] (1-1.north) to [bend left] (1-3.north) ; 
\end{pNiceMatrix}$

\end{document}

创建的矩阵的几何形状与环境相同amsmath(与 Tikz 数学节点矩阵不同)。

上述代码的输出

您可能需要多次编译(因为 PGF/Tikz 节点)。

相关内容