[Tex/LaTex] How would you do Karnaugh’s maps in LaTeX or ConTeXt


In a document, I have to include those simple diagrams to show the procedure of reducing logical circuits.

What do you think is the best way to do them?

Best Answer

When I had to draw Karnaugh maps for my computer organization class, I use the colortbl package and colored individual cells; however, this got really bulky really quickly, and required coloring the intersections manually. Knowing what I do now, I'd use a TikZ matrix:



    \matrix (karnaugh) [matrix of math nodes] {
      1 & 0 & 1 & 1 \\
      1 & 0 & 0 & 1 \\
      1 & 0 & 1 & 1 \\
      1 & 1 & 0 & 1 \\
    } ;

    \foreach \i/\bits in {1/00,2/01,3/11,4/10} {
      \node [left  = 2mm of karnaugh-\i-1] {$\bits$} ;
      \node [above = 2mm of karnaugh-1-\i] {$\bits$} ;

    \node [left  = .6cm of karnaugh.west]  (BA) {$BA$} ;
    \node [above = .5cm of karnaugh.north] (DC) {$DC$} ;

    \draw    ($(DC.north       -| karnaugh.west)  + (-.75mm,0)$)
          -- ($(karnaugh.south -| karnaugh.west)  + (-.75mm,0)$)
             ($(BA.west        |- karnaugh.north) + (0,+.40mm)$)
          -- ($(karnaugh.east  |- karnaugh.north) + (0,+.40mm)$) ;

        \fill [red]
              (karnaugh-1-1.north west) rectangle (karnaugh-4-1.south east)
              (karnaugh-1-4.north west) rectangle (karnaugh-4-4.south east) ;
        \fill [blue]
              (karnaugh-1-3.north west) rectangle (karnaugh-1-4.south east) ;
        \fill [green]
              (karnaugh-3-3.north west) rectangle (karnaugh-3-4.south east) ;
        \fill [yellow]
              (karnaugh-4-1.north west) rectangle (karnaugh-4-2.south east) ;

This produces the following output:

Example Karnaugh map.

Oddly, the most complicated part of this solution is probably labeling the rows and columns with 00, etc., and drawing the separating vertical and horizontal lines. Other than that, things are pretty straightforward. The matrix of math nodes option tells TikZ to surround each entry in the matrix with \node {$ and $};. If you want to play with the spacing, you can use the row sep= and column sep= options. Next, I loop over each row/column index, and place the label a bit away from said row. Finally, I place the global labels further away. Drawing the edges uses the (pt-a -| pt-b) coordinate syntax, which says "place this point on the intersection of a horizontal line from pt-a and a vertical line from pt-b"; |- reverses which uses the horizontal line. Looking at that should make it clear why those were chosen; they draw the separating lines.

Finally, we draw the regions in the Karnaugh map. We work on the background layer (which was declared at the start of the document), and just surround each region with a semi-transparent colored rectangle. TikZ will handle the blending for us.

Edit: Since you requested a solution in LaTeX or ConTeXt, I should add that TikZ works with plain TeX, LaTeX, and ConTeXt, so this'll work in both cases. The TikZ manual tells you what needs to change when using ConTeXt (not much); if I recall, the environments mostly become \starttikzpicture/\stoptikzpicture pairs and the like, but I don't use ConTeXt, so I'm not sure.