41

There is a part of my paper where I use the distributive property and it might not be clear to the reader to see the operation result (I'm using in proposional logic for a proof). The logic equation (part of) is:

$$ (l_{1}) \vee \big( (p \vee q) \wedge (\neg p \vee q) \wedge (p \vee \neg q) \wedge (\neg p \vee \neg q)\big) $$
$$ (l_{1} \vee p \vee q) \wedge (l_{1} \vee \neg p \vee q) \wedge (l_{1} \vee p \vee \neg q) \wedge (l_{1} \vee \neg p \vee \neg q) $$

So I was wondering if there is a way to represent this operation like a 'shower' (see another example in pic 1). Maybe there is some hidden magic mathmode command or pkg for this. At last we can also rely on tikz.

Distributive Property

1
  • 1
    As this has returned to the front page, I'll just take the opportunity to note that \tikzmark, which is used in a couple of answers, is now available in its own TikZ library: \usetikzlibrary{tikzmark} Commented Nov 22, 2020 at 10:07

4 Answers 4

21

The following uses pst-node from the pstricks bundle. So, you need to compile it with either latex -> dvips -> ps2pdf, or xelatex:

enter image description here

\documentclass{article}
\usepackage{amsmath}% http://ctan.org/pkg/amsmath
\usepackage{pst-node}% http://ctan.org/pkg/pst-node
\begin{document}
\[
  \begin{array}{c}
    \psDefBoxNodes{n1}{(l_{1})} \vee \big( 
      \psDefBoxNodes{n2}{(p \vee q)} \wedge 
      \psDefBoxNodes{n3}{(\neg p \vee q)} \wedge 
      \psDefBoxNodes{n4}{(p \vee \neg q)} \wedge 
      \psDefBoxNodes{n5}{(\neg p \vee \neg q)}\big) \\
    (l_{1} \vee p \vee q) \wedge (l_{1} \vee \neg p \vee q) \wedge (l_{1} \vee p \vee \neg q) \wedge (l_{1} \vee \neg p \vee \neg q)
  \end{array}
\]
\psset{nodesep=3pt,arcangle=15}
\ncarc{->}{n1:tC}{n2:tC}
\ncarc{->}{n1:tC}{n3:tC}
\ncarc{->}{n1:tC}{n4:tC}
\ncarc{->}{n1:tC}{n5:tC}
\end{document}

\psDefBoxNodes{<node>}{<stuff>} declares a special node <node> for <stuff>. Subsequently one can refer to the bounding box location of the node using character combinations. In the above example, <node>:tC refers to the top Center of <node>.

1
  • 1
    @Werner: If you put arrows = -> inside \psset you can avoid all the {->}s. Commented Oct 18, 2015 at 18:44
44

Adapted Solution:

Here is a version of the Basic Solution below adapted to your specific case:

enter image description here

\documentclass{article}
\usepackage{amsmath}

\usepackage{tikz}
\usetikzlibrary{calc,shapes}

\newcommand{\tikzmark}[1]{\tikz[overlay,remember picture] \node (#1) {};}
\newcommand{\DrawBox}[4]{%
  \begin{tikzpicture}[overlay,remember picture,-latex,shorten >=5pt,shorten <=5pt,out=70,in=130]
    \draw[distance=0.45cm,#1] (a.north) to (b.north);
    \draw[distance=0.65cm,#2] (a.north) to (c.north);
    \draw[distance=0.9cm, #3] (a.north) to (d.north);
    \draw[distance=1.1cm, #4] (a.north) to (e.north);
  \end{tikzpicture}
}
\begin{document}
\begin{gather*}
(\tikzmark{a}l_{1}) \vee \big( (p \vee\tikzmark{b} q) \wedge (\neg p \vee\tikzmark{c} q) \wedge (p \vee\tikzmark{d} \neg q) \wedge (\neg p \vee\tikzmark{e} \neg q)\big) \DrawBox{red}{blue}{green}{orange}\\
(l_{1} \vee p \vee q) \wedge (l_{1} \vee \neg p \vee q) \wedge (l_{1} \vee p \vee \neg q) \wedge (l_{1} \vee \neg p \vee \neg q)
\end{gather*}
\end{document}

Notes:


Basic Solution:

You can use tikz and the \tikzmark as defined in Arrow between parts of equation in LaTeX). Each endpoint of an arc is identified by \tikzmark, and the \DrawBox macro draws the arc between each of the nodes. The arc angle going out are adjusted by out=, and the incoming angle of the endpoint is specified by in=.

enter image description here

\documentclass{article}
\usepackage{amsmath}

\usepackage{tikz}
\usetikzlibrary{calc,shapes}


\newcommand{\tikzmark}[1]{\tikz[overlay,remember picture] \node (#1) {};}
\newcommand{\DrawBox}[2]{%
  \begin{tikzpicture}[overlay,remember picture]
    \draw[->,shorten >=5pt,shorten <=5pt,out=70,in=130,distance=0.5cm,#1] (MarkA.north) to (MarkC.north);
    \draw[->,shorten >=5pt,shorten <=5pt,out=50,in=140,distance=0.3cm,#2] (MarkA.north) to (MarkB.north);
  \end{tikzpicture}
}
\begin{document}
\begin{equation}
\tikzmark{MarkA}5 (x\tikzmark{MarkB} + 6\tikzmark{MarkC})\DrawBox{red}{blue}
\end{equation}
\end{document}
8
  • @FaheemMitha: There was a change in the standalone package. Chane to \documentclass{article}. Fixing solution now... Commented Nov 9, 2012 at 8:48
  • The basic version (bottom of post) does not work for me. I get ERROR: LaTeX Error: Bad math environment delimiter. Commented Nov 9, 2012 at 8:49
  • Funny, from emacs it does not work. The command it uses is pdflatex -shell-escape -interaction=nonstopmode "\input" peter.tex and with the command the arrows are wrong. Any idea why? Commented Nov 9, 2012 at 8:54
  • Did you run it twice? Opps., looks like I forgot my usual "Notes" section. Will update... Commented Nov 9, 2012 at 8:55
  • 1
    @Eugene: Just add a \tikzmark before the a term, and then \drawthe lines from this additional mark to the other terms. If you are still have trouble, let me know as in the second example above. Also see Better solution to display the Distributive Property. Commented Jan 19, 2015 at 3:25
26

Just to add something to the great answers already here: it's sometimes useful to have squared arrows instead of curved arrows. Here's an example of how you can do that. The same style could be applied to any of the other solutions here (with some minor tweaking of the anchors.)

\documentclass{article}
\usepackage{amsmath}
\usepackage{tikz}

\newcommand{\tikzmark}[1]{\tikz[overlay,remember picture] \node (#1) {};}
\tikzset{square arrow/.style={to path={-- ++(0,-.25) -| (\tikztotarget)}}}
\begin{document}

\begin{equation}
  a\tikzmark{a}x^2 + bx + c = 5\tikzmark{b}x^2 + bx + c.
  \tikz[overlay,remember picture]
   {\draw[->,square arrow] (a.south) to (b.south);}
\end{equation}

\end{document}

output of code

Response to comments

If you want to add a label text to the line you can do the following. A big thanks to Kpym for improving this code.

\documentclass{article}
\usepackage{amsmath}
\usepackage{tikz}

\newcommand{\tikzmark}[1]{\tikz[overlay,remember picture] \node (#1) {};}

\tikzset{square arrow/.style={
    to path={-- ++(0,-.25)  -| (\tikztotarget) \tikztonodes},below,pos=.25}}
\begin{document}

\begin{equation}
  a\tikzmark{a}x^2 + bx + c = 5\tikzmark{b}x^2 + bx + c.
  \tikz[overlay,remember picture]
   {\path[draw,->,square arrow] (a.south) to node{x} (b.south) ;
    }
\end{equation}

\end{document}

output of code

12
  • 3
    How can I put text midway of the line drawn?
    – azetina
    Commented Oct 13, 2012 at 2:55
  • I have the same question @azetina has. Using this method plus the cancel package would make really beautiful results. Commented Oct 16, 2015 at 18:35
  • 1
    @AlfredoHernández I've added way to add text to the line.
    – Alan Munn
    Commented Oct 17, 2015 at 4:36
  • @azetina A bit late, but I've added a way to add text to the line. :)
    – Alan Munn
    Commented Oct 17, 2015 at 4:36
  • Thanks a lot, Alan! It won't work with cancel in the way I had in mind, but this alone will do magnificently! Commented Oct 17, 2015 at 8:42
22

Here's something that might be slightly more comfortable to use if you need this regularly.

I've defined three new commands, \source, \target and \drawarrows. In your equation, replace the source term with \source{<source term>}, and each of the <target terms> with \target{<target term>}. After your equation, issue \drawarrows, and the arrows will be drawn. The solution uses TikZ overlay, which means you have to compile the document twice to get the placement right.

\documentclass{article}

\usepackage{tikz}

\newcommand\source[1]{%
    \tikz[remember picture,baseline,inner sep=0pt] {%
        \node [name=source,anchor=base]{$#1$};
    }%
    \setcounter{target}{0}
}

\newcounter{target}
\newcommand\target[1]{%
    \tikz[remember picture,baseline,inner sep=0pt] {%
        \node [name=target-\thetarget,anchor=base]{$#1$};
    }%
    \stepcounter{target}%
}

\newcommand\drawarrows{
    \tikz[remember picture, overlay, bend left=20, -latex] {
        \foreach \i [evaluate=\i as \n using int(\i-1)] in {1,...,\thetarget} {
            \draw (source.north) to (target-\n.north);
        }
    }
}


\begin{document}
$\source{(l_{1})}\vee \big( \target{(p \vee q)} \wedge \target{(\neg p \vee q)} \wedge \target{(p \vee \neg q)} \wedge \target{(\neg p \vee \neg q)}\big)$
\drawarrows
\end{document}
3
  • @Jake: I was just about to post that you should reset the counter at the end of \drawarrows so that if there is more than one use of this it still works, but somehow it appears as if that is not necessary. Am curious as to why? Let me know if I missed something obvious, of if it more involved I should probably most a new question. Commented Nov 22, 2011 at 5:00
  • @PeterGrill: The counter is reset at the end of \source. Hm, I wonder which place (end of \source or end of \drawarrows) makes more sense.
    – Jake
    Commented Nov 22, 2011 at 5:04
  • Ok, I guess my logic was doing to reset it at the end of \drawarrows, but I can't think of any downside of initializing at the start. Commented Nov 22, 2011 at 5:07

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .