Animated set intersection

The animate.sty package is a useful and fun tool for creating Javascript driven animations in PDF files. Brian S. Marks has already contributed an impressive animated statistical distribution example that demonstrates animate.sty. The following example is much simpler, but demonstrates a more general technique that is useful in conjunction with other tools as well.

The animation is a two step process:

  1. Creating the individual frames of the animation. Each frame becomes a page in a PDF file.
  2. Putting together the frames using animate.

The main reason we do it this way is because animate does not allow a \newframe inside PGF's \foreach command. This means that we can't put a \foreach loop around the parameterized picture inside the animateinline environment (we can use a \foreach for other purposes though).

Update: A standalone version of the example is now available that uses \whiledo to parameterize the picture.

Step 1. Creating the frames

The animation we will make demonstrates the set intersection operation. The code for drawing the sets is based on the venn diagram example. A foreach loop is used to draw a total of 21 frames, varying the x-coordinate of set B. The preview.sty package is used to crop every tikzpicture and put each picture/frame on a separate page.

setanim.tex (setanim.pdf) source:

% Animate a set intersection operation.
% The target document is a beamer presentation, so we load the
% beamer class to get the same fonts as in the presentation.
\documentclass{beamer}
\usepackage{tikz}
\usepackage[active,tightpage]{preview}
\PreviewEnvironment{tikzpicture}
\begin{document}
% define the bounding box
\def\boundb{(-2,2) rectangle (4,-2)}
% Create n frames with \xb as parameter
\foreach \xb in {0,0.1,...,2.1}{
    \def\setA{(0,0) circle (1)}
    \def\setB{(\xb,0) circle (1)}
    \begin{tikzpicture}
        \draw \boundb;
        % intersection
        \begin{scope}
            \clip \setA;
            \fill[black!20] \setB;
        \end{scope}
        \begin{scope}[even odd rule]% first circle without the second
            \clip \setB \boundb;
            \fill[red!20] \setA;
        \end{scope}
        \begin{scope}[even odd rule]% first circle without the second
            \clip \setA \boundb;
            \fill[blue!20] \setB;
        \end{scope}
        \draw \setA;
        \draw \setB;
        \node at (-1,0) [left] {$A$};
        \node at (\xb+1,0) [right] {$B$};
        \node at (4,2) [below left] {$A\cap B$};
    \end{tikzpicture}
}
\end{document}

The output from the above code is a the PDF setanim.pdf where each page contains a frame of the animation.

Step 2. Putting together the frames

The next step is to put the frames together and create an animation. There are different ways you can do this, but I will only demonstrate the animate.sty package. Some alternatives are:

  • Convert the pages in the PDF to bitmaps and put them together using video creation tools like ffmpeg, Blender and many others.
  • Use SWFTools' pdf2swf tool to create a Flash animation.

The animate package provides the command \animatedgraphics for creating animations based on a sequence of files or a multi-page PDF:

\animategraphics[<options>]{<frame rate>}{<file basename>}{<first>}{<last>}

See the documentation for an explanation of the available options and parameters. Here is the code for including the the frames:

\documentclass{beamer}
\usepackage{animate}
\begin{document}
\begin{frame}
    \frametitle{Set intersection}
    \begin{center}
        % Set frame rate to 12 frames/sec. Load frames from setanim.pdf.
        % We will use all frames, so there is no need to specify a start
        % and end frame.
        \animategraphics[autoplay,palindrome]{12}{animations/setanim}{}{}
    \end{center}
\end{frame}
\end{document}

Download the PDF to see the animation in action.

Note

Acrobat Reader v >= 6.0 is required to view this example.

A standalone version

The author of the animate package, Alexander Grahn, has contributed a version of the above example that does not require splitting the frames and the viewer in separate files:

\documentclass{beamer}
\usepackage{tikz}
\usepackage{animate}
\usepackage{fp}
% parameterized tikz graphics
\newcommand{\intersect}[1]{%
\def\setA{(0,0) circle (1)}%
\def\setB{(#1,0) circle (1)}%
% define the bounding box
\def\boundb{(-2,2) rectangle (4,-2)}%
%
\begin{tikzpicture}
    \draw \boundb;
    % intersection
    \begin{scope}
    \clip \setA;
    \fill[black!20] \setB;
    \end{scope}
    \begin{scope}[even odd rule]% first circle without the second
    \clip \setB \boundb;
    \fill[red!20] \setA;
    \end{scope}
    \begin{scope}[even odd rule]% first circle without the second
    \clip \setA \boundb;
    \fill[blue!20] \setB;
    \end{scope}
    \draw \setA;
    \draw \setB;
    \node at (-1,0) [left] {$A$};
    \node at (#1+1,0) [right] {$B$};
    \node at (4,2) [below left] {$A\cap B$};
\end{tikzpicture}
}
\begin{document}
\begin{frame}
\frametitle{Set intersection}
\begin{center}
    \begin{animateinline}[autoplay,palindrome]{12}
    %first frame, xb=0.0
    \gdef\xb{0}% xb initial value
    \intersect{\xb}%
    %remaining frames, xb=0.1...2.1
    \whiledo{\lengthtest{\xb pt < 2.1pt}}{%
        \newframe
        \FPeval{xb}{\xb+0.1}% new xb
        \xdef\xb{\xb}% make \xb global
        \intersect{\xb}%
    }%
    \end{animateinline}
\end{center}
\end{frame}
\end{document}


animated-set-intersection

Edit and compile if you like:

% Animated set intersection
%
% The animations can only be viewed in Acrobat (Reader) v >= 6.
\documentclass{beamer}
\usepackage{animate}


\begin{document}

\begin{frame}
    \frametitle{Set intersection}
    \begin{center}
        % Set frame rate to 12 frames/sec. Load frames from setanim.pdf.
        % We will use all frames, so there is no need to specify a start
        % and end frame.
        \animategraphics[autoplay,palindrome]{12}{animations/setanim}{}{}
    \end{center}
\end{frame}
\end{document}

Click to download: animated-set-intersection.texanimated-set-intersection.pdf
Open in Overleaf: animated-set-intersection.tex