algorithm2e + beamer 包中使用覆盖规范进行背景着色

algorithm2e + beamer 包中使用覆盖规范进行背景着色

我想在演示过程中突出显示幻灯片中的伪代码部分。在 PowerPoint 中很容易,我已经示例幻灯片

在此处输入图片描述

但是,我无法使用和包获得类似的效果beamertikzalgorithm2e

到目前为止,我已经定义了以下命令。

\newcommand<>{\myspot}[1]
{
\begin{tikzpicture}
        \node[draw=none,inner sep=0cm] (n1)
        {
            #1
        };
    \uncover#2{
        \draw (n1) node[rectangle,inner sep=0cm, fill=yellow] (n2)
        {
            #1
        };
    }
    \end{tikzpicture}
}

它非常有用,但只能突出显示我的代码中的一行。

\myspot<2>{
$pseudo_code here$
}

如何使用 实现示例幻灯片中所示的类似效果beamer

答案1

用于\tikzmark放置辅助节点和fit库,以及remember picture, overlay放置阴影的选项。一个小例子:

\documentclass{beamer}
\usepackage[ruled,vlined,linesnumbered]{algorithm2e}
\usepackage{tikz}
\usetikzlibrary{fit,calc}

\newcommand{\tikzmark}[1]{%
  \tikz[overlay,remember picture,baseline] \node [anchor=base] (#1) {};}

\definecolor{mybrown}{RGB}{255,218,195}
\definecolor{myframe}{RGB}{197,122,195}

\begin{document}

\begin{frame}

\begin{columns}
\column{.4\textwidth}
\onslide<2->{
\setlength\fboxsep{6pt}%
\framebox{\begin{tikzpicture}[x=0.8cm,init/.style={circle,fill=green!60!black,inner sep=2pt},
tran/.style={circle,fill=magenta!60!black,inner sep=3pt}]
\node<1,2,3>[init] at (0,0) (p) {};
\node<4>[tran] at (0,0) (p) {};
\node[init] at (1,-1) (q) {};
\node[init] at (3,-1) (r) {};
\node<1,2,4>[init] at (2.5,-2) (s) {};
\node<3>[tran] at (2.5,-2) (s) {};
\node[init] at (3.5,-3) (t) {};
\draw[blue] (p) -- (q) -- (r)  -- (s);
\draw[blue] (r) -- (t);
\end{tikzpicture}}
}

\column{.6\textwidth}
\begin{algorithm}[H]
\SetKwData{Left}{left}\SetKwData{This}{this}\SetKwData{Up}{up}
\SetKwFunction{Union}{Union}\SetKwFunction{FindCompress}{Find}
\SetKwInOut{Input}{input}\SetKwInOut{Output}{output}

\For{$i\leftarrow 2$ \KwTo $l$}
{
\emph{special treatment of $i$}\;
\For{$j\leftarrow 2$ \KwTo $w$}{\label{forins}
\Left$\leftarrow$ \FindCompress{$Im[i,j-1]$}\;
\tikzmark{a}\If(\tcp*[h]{}){\Left compatible \This}{\label{lt}
\lIf{\Left $<3$}{\Union{\Left}}\;
\lElse{\Union{\This,\Left}\tikzmark{b}\;}
}
\tikzmark{c}\If(\tcp*[h]{}){\Left compatible \This}{\label{lt1}
\lIf{\Left $<3$}{\Union{\Left}}\;
\lElse{\Union{\This,\Left}\tikzmark{d}\;}
}
}
\lForEach{element $e$ of the line $i$}{\FindCompress{p}}
}
\caption{disjoint decomposition}\label{algo_disjdecomp}
\end{algorithm}
\end{columns}

\begin{tikzpicture}[remember picture,overlay]
\coordinate (aa) at ($(a)+(0,0.2)$);
\coordinate (bb) at ($(b)+(1.2,0)$);
\node<3>[draw=myframe,line width=1pt,fill=mybrown,opacity=0.4,rectangle,rounded corners,fit=(aa) (bb)] {};
\coordinate (cc) at ($(c)+(0,0.2)$);
\coordinate (dd) at ($(d)+(1.2,0)$);
\node<4>[draw=myframe,line width=1pt,fill=mybrown,opacity=0.4,rectangle,rounded corners,fit=(cc) (dd)] {};
\end{tikzpicture}
\end{frame}

\end{document}

最终得到的四张幻灯片:

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


由 Andrew Stacey 添加

这是使用略有改进的 tikzmark这使得可以把盒子在后面文本。在做这件事时,我还添加了覆盖感知样式对于这两个节点,非跳跃图片因为节点大小变化时的小跳跃让我很烦恼(你需要编译代码才能看到这个效果,试着注释掉环境stop jumping中的键tikzpicture)。我发现\resetcounteronoverlays{algocf} 做过工作 - 除非我错过了什么。从好的方面来说,我摆脱了对fitcalc库的依赖。以下是完整代码:

\documentclass{beamer}
% \url{https://tex.stackexchange.com/q/51582/86}
%
% Using code from:
%  https://tex.stackexchange.com/a/6155/86 for overlay-aware styles
%  https://tex.stackexchange.com/a/50054/86 for advanced tikzmark
%  https://tex.stackexchange.com/q/18704/86 for the non-jumping pictures
\usepackage[ruled,vlined,linesnumbered]{algorithm2e}
\usepackage{tikz}
\makeatletter

\newcounter{jumping}
\resetcounteronoverlays{jumping}

\def\jump@setbb#1#2#3{%
  \@ifundefined{jump@#1@maxbb}{%
    \expandafter\gdef\csname jump@#1@maxbb\endcsname{#3}%
  }{%
    \csname jump@#1@maxbb\endcsname
    \pgf@xa=\pgf@x
    \pgf@ya=\pgf@y
    #3
    \pgfmathsetlength\pgf@x{max(\pgf@x,\pgf@xa)}%
    \pgfmathsetlength\pgf@y{max(\pgf@y,\pgf@ya)}%
    \expandafter\xdef\csname jump@#1@maxbb\endcsname{\noexpand\pgfpoint{\the\pgf@x}{\the\pgf@y}}%
  }
  \@ifundefined{jump@#1@minbb}{%
    \expandafter\gdef\csname jump@#1@minbb\endcsname{#2}%
  }{%
    \csname jump@#1@minbb\endcsname
    \pgf@xa=\pgf@x
    \pgf@ya=\pgf@y
    #2
    \pgfmathsetlength\pgf@x{min(\pgf@x,\pgf@xa)}%
    \pgfmathsetlength\pgf@y{min(\pgf@y,\pgf@ya)}%
    \expandafter\xdef\csname jump@#1@minbb\endcsname{\noexpand\pgfpoint{\the\pgf@x}{\the\pgf@y}}%
  }
}

\tikzset{%
  remember picture with id/.style={%
    remember picture,
    overlay,
    save picture id=#1,
  },
  save picture id/.code={%
    \edef\pgf@temp{#1}%
    \immediate\write\pgfutil@auxout{%
      \noexpand\savepointas{\pgf@temp}{\pgfpictureid}}%
  },
  if picture id/.code args={#1#2#3}{%
    \@ifundefined{save@pt@#1}{%
      \pgfkeysalso{#3}%
    }{
      \pgfkeysalso{#2}%
    }
  },
  onslide/.code args={<#1>#2}{%
    \only<#1>{\pgfkeysalso{#2}}%
  },
  alt/.code args={<#1>#2#3}{%
    \alt<#1>{\pgfkeysalso{#2}}{\pgfkeysalso{#3}}%
  },
  stop jumping/.style={
    execute at end picture={%
      \stepcounter{jumping}%
      \immediate\write\pgfutil@auxout{%
        \noexpand\jump@setbb{\the\value{jumping}}{\noexpand\pgfpoint{\the\pgf@picminx}{\the\pgf@picminy}}{\noexpand\pgfpoint{\the\pgf@picmaxx}{\the\pgf@picmaxy}}
      },
      \csname jump@\the\value{jumping}@maxbb\endcsname
      \path (\the\pgf@x,\the\pgf@y);
      \csname jump@\the\value{jumping}@minbb\endcsname
      \path (\the\pgf@x,\the\pgf@y);
    },
  }
}


\def\savepointas#1#2{%
  \expandafter\gdef\csname save@pt@#1\endcsname{#2}%
}

\def\tmk@labeldef#1,#2\@nil{%
  \def\tmk@label{#1}%
  \def\tmk@def{#2}%
}

\tikzdeclarecoordinatesystem{pic}{%
  \pgfutil@in@,{#1}%
  \ifpgfutil@in@%
    \tmk@labeldef#1\@nil
  \else
    \tmk@labeldef#1,\pgfpointorigin\@nil
  \fi
  \@ifundefined{save@pt@\tmk@label}{%
    \tikz@scan@one@point\pgfutil@firstofone\tmk@def
  }{%
  \pgfsys@getposition{\csname save@pt@\tmk@label\endcsname}\save@orig@pic%
  \pgfsys@getposition{\pgfpictureid}\save@this@pic%
  \pgf@process{\pgfpointorigin\save@this@pic}%
  \pgf@xa=\pgf@x
  \pgf@ya=\pgf@y
  \pgf@process{\pgfpointorigin\save@orig@pic}%
  \advance\pgf@x by -\pgf@xa
  \advance\pgf@y by -\pgf@ya
  }%
}
\newcommand\tikzmark[2][]{%
\tikz[remember picture with id=#2] #1;}
\makeatother

\definecolor{mybrown}{RGB}{255,218,195}
\definecolor{myframe}{RGB}{197,122,195}

\resetcounteronoverlays{algocf}

\newcommand<>{\boxto}[1]{%
\only#2{\tikz[remember picture,overlay]
\draw[myframe,line width=1pt,fill=mybrown,,rectangle,rounded corners]
(pic cs:#1) ++(1.4,-.25) rectangle (-.2,0.4)
;}%
}


\begin{document}

\begin{frame}
\begin{columns}
\column{.4\textwidth}
\onslide<2->{
\setlength\fboxsep{6pt}%
\framebox{\begin{tikzpicture}[
      x=0.8cm,
      init/.style={circle,fill=green!60!black,inner sep=2pt},
      tran/.style={circle,fill=magenta!60!black,inner sep=3pt},
      stop jumping
    ]
\node[alt=<4>{tran}{init}] at (0,0) (p) {};
\node[init] at (1,-1) (q) {};
\node[init] at (3,-1) (r) {};
\node[alt=<3>{tran}{init}] at (2.5,-2) (s) {};
\node[init] at (3.5,-3) (t) {};
\draw[blue] (p) -- (q) -- (r)  -- (s);
\draw[blue] (r) -- (t);
\end{tikzpicture}}
}

\column{.6\textwidth}
\begin{algorithm}[H]
\SetKwData{Left}{left}\SetKwData{This}{this}\SetKwData{Up}{up}
\SetKwFunction{Union}{Union}\SetKwFunction{FindCompress}{Find}
\SetKwInOut{Input}{input}\SetKwInOut{Output}{output}

\For{$i\leftarrow 2$ \KwTo $l$}
{
\emph{special treatment of $i$}\;
\For{$j\leftarrow 2$ \KwTo $w$}{\label{forins}
\Left$\leftarrow$ \FindCompress{$Im[i,j-1]$}\;
\boxto<3>{b}\If(\tcp*[h]{}){\Left compatible \This}{\label{lt}
\lIf{\Left $<3$}{\Union{\Left}}\;
\lElse{\Union{\This,\Left}\tikzmark{b}\;}
}
\boxto<4>{d}\If(\tcp*[h]{}){\Left compatible \This}{\label{lt1}
\lIf{\Left $<3$}{\Union{\Left}}\;
\lElse{\Union{\This,\Left}\tikzmark{d}\;}
}
}
\lForEach{element $e$ of the line $i$}{\FindCompress{p}}
}
\caption{disjoint decomposition}\label{algo_disjdecomp}
\end{algorithm}
\end{columns}

\end{frame}

\end{document}

第一张幻灯片包含突出显示的代码 第二张幻灯片,突出显示了代码 第三张幻灯片突出显示了代码 第四张幻灯片,突出显示代码

相关内容