34

I've been using LaTeX for a couple of years, but I'm pretty new to the tikz package. In particular, I'd like to add Karnaugh's maps in my document. I've already found a solution that satisfy me (can be found here: How would you do Karnaugh's maps in LaTeX or ConTeXt?), and I'd like to slightly adjust it to make the boolean params appear at the very first cell which I want it to be diagonally split like in this example: Remove vertical lines for table.

Would anybody help me? Thanks in advance!

Driu
  • 1,069

2 Answers2

58

I've added a filling color to the code proposed on remove vertical lines for table. It works well for all groups although I must admit that \implicantcantons (group 4 corners on a 16 positions map) needs some improvement.

EDIT: I've also added a 2x2 Karnaugh map and command \implicantsol to mark isolated elements.

EDIT 2: Solved the problem with \implicantcantons. Now four corners groups are correctly filled. First example has no sense, it just shows several grouping options.

enter image description here

\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{matrix,calc}

%isolated term
%#1 - Optional. Space between node and grouping line. Default=0
%#2 - node
%#3 - filling color
\newcommand{\implicantsol}[3][0]{
    \draw[rounded corners=3pt, fill=#3, opacity=0.3] ($(#2.north west)+(135:#1)$) rectangle ($(#2.south east)+(-45:#1)$);
    }


%internal group
%#1 - Optional. Space between node and grouping line. Default=0
%#2 - top left node
%#3 - bottom right node
%#4 - filling color
\newcommand{\implicant}[4][0]{
    \draw[rounded corners=3pt, fill=#4, opacity=0.3] ($(#2.north west)+(135:#1)$) rectangle ($(#3.south east)+(-45:#1)$);
    }

%group lateral borders
%#1 - Optional. Space between node and grouping line. Default=0
%#2 - top left node
%#3 - bottom right node
%#4 - filling color
\newcommand{\implicantcostats}[4][0]{
    \draw[rounded corners=3pt, fill=#4, opacity=0.3] ($(rf.east |- #2.north)+(90:#1)$)-| ($(#2.east)+(0:#1)$) |- ($(rf.east |- #3.south)+(-90:#1)$);
    \draw[rounded corners=3pt, fill=#4, opacity=0.3] ($(cf.west |- #2.north)+(90:#1)$) -| ($(#3.west)+(180:#1)$) |- ($(cf.west |- #3.south)+(-90:#1)$);
}

%group top-bottom borders
%#1 - Optional. Space between node and grouping line. Default=0
%#2 - top left node
%#3 - bottom right node
%#4 - filling color
\newcommand{\implicantdaltbaix}[4][0]{
    \draw[rounded corners=3pt, fill=#4, opacity=0.3] ($(cf.south -| #2.west)+(180:#1)$) |- ($(#2.south)+(-90:#1)$) -| ($(cf.south -| #3.east)+(0:#1)$);
    \draw[rounded corners=3pt, fill=#4, opacity=0.3] ($(rf.north -| #2.west)+(180:#1)$) |- ($(#3.north)+(90:#1)$) -| ($(rf.north -| #3.east)+(0:#1)$);
}

%group corners
%#1 - Optional. Space between node and grouping line. Default=0
%#2 - filling color
\newcommand{\implicantcantons}[2][0]{
    \draw[rounded corners=3pt, opacity=.3] ($(rf.east |- 0.south)+(-90:#1)$) -| ($(0.east |- cf.south)+(0:#1)$);
    \draw[rounded corners=3pt, opacity=.3] ($(rf.east |- 8.north)+(90:#1)$) -| ($(8.east |- rf.north)+(0:#1)$);
    \draw[rounded corners=3pt, opacity=.3] ($(cf.west |- 2.south)+(-90:#1)$) -| ($(2.west |- cf.south)+(180:#1)$);
    \draw[rounded corners=3pt, opacity=.3] ($(cf.west |- 10.north)+(90:#1)$) -| ($(10.west |- rf.north)+(180:#1)$);
    \fill[rounded corners=3pt, fill=#2, opacity=.3] ($(rf.east |- 0.south)+(-90:#1)$) -|  ($(0.east |- cf.south)+(0:#1)$) [sharp corners] ($(rf.east |- 0.south)+(-90:#1)$) |-  ($(0.east |- cf.south)+(0:#1)$) ;
    \fill[rounded corners=3pt, fill=#2, opacity=.3] ($(rf.east |- 8.north)+(90:#1)$) -| ($(8.east |- rf.north)+(0:#1)$) [sharp corners] ($(rf.east |- 8.north)+(90:#1)$) |- ($(8.east |- rf.north)+(0:#1)$) ;
    \fill[rounded corners=3pt, fill=#2, opacity=.3] ($(cf.west |- 2.south)+(-90:#1)$) -| ($(2.west |- cf.south)+(180:#1)$) [sharp corners]($(cf.west |- 2.south)+(-90:#1)$) |- ($(2.west |- cf.south)+(180:#1)$) ;
    \fill[rounded corners=3pt, fill=#2, opacity=.3] ($(cf.west |- 10.north)+(90:#1)$) -| ($(10.west |- rf.north)+(180:#1)$) [sharp corners] ($(cf.west |- 10.north)+(90:#1)$) |- ($(10.west |- rf.north)+(180:#1)$) ;
}

%Empty Karnaugh map 4x4
\newenvironment{Karnaugh}%
{
\begin{tikzpicture}[baseline=(current bounding box.north),scale=0.8]
\draw (0,0) grid (4,4);
\draw (0,4) -- node [pos=0.7,above right,anchor=south west] {cd} node [pos=0.7,below left,anchor=north east] {ab} ++(135:1);
%
\matrix (mapa) [matrix of nodes,
        column sep={0.8cm,between origins},
        row sep={0.8cm,between origins},
        every node/.style={minimum size=0.3mm},
        anchor=8.center,
        ampersand replacement=\&] at (0.5,0.5)
{
                       \& |(c00)| 00         \& |(c01)| 01         \& |(c11)| 11         \& |(c10)| 10         \& |(cf)| \phantom{00} \\
|(r00)| 00             \& |(0)|  \phantom{0} \& |(1)|  \phantom{0} \& |(3)|  \phantom{0} \& |(2)|  \phantom{0} \&                     \\
|(r01)| 01             \& |(4)|  \phantom{0} \& |(5)|  \phantom{0} \& |(7)|  \phantom{0} \& |(6)|  \phantom{0} \&                     \\
|(r11)| 11             \& |(12)| \phantom{0} \& |(13)| \phantom{0} \& |(15)| \phantom{0} \& |(14)| \phantom{0} \&                     \\
|(r10)| 10             \& |(8)|  \phantom{0} \& |(9)|  \phantom{0} \& |(11)| \phantom{0} \& |(10)| \phantom{0} \&                     \\
|(rf) | \phantom{00}   \&                    \&                    \&                    \&                    \&                     \\
};
}%
{
\end{tikzpicture}
}

%Empty Karnaugh map 2x4
\newenvironment{Karnaughvuit}%
{
\begin{tikzpicture}[baseline=(current bounding box.north),scale=0.8]
\draw (0,0) grid (4,2);
\draw (0,2) -- node [pos=0.7,above right,anchor=south west] {bc} node [pos=0.7,below left,anchor=north east] {a} ++(135:1);
%
\matrix (mapa) [matrix of nodes,
        column sep={0.8cm,between origins},
        row sep={0.8cm,between origins},
        every node/.style={minimum size=0.3mm},
        anchor=4.center,
        ampersand replacement=\&] at (0.5,0.5)
{
                      \& |(c00)| 00         \& |(c01)| 01         \& |(c11)| 11         \& |(c10)| 10         \& |(cf)| \phantom{00} \\
|(r00)| 0             \& |(0)|  \phantom{0} \& |(1)|  \phantom{0} \& |(3)|  \phantom{0} \& |(2)|  \phantom{0} \&                     \\
|(r01)| 1             \& |(4)|  \phantom{0} \& |(5)|  \phantom{0} \& |(7)|  \phantom{0} \& |(6)|  \phantom{0} \&                     \\
|(rf) | \phantom{00}  \&                    \&                    \&                    \&                    \&                     \\
};
}%
{
\end{tikzpicture}
}

%Empty Karnaugh map 2x2
\newenvironment{Karnaughquatre}%
{
\begin{tikzpicture}[baseline=(current bounding box.north),scale=0.8]
\draw (0,0) grid (2,2);
\draw (0,2) -- node [pos=0.7,above right,anchor=south west] {b} node [pos=0.7,below left,anchor=north east] {a} ++(135:1);
%
\matrix (mapa) [matrix of nodes,
        column sep={0.8cm,between origins},
        row sep={0.8cm,between origins},
        every node/.style={minimum size=0.3mm},
        anchor=2.center,
        ampersand replacement=\&] at (0.5,0.5)
{
          \& |(c00)| 0          \& |(c01)| 1  \\
|(r00)| 0 \& |(0)|  \phantom{0} \& |(1)|  \phantom{0} \\
|(r01)| 1 \& |(2)|  \phantom{0} \& |(3)|  \phantom{0} \\
};
}%
{
\end{tikzpicture}
}

%Defines 8 or 16 values (0,1,X)
\newcommand{\contingut}[1]{%
\foreach \x [count=\xi from 0]  in {#1}
     \path (\xi) node {\x};
}

%Places 1 in listed positions
\newcommand{\minterms}[1]{%
    \foreach \x in {#1}
        \path (\x) node {1};
}

%Places 0 in listed positions
\newcommand{\maxterms}[1]{%
    \foreach \x in {#1}
        \path (\x) node {0};
}

%Places X in listed positions
\newcommand{\indeterminats}[1]{%
    \foreach \x in {#1}
        \path (\x) node {X};
}

\begin{document}
    \begin{Karnaugh}
        \contingut{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}
       \implicant{0}{2}{red}
       \implicant{5}{15}{purple}
       \implicantdaltbaix[3pt]{3}{10}{blue}
    \implicantcantons[2pt]{orange}
       \implicantcostats{4}{14}{green}
    \end{Karnaugh}
    %
    \begin{Karnaughvuit}
       \minterms{3,4}
        \maxterms{0,1,6,7}
       \indeterminats{2,5}
       \implicant{3}{2}{green}
       \implicant{4}{5}{}
    \end{Karnaughvuit}
    %
    \begin{Karnaughquatre}
        \minterms{1,2}
       \maxterms{0,3}
       \implicantsol{1}{green}
       \implicantsol{2}{red}
    \end{Karnaughquatre}

\end{document}
Ignasi
  • 136,588
  • 1
    Wow, I must admit that this is so much more than I expected, thank you! Just a last question: could you give me some indication about how to draw the K-map for two variables? Sorry for this request, I tried to modify your code to make it by myself, but the result was simply messy! :) – Driu Oct 25 '13 at 09:53
  • @QAndy I've updated the answer. Glad to help you. – Ignasi Oct 25 '13 at 10:20
  • This is excellent! could some please show how to make these translucent? changing the opacity number in \draw doesn't seem to have an effect.. – sfranky Jun 28 '14 at 08:16
  • @sfranky What do you mean for translucent? opacity=0 means completely transparent and opacity=1 completely opaque. If you want cell contains be shown over filling color, change command order inside maps: first groupd (implicant...) and later values (minterms, maxterms, ...) – Ignasi Jun 28 '14 at 09:10
  • By translucent I meant not completely transparent (0<x<1). I had to do what you suggest anyway, otherwise i was just getting boxes with no numbers on them. The problem I have is that when two or more boxes overlap, there is a lower layer and an upper layer, and the upper layer is hiding the lower layer, whereas I'd prefer both to be shown. But changing opacity doesn't have any effect! – sfranky Jun 28 '14 at 09:40
  • 1
    @sfranky If you're using pdflatex and the posted code, the result should be like my figure. May be you have some outdated file. – Ignasi Jun 28 '14 at 09:56
  • 1
    It turns out it was clashing with package Transparent (I don't even remember why that was there!). – sfranky Jun 28 '14 at 10:27
  • @Ignasi I have the same problem with the transparency as @sfranky but I have to use the the package \usepackage{transparent} is there a method to get your code working with both packages included? – kimliv Jan 21 '16 at 12:00
  • @kimliv I've tested and transparent breaks TiKZ transparency. I don't know what happens so I think a new question (if it's not already answered here) about this problem could be pertinent. – Ignasi Jan 21 '16 at 12:06
  • @kimliv: I've found this: http://tex.stackexchange.com/a/253417/1952. It explains that transparent and TikZ are incompatible, but provides a workarround which I've not testet. I hope it helps. – Ignasi Jan 21 '16 at 16:57
33

Some days ago (Nov. 26), Mat­tias Ja­cob­s­son uploaded his karnaugh-map package to CTAN. Now instead of the code in my alternative answer you can use a real package.

karnaugh-map is also based in TikZ and can draw maps from two to six variables, being four the number for the default map. Maps for five and six variables are drawn with two (or four) four variables submaps. implicant commands can specify to which submap apply.

Following code shows some examples using this new tool.

\documentclass[tikz, border=2mm]{standalone}
\usepackage{karnaugh-map}

\begin{document}
    \begin{karnaugh-map}
        \manualterms{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}
        \implicant{0}{2}
        \implicant{5}{15}
        \implicantedge{1}{3}{9}{11}
        \implicantcorner
        \implicantedge{4}{12}{6}{14}
    \end{karnaugh-map}

    \begin{karnaugh-map}[4][2][1][$X_1X_0$][$X_2$]
        \minterms{3,4}
        \maxterms{0,1,6,7}
        \indeterminants{2,5}
        \implicant{3}{2}
        \implicant{4}{5}
    \end{karnaugh-map}

    \begin{karnaugh-map}[2][2][1][$b$][$a$]
        \minterms{1,2}
        \maxterms{0,3}
        \implicant{1}{1}
        \implicant{2}{2}
    \end{karnaugh-map}

    \begin{karnaugh-map}[4][4][4]
        \implicant{0}{0}[0,1,2,3]
    \end{karnaugh-map}
\end{document}

enter image description here

enter image description here

Ignasi
  • 136,588
  • 1
    Amazing! After installing package xstring this worked like a charm. – Matthias Braun Sep 25 '19 at 11:02
  • This seems to fail with \begin{karnaugh-map}[4][8][1] for 5 variables although the doc says it can draw up to 6 variables while tikz-karnaugh works for 5 variables. – An5Drama Feb 13 '24 at 08:34