Tikz 在网格中垂直对齐

Tikz 在网格中垂直对齐

以下是一个 MWE 来说明问题。我甚至不知道如何正确描述它。一旦我添加最后一条曲线,垂直位置就会被破坏。有人可以解释一下这种行为吗?

\documentclass{beamer}

\mode<presentation>
{
  \usetheme{Warsaw}      % or try Darmstadt, Madrid, Warsaw, ...
  \usecolortheme{default} % or try albatross, beaver, crane, ...
  \usefonttheme{default}  % or try serif, structurebold, ...
  \setbeamertemplate{navigation symbols}{}
  \setbeamertemplate{caption}[numbered]
}
\usepackage{subfig}
\makeatletter
\@addtoreset{subfigure}{framenumber}
\usepackage{tikz}
\usetikzlibrary{positioning,calc,shapes,arrows,fit}
\begin{document}
\begin{frame}
  \begin{figure}
    \subfloat[]{\label{}
      \begin{tikzpicture}[darkstyle/.style={circle,draw,fill=blue!20,minimum size=20}]
        \foreach \y in {0,...,3}
        \foreach \x in {0,...,3}
        {\pgfmathtruncatemacro{\label}{4 * \y + \x}
        \node [darkstyle]  (\y\x) at (1.5*\x,4.5-1.5*\y) {\label};}

        \foreach \y [count=\yi]  in {0,...,2}
        \foreach \x in {0,...,3}
        \draw [->,green] (\x\y) -- (\x\yi) ;

        % \foreach \i [count=\ii] in {0,...,2}
        % \draw [->,green] (\i3) to [in=90, out=-90] (\ii0) ;

        \foreach \i [count=\ii] in {0,...,2}
        \draw [->,green] (\i3) to [in=45, out=-135] (\ii0) ;
      \end{tikzpicture}
    }
    \subfloat[]{\label{}
      \begin{tikzpicture}[darkstyle/.style={circle,draw,fill=blue!20,minimum size=20, outer sep=0pt}]
        \foreach \y in {0,...,3}
        \foreach \x in {0,...,3}
        {\pgfmathtruncatemacro{\label}{4 * \y + \x}
        \node [darkstyle]  (\y\x) at (1.5*\x,4.5-1.5*\y) {\label};}

        \foreach \y [count=\yi]  in {0,...,2}
        \foreach \x in {0,...,3}
        \draw [->,green] (\x\y) -- (\x\yi) ;

        \draw [->,green] (03) to [in=90, out=-90] (10) ;
        \draw [->,green] (13) to [in=90, out=-90] (20) ;
        % \draw [->,green] (23) to [in=90, out=-90] (30) ;
      \end{tikzpicture}
    }
  \end{figure}
\end{frame}
\begin{frame}
  \begin{figure}
    \subfloat[]{\label{}
      \begin{tikzpicture}[darkstyle/.style={circle,draw,fill=blue!20,minimum size=20}]
        \foreach \y in {0,...,3}
        \foreach \x in {0,...,3}
        {\pgfmathtruncatemacro{\label}{4 * \y + \x}
        \node [darkstyle]  (\y\x) at (1.5*\x,4.5-1.5*\y) {\label};}

        \foreach \y [count=\yi]  in {0,...,2}
        \foreach \x in {0,...,3}
        \draw [->,green] (\x\y) -- (\x\yi) ;

        % \foreach \i [count=\ii] in {0,...,2}
        % \draw [->,green] (\i3) to [in=90, out=-90] (\ii0) ;

        \foreach \i [count=\ii] in {0,...,2}
        \draw [->,green] (\i3) to [in=45, out=-135] (\ii0) ;
      \end{tikzpicture}
    }
    \subfloat[]{\label{}
      \begin{tikzpicture}[darkstyle/.style={circle,draw,fill=blue!20,minimum size=20, outer sep=0pt}]
        \foreach \y in {0,...,3}
        \foreach \x in {0,...,3}
        {\pgfmathtruncatemacro{\label}{4 * \y + \x}
        \node [darkstyle]  (\y\x) at (1.5*\x,4.5-1.5*\y) {\label};}

        \foreach \y [count=\yi]  in {0,...,2}
        \foreach \x in {0,...,3}
        \draw [->,green] (\x\y) -- (\x\yi) ;

        \draw [->,green] (03) to [in=90, out=-90] (10) ;
        \draw [->,green] (13) to [in=90, out=-90] (20) ;
        \draw [->,green] (23) to [in=90, out=-90] (30) ;
      \end{tikzpicture}
    }
  \end{figure}
\end{frame}
\end{document}

在此处输入图片描述 在此处输入图片描述

答案1

曲线路径由具有两个控制点的贝塞尔曲线构成。TikZ 通过确保路径的所有点都位于边界框内来自动扩展图片的边界框。对于直线、圆弧/圆/椭圆和基本曲线,这通常效果很好。对于

您可以看到路径的控制点(红色十字)

\draw (  0,0 ) to    [bend left] (2,2);
\draw ( .5,0 ) arc   [start angle=180, delta angle=-90, radius=1.5];
\draw (1.5,.5) circle[radius=.5, rotate=0];

对于 TikZ 本身,虚线表示边界框。
观察当我旋转circle右图中约为45度。

在此处输入图片描述在此处输入图片描述

TikZ 不使用实际路径来扩展边界框,而是使用(除了起点和目标点之外)控制点。

现在,让我们看一下您的图片(只是为了清楚起见:即使没有我为此答案添加的绘制点,也会发生这种情况):

在此处输入图片描述

(尽管 TikZ 实际上可以计算路径上的点(对于节点),但它不会使用它来计算边界框。)


在您的示例中,您看不到添加的空间,因为图片的基线位于底部,这是 TeX 垂直对齐图片的地方。

对于您来说,最简单的解决方案是将overlay选项添加到弯曲路径(无论如何它已经位于节点创建的边界框内):

在此处输入图片描述

我还建议您使用edges,这通常会使代码更简洁:

\path[overlay, ->, green, in=90, out=-90] (03) edge (10)
                                          (13) edge (20)
                                          (23) edge (30);

(我也会使用其他节点名称,即n-<row>-<column>节点n-12-3使用另一个名称作为节点n-1-23。)

附录

本答案中创建图片的代码是

\usetikzlibrary{backgrounds,decorations.pathreplacing,shapes.misc}
\tikzset{
  show bezier control points/.style={
    postaction={
      decoration={name=show path construction,
      curveto code={\draw [-, overlay, opacity=1, blue, densely dotted]
          (\tikzinputsegmentfirst) -- (\tikzinputsegmentsupporta)
          node [at end, cross out, draw, solid, red, inner sep=1pt]{};
        \draw [-, overlay, opacity=1, blue, densely dotted]
          (\tikzinputsegmentsupportb) -- (\tikzinputsegmentlast)
          node [at start, cross out, draw, solid, red, inner sep=1pt]{};}},
      decorate}},
  every picture/.append style={
    inner frame sep=0, framed, thick, opacity=.5,
    background rectangle/.append style={thin, dashed}}}

然后可以使用样式show bezier control points来可视化贝塞尔曲线(使用decorations.pathreplacing库及其show path construction装饰以及库cross out中的形状)shapes.misc。边界框是通过backgroundsframed在图片末尾添加矩形的选项”添加的。

答案2

您可以通过在左图中以相同的方式定义路径来伪造这样的曲线

\path [->,green] (23) to [in=90, out=-90] (30) ;

所以您将拥有相同的高度。该\path命令将沿着曲线移动笔,但不会绘制任何东西。曲线将“不可见”。

在此处输入图片描述

相关内容