编辑:

编辑:

我想将 3 个投影仪块放在一个框架上并按循环顺序连接它们。

我尝试使用 TikZ 进行一些操作,但没有效果。

主要问题是以下代码中的点n1.southn2.south实际上位于块的末尾。

\documentclass[aspectratio=169]{beamer}
\usepackage{tikz}
\usetheme{Frankfurt}

\tikzset{
  every overlay node/.style={
    %draw=black,fill=white,rounded corners,
    anchor=north west,
  },
}
% Usage:
% \tikzoverlay at (-1cm,-5cm) {content};
% or
% \tikzoverlay[text width=5cm] at (-1cm,-5cm) {content};
\def\tikzoverlay{%
   \tikz[baseline,overlay]\node[every overlay node]
}%

\begin{document}

\begin{frame}
\tikzoverlay (n1) at (8cm,2cm) {
  \begin{minipage}{0.4\textwidth}
    \begin{block}{title1}
      {Text1}
    \end{block}
  \end{minipage}
};

\tikzoverlay (n2) at (0cm,2cm) {
  \begin{minipage}{0.4\textwidth}
    \begin{block}{title2}
      Text2
    \end{block}
  \end{minipage}
};

\tikzoverlay (n3) at (5cm,0cm) {
  \begin{minipage}{0.4\textwidth}
    \begin{block}{Title3}
      Text3
    \end{block}
  \end{minipage}
};

\begin{tikzpicture}[overlay]
  \path [line width=0.3cm,->] (n1.south) edge (n3.south);
  \path [line width=0.3cm,->] (n3.north) edge (n2.south);
  \path [line width=0.3cm,->] (n2.east) edge (n1.west);

\end{tikzpicture}


\end{frame}
\end{document}

答案1

我在某些方面修复了你的代码:

  1. 最重要的是,您还必须remember picture为覆盖提供选项。如果没有它,每个节点的名称就不会引用正确的坐标,因为它们是不同 tikz 图片中的节点。
  2. baseline在这种情况下,实际上不需要该选项。
  3. inner sep对于块节点,设置为零
  4. %在某些行的末尾添加以防止垂直空格(这种情况仍然会发生,我不知道为什么,可以通过取消注释样式的第一行来使其可见every overlay node

最终的代码如下:

\documentclass[aspectratio=169]{beamer}
\usepackage{tikz}
\usetheme{Frankfurt}

\tikzset{
  every overlay node/.style={
    %draw=black,fill=white,rounded corners,
    anchor=north west, inner sep=0pt,
  },
}
% Usage:
% \tikzoverlay at (-1cm,-5cm) {content};
% or
% \tikzoverlay[text width=5cm] at (-1cm,-5cm) {content};
\def\tikzoverlay{%
   \tikz[remember picture, overlay]\node[every overlay node]
}%

\begin{document}

\begin{frame}
\tikzoverlay (n1) at (8cm,2cm) {%
  \begin{minipage}{0.4\textwidth}%
    \begin{block}{title1}%
      {Text1}
    \end{block}
  \end{minipage}
};

\tikzoverlay (n2) at (0cm,2cm) {%
  \begin{minipage}{0.4\textwidth}%
    \begin{block}{title2}%
      Text2
    \end{block}
  \end{minipage}
};

\tikzoverlay (n3) at (5cm,0cm) {%
  \begin{minipage}{0.4\textwidth}%
    \begin{block}{Title3}%
      Text3
    \end{block}
  \end{minipage}
};

\begin{tikzpicture}[remember picture, overlay]
  \path [line width=0.3cm,->] (n1.south) edge (n3.south);
  \path [line width=0.3cm,->] (n3.north) edge (n2.south);
  \path [line width=0.3cm,->] (n2.east) edge (n1.west);
\end{tikzpicture}
\end{frame}
\end{document}

产生(之后编译两次):

结果

在我看来,这很丑陋,但我想这就是你想要的。

编辑:

当我编写上述代码时,我没有注意绘制每个节点的坐标值。我假设节点 2 与节点 1 处于不同级别的结果是故意的。但 OP 注释让我意识到两个节点确实使用相同的 y 坐标,那么,为什么它们不对齐呢?

原因是它们不是在同一个 中绘制的tikzpicture,因此它们不共享坐标空间。每个tikzpicture(或\tikz命令)都启动自己的坐标系。因此,新的问题是“那么为什么几乎工作了?

原因是每个图形都有选项overlay,这意味着无论图片实际绘制什么,tex 为该图片保留的空间都是零。它是一个无量纲点。该点就是图形的原点。

因此,如果我们有三个图形,中间没有空格,由于每个图形在 tex 中都被视为无量纲点,因此这三个图形将绘制在“同一点”,因此它们的坐标系将匹配。但如果图形被文字分隔开,那么每个图形都有自己的原点。

就你的情况而言,分开通过空格甚至`\par,因为源代码中有空行,并且图形之间有行尾。

解决方案是删除所有不需要的空间,方法是删除图形之间的空行并注释掉每个图形末尾的回车符(否则会产生空格):

\documentclass[aspectratio=169]{beamer}
\usepackage{tikz}
\usetheme{Frankfurt}

\tikzset{
  every overlay node/.style={
    %draw=black,fill=white,rounded corners,
    anchor=north west, inner sep=0pt,
  },
}
% Usage:
% \tikzoverlay at (-1cm,-5cm) {content};
% or
% \tikzoverlay[text width=5cm] at (-1cm,-5cm) {content};
\def\tikzoverlay{%
   \tikz[remember picture, overlay]\node[every overlay node]
}%

\begin{document}

\begin{frame}
\tikzoverlay (n1) at (8cm,2cm) {%
  \begin{minipage}{0.4\textwidth}%
    \begin{block}{title1}%
      {Text1}
    \end{block}
  \end{minipage}
};%
\tikzoverlay (n2) at (0cm,2cm) {%
  \begin{minipage}{0.4\textwidth}%
    \begin{block}{title2}%
      Text2
    \end{block}
  \end{minipage}
};%
\tikzoverlay (n3) at (5cm,0cm) {%
  \begin{minipage}{0.4\textwidth}%
    \begin{block}{Title3}%
      Text3
    \end{block}
  \end{minipage}
};%
%
\begin{tikzpicture}[remember picture, overlay]
  \path [line width=0.3cm,->] (n1.south) edge (n3.south);
  \path [line width=0.3cm,->] (n3.north) edge (n2.south);
  \path [line width=0.3cm,->] (n2.east)  edge (n1.west);
\end{tikzpicture}
\end{frame}
\end{document}

结果:

结果

答案2

JLDiaz 向您解释了如何修复代码,但结果还有待改进。我建议的解决方案可能并不完美,因为需要多加注意,但在我看来,它提供了更好的结果。

它基于包textpos将方块放置在更改投影仪中块的默认宽度自定义块宽度并在\tikzmark宏上识别块。

实际上,您的解决方案中有趣的是,您识别块并将其放入 TikZ 节点中,以便稍后使用节点的锚点将它们连接起来的机制。然而,此解决方案使用textpos因此:如何识别整个区块?这就是需要的原因\tikzmark。请注意,使用textpos有助于避免出现垂直错位等问题。

构建\tikzmark方式使得节点可以在其宽度和高度上扩展(这是需要小心的部分):请注意,块的高度最终取决于您的内容,所以我的建议是 1)先写内容 2)稍后修复其高度。

所标识的点mark恰好位于块标题的中心并且节点标识了比块更大的区域:

在此处输入图片描述

从图中可以看出,通过构建的节点有一半\tikzmark是空的:这样做是为了确保连接平行块,箭头可以通过类似的东西实现

\path[line width=0.2cm](n2.east)edge[bend left](n1.west);

因此,上部仍为空,如果您在块顶部绘制开始/结束的连接,则应该注意此行为。此问题已通过特殊锚点以特殊方式修复。

显示所有内容的代码:

\documentclass[aspectratio=169]{beamer}
\usepackage{lmodern}
\usepackage{tikz}
\usepackage[overlay]{textpos}
\usetheme{Frankfurt}

\newcommand{\tikzmark}[2][minimum width=6cm,minimum height=1.5cm]{
 \tikz[remember picture,overlay]
 \node[anchor=west,
       inner sep=0pt,
       outer sep=6pt,
       xshift=-0.5em,
       yshift=-3ex,
       #1](#2){};
}

\newcommand{\shownode}[1]{
  \tikz[remember picture,overlay]\draw[red](#1.south east)rectangle(#1.north west);
}

\newcommand{\showanchor}[1]{
  \tikz[remember picture,overlay]\draw[red,thick,mark=x] plot coordinates{(#1)};
}

% original code from Stefan Kottwitz
% https://tex.stackexchange.com/a/12551/13304
\newenvironment<>{varblock}[2][.9\textwidth]{%
  \setlength{\textwidth}{#1}
  \begin{actionenv}#3%
    \def\insertblocktitle{#2}%
    \par%    
    \usebeamertemplate{block begin}%
    }
  {\par%
    \usebeamertemplate{block end}%
  \end{actionenv}}

\newenvironment{myblock}[1]{\begin{textblock*}{500pt}(#1)}{\end{textblock*}}

% special way to reach the top of the block
\def\newabove(#1){
([yshift=1.5ex]#1.center)
}

\begin{document}
\begin{frame}
\begin{myblock}{0.55\textwidth, -0.2\textheight}
    \tikzmark{n1}
    \shownode{n1}    
    %remove the previous line: just used to see where the invisible node is placed
    \begin{varblock}[6cm]{title1}
    text1
    \end{varblock}
    \showanchor{n1}
    %remove also this: just used to see where n1 is positioned
\end{myblock}

\begin{myblock}{0em, -0.2\textheight}
    \tikzmark{n2}
    \shownode{n2}
    \begin{varblock}[6cm]{title2}
    text2
    \end{varblock}
    \showanchor{n2}
\end{myblock} 

\begin{myblock}{0.3\textwidth, 0.2\textheight}
    \tikzmark[minimum width=5cm,minimum height=2.25cm]{n3} % customization of width and height
    \shownode{n3}
    \begin{varblock}[5cm]{title3}
    text3\\
    text
    \end{varblock}
    \showanchor{n3}
\end{myblock}

\begin{tikzpicture}[remember picture,overlay,-stealth]
\path[line width=0.2cm](n2.east)edge[bend left](n1.west);
\path[line width=0.2cm](n1.south)edge[bend left](n3.east);
\path[line width=0.2cm](n3.west)edge[bend left](n2.south);
% in case you need to connect some block from ``north''
%\path[line width=0.2cm](n3.north)edge[bend left](n1.south west); % is wrong
\path[line width=0.2cm]\newabove(n3) edge[bend left](n1.south west);
\end{tikzpicture}
\end{frame}
\end{document}

删除所有内容以使节点和锚点可见,以及显示如何到达块顶部的特殊路径,最终得到:

在此处输入图片描述

我想这就是你想要的。

如何处理区块的高度问题

由于这可能是该程序的一个缺点,让我们举一个例子。

首先,我们应该关心块的内容,而不要考虑高度或其他东西。例如:

\documentclass[aspectratio=169]{beamer}
\usepackage{lmodern}
\usepackage{tikz}
\usetheme{Frankfurt}
\usepackage[overlay]{textpos}

\newcommand{\tikzmark}[2][minimum width=6cm,minimum height=1.5cm]{
 \tikz[remember picture,overlay]
 \node[anchor=west,
       inner sep=0pt,
       outer sep=6pt,
       xshift=-0.5em,
       yshift=-3ex,
       #1](#2){};
}

\newcommand{\shownode}[1]{
  \tikz[remember picture,overlay]\draw[red](#1.south east)rectangle(#1.north west);
}

\newcommand{\showanchor}[1]{
  \tikz[remember picture,overlay]\draw[red,thick,mark=x] plot coordinates{(#1)};
}

% original code from Stefan Kottwitz
% https://tex.stackexchange.com/a/12551/13304
\newenvironment<>{varblock}[2][.9\textwidth]{%
  \setlength{\textwidth}{#1}
  \begin{actionenv}#3%
    \def\insertblocktitle{#2}%
    \par%    
    \usebeamertemplate{block begin}%
    }
  {\par%
    \usebeamertemplate{block end}%
  \end{actionenv}}

\newenvironment{myblock}[1]{\begin{textblock*}{500pt}(#1)}{\end{textblock*}}

% special way to reach the top of the block
\def\newabove(#1){
([yshift=1.5ex]#1.center)
}

\begin{document}
\begin{frame}

\begin{myblock}{0cm,-2.5cm}
    \tikzmark{n1}
    \begin{varblock}[6cm]{title1}
    Hello! :) This is the text of my block. Here I want to say
    that the height of the blocks is not so problematic.
    \end{varblock}
\end{myblock}

\begin{myblock}{8cm,-2.5cm}
    \tikzmark{n2}
    \begin{varblock}[6cm]{title2}
    This is my very long block with even an equation:
    \[\Delta_n=
     \begin{cases}
       1 \quad q_n>0\\
       0 \quad q_n=0
     \end{cases}
    \]
    \end{varblock}
\end{myblock}


% I can leave all blank lines I want




\begin{myblock}{8cm,2cm}
    \tikzmark{n3}
    \begin{varblock}[6cm]{title3}
    Short text
    \end{varblock}
\end{myblock}



\begin{myblock}{0cm,2cm}
    \tikzmark{n4}
    \begin{varblock}[6cm]{title4}
    Short text
    \end{varblock}
\end{myblock}

\begin{tikzpicture}[remember picture,overlay,-stealth,line width=0.2cm]
\draw (n1.east)--(n2.west);
\draw (n2.south)--\newabove(n3);
\draw (n3.west)--(n4.east);
\draw \newabove(n4)--(n1.south);
\end{tikzpicture}
\end{frame}
\end{document}

请注意,我故意留下了一些空行。经过两次编译运行后,我们得到:

在此处输入图片描述

哦.. 区块 1 和 2 有问题。为什么?因为高度不对;使用我们的\shownode\showanchor可以理解原因:

在此处输入图片描述

现在请注意,默认值是1.5cm高度。因此,类似于0.75cm带有标题和正文一行的块。

在区块 1 中,我们有 4 行+标题,因此粗略地说,我们有标准高度的三倍:0.75cm x 3=2.25cm。然而,这只是区块,因此要获得整个节点,我们应该再次乘以二。总计:4.5cm

现在看第二个块:它只是比块 1 高一点。我猜那是1cm更高,所以我们把它放上去5.5cm

所以我们必须更新:

\begin{myblock}{0cm,-2.5cm}
    \tikzmark[minimum width=6cm, minimum height=4.5cm]{n1}
    \shownode{n1}
    \begin{varblock}[6cm]{title1}
    Hello! :) This is the text of my block. Here I want to say
    that the height of the blocks is not so problematic.
    \end{varblock}
    \showanchor{n1}
\end{myblock}

\begin{myblock}{8cm,-2.5cm}
    \tikzmark[minimum width=6cm, minimum height=5.5cm]{n2}
    \shownode{n2}
    \begin{varblock}[6cm]{title2}
    This is my very long block with even an equation:
    \[\Delta_n=
     \begin{cases}
       1 \quad q_n>0\\
       0 \quad q_n=0
     \end{cases}
    \]
    \end{varblock}
    \showanchor{n2}
\end{myblock}

这提供了:

在此处输入图片描述

差不多我们完成了。但我对区块 2 仍不满意:它不够精确。我想我们需要0.25cm更多。因此:

\begin{myblock}{8cm,-2.5cm}
    \tikzmark[minimum width=6cm, minimum height=5.75cm]{n2}
    \shownode{n2}
    \begin{varblock}[6cm]{title2}
    This is my very long block with even an equation:
    \[\Delta_n=
     \begin{cases}
       1 \quad q_n>0\\
       0 \quad q_n=0
     \end{cases}
    \]
    \end{varblock}
    \showanchor{n2}
\end{myblock}

得出:

在此处输入图片描述

哦……糟糕。太多了!好吧,我们把它缩短一点5.7cm。这肯定是正确的。总结一下:

在此处输入图片描述

相关内容