在 tikz 矩阵节点内居中和定位图像

在 tikz 矩阵节点内居中和定位图像

我正在尝试构建一个 tikz 矩阵,其中每个单元格要么是空的,要么包含图像或图像的一部分。也就是说,如果单个图像很大,则可能跨越多个单元格。

我正在使用以下内容测试图像kings使用以下代码从 OpenClipart调用:

\documentclass[tikz]{standalone}
\usetikzlibrary{fit, matrix}

\begin{document}
\begin{tikzpicture}
\matrix [
    matrix of nodes,
    row sep=-\pgflinewidth,
    column sep=-\pgflinewidth,
    nodes={
        rectangle, draw=black, minimum height=11mm, minimum width=11mm,
        anchor=center, inner sep=0pt, outer sep=0pt, font=\Huge
    },
    nodes in empty cells,
    name=table
] {    
 &  &  &  &  \\
 &  &  &  &  \\
 &  &  &  &  \\
 &  &  &  &  \\
};

% Using draw just to make the problem clear
\node[fit=(table-2-3)(table-2-4), draw]{
% This works, but is there a more robust way?
%\vspace{-0.1cm}
\includegraphics[width=22mm, height=11mm]{kings}
};

\node[fit=(table-3-1)(table-4-2), draw]{
%\vspace{-0.1cm}
\includegraphics[width=22mm, height=11mm]{kings}
};

\end{tikzpicture}
\end{document}

这将产生以下输出:

在此处输入图片描述

在这里,我使用draw只是为了让问题更清楚:似乎图像的下半部分用于居中。通过使用负片,vspace我可以让它看起来不错,但它看起来不太好或不稳固。有没有更好的方法?

还有一个问题,我希望图像内部的网格线消失(即,图像应该绘制在网格的内线上),但外线应该保持完整。同样,我可以通过执行类似 的操作“几乎”做到这一点draw=white,但会产生类似效果(图像上方的黑线会断开,因为在图像周围绘制了一个白色矩形):

在此处输入图片描述

答案这里帮助我更接近目标,但只考虑单个节点内的单个图像。

答案1

该库的手册说明fit

fit 选项的具体效果如下:

  1. […]
  2. […]
  3. […]
  4. […]
  5. […]
  6. 节点排版后,其高度和深度将被调整,使得它们加起来等于计算出的边界框的高度,并且节点的文本在框内垂直居中。

上面的意思是,一般来说,如果节点包含文本(如上例中的框),它将位于框内的中央。将文本放在其他地方会很困难,特别是更改节点的锚点不会产生预期的效果。相反,您应该做的是创建一个带有 fit 选项的不包含任何文本的节点,为其命名,然后使用普通节点在所需位置添加文本。或者,考虑使用标签或 pin 选项。

这意味着创建的节点将具有text height=5.5mmtext depth=5.5mm。您的图片只有高度,没有深度,这会将其向上推。

最简单的解决方案是遵循手册的建议。

我们将使用没有文本的拟合节点,并使用label键将另一个节点放置在拟合节点的中心。

fill只需将节点(而不是标签)与背景颜色(此处)结合,即可删除图片后面的线条white。如果您有更复杂的图形,这可能会失败。(我认为这是一种肮脏的解决方案,但有时它们是最简单的。)

inner sep=-.5\pgflinewidth使得拟合节点的线宽实际上比其拟合节点的线宽小一半,这样您就不会过度绘制未穿过图片的线条。如果您对矩阵节点使用不同的线宽,则需要调整这一点,但它可以自动完成,这样您就不必因为想尝试另一种线宽而调整一堆样式。

由于标签和矩阵本身都是节点,因此我也会inner sep=0pt向它们添加节点,以便它们不会对图片的边界框产生贡献。

我使用这种kings风格使其易于使用,而不必重复大量相同的 TikZ 指令。

根据您的实际图形,可能会在这里或那里进行调整。

代码

\documentclass[tikz]{standalone}
\usetikzlibrary{fit, matrix}
\begin{document}
\begin{tikzpicture}[
    kings/.style={
      fit={#1},
      fill=white,                 % overdraw lines behind the picture
      inner sep=-.5\pgflinewidth, % but don't touch the lines around it
      node contents=,             % no text in the fitted node → no need for {}
      label={
        [inner sep=0pt]     % the label is a node, we don't want that padding here either
        center:             % the label will be placed at the center of the fitted node
        {\includegraphics[width=22mm, height=11mm]{kings}}}}]
\matrix [
    matrix of nodes,
    inner sep=0pt,                % no padding around the cells
    row sep=-\pgflinewidth,
    column sep=-\pgflinewidth,
    nodes={
        rectangle, draw=black, minimum height=11mm, minimum width=11mm,
        anchor=center, inner sep=0pt, outer sep=0pt
    },
    nodes in empty cells,
    name=table
] {    
 &  &  &  &  \\
 &  &  &  &  \\
 &  &  &  &  \\
 &  &  &  &  \\
};

\node[kings=(table-2-3)(table-2-4)];
\node[kings=(table-3-1)(table-4-2)];
\end{tikzpicture}
\end{document}

输出

在此处输入图片描述

相关内容