How to Generate All Possible Venn Diagrams Efficiently – TikZ-PGF and PStricks

pstrickstikz-pgfvenn-diagrams

I can draw Venn diagrams but now my question is more complicated than just drawing Venn diagrams one by one. I need to draw all possible Venn diagrams efficiently. I need a combinatorical approach because there are 256 combinations.

Let's choose the following sets as the case to consider. The binary number labels are used to uniquely identified each "atomic" region. My definition: An atomic region does not contain any smaller region.

Because there are 8 atomic regions, each can be either selected or not to compose a new compound region. Therefore there are 2^8 ways.

How to generate all possible Venn diagrams (with the case above) efficiently?

enter image description here

The objective is to produce 256 Venn diagrams, each diagram has a unique colored compound region that has an associated set operation.

Let's use 8-bit integer to represent each diagram.

The first bit (the most left bit or the most significant bit) represents the region 000.

The second bit represents the region 100.

The least significant bit represents the region 111.

Bit 0 represent not-join to produce a new compound region. And 1 otherwise.

If the first diagram with the complement of AuBuC then its binary representation is 1000 0000. 1111 1111 represents S. Etc etc etc!

The Problem Sheet

The problem sheet will ask the student to find a set operation (not necessarily unique) for each RED COMPOUND region in each diagram below.

enter image description here
enter image description here
enter image description here

Best Answer

Right, here's some code:

\documentclass{standalone}
%\url{https://tex.stackexchange.com/q/67395/86}
\usepackage{tikz}

\makeatletter

\def\venn@strip#1#2\venn@STOP{%
  \def\venn@next{#1}%
  \gdef\venn@rest{#2}%
}

\newcommand{\venn}[1]{%
\begin{tikzpicture}
\coordinate (A) at (0,0);
\coordinate (B) at (2,0);
\coordinate (C) at (1,{sqrt(3)});
\coordinate (S-SE) at (5,-3);
\coordinate (S-NW) at (-3,{sqrt(3)+3});
  \edef\venn@rest{#100000000}%
  \foreach \i in {0,...,7} {
  \begin{scope}[even odd rule]
    \expandafter\venn@strip\venn@rest\venn@STOP
    \ifnum\venn@next=1\relax
    \pgfmathparse{Mod(\i,2) == 1 ? "(S-SE) rectangle (S-NW)" : ""}
    \path[clip] \pgfmathresult (A) circle[radius=2];
    \pgfmathparse{Mod(floor(\i/2),2) == 1 ? "(S-SE) rectangle (S-NW)" : ""}
    \path[clip] \pgfmathresult (B) circle[radius=2];
    \pgfmathparse{Mod(floor(\i/4),2) == 1 ? "(S-SE) rectangle (S-NW)" : ""}
    \path[clip] \pgfmathresult (C) circle[radius=2];
    \fill[rounded corners,red] (S-SE) rectangle (S-NW);
    \fi
  \end{scope}
  }
    \draw[ultra thick] (A) circle[radius=2];
    \draw[ultra thick] (B) circle[radius=2];
    \draw[ultra thick] (C) circle[radius=2];
    \draw[ultra thick,rounded corners] (S-SE) rectangle (S-NW);
\end{tikzpicture}
}

\makeatother

\newcommand{\allvendiagrams}{
% To generate the lot:
\foreach \j in {0,...,255} {
  \def\venncode{}
  \foreach \k in {0,...,7} {
    \pgfmathparse{Mod(floor(\j/2^\k),2) == 1 ? "\venncode1" : "\venncode0"}
    \global\let\venncode=\pgfmathresult
  }
  \venn{\venncode}

}
}

\begin{document}
\venn{10000000}
\venn{01000000}
\venn{11000000}
\end{document}

And here's the result:

Sample venn diagrams

I almost certainly have used a different code for the different regions - I went for simpler code. The rubric is that a 1 in the kth place fills the kth region, and the correspondence between labels and regions is to write out k as a binary number, then if the bit is set, that circle is used inside and if not, outside. At the end, we draw the region and circles on top. I haven't gone for much customisability, but hopefully it's fairly obvious what to change to get it to look different.

Edit from the questioner: By using \documentclass[border=3pt,tikz]{standalone} and invoking \allvendiagrams instead of \venn{10000000}\venn{01000000}\venn{11000000}, the output will show all the Venn diagrams as follows. But not in GIF for sure.

enter image description here