11

Based on this question: How to draw arrows between parts of an equation to show the Math Distributive Property (Multiplication)? I got some nice tools for illustrating to my students how to find the product of a number or a variable and a parenthesis.

However, the solution fails when I should have two sources in one line, for instance when expanding (a+3)(b+4). I would also be able to place a small number next to or above the arrowhead to indicate the first calculation, the second, etc. The second set of arrows could just as well go below the expression, not above it, to simplify things.

I could of course define myself a new set of macros similar to the existing ones, for instance \sourceTwo and \targetTwo, but it feels like this could be done more elegant.

MWE:

\documentclass[]{article}
\usepackage[utf8]{inputenc}
\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=45, -latex] {
        \foreach \i [evaluate=\i as \n using int(\i-1)] in {1,...,\thetarget} {
            \draw (source.north) to (target-\n.north);
        }
    }
}

\begin{document}

\begin{equation}
    (\source{a}+4)(\target{b}+\target{3}) = \drawarrows
\end{equation}

\end{document}
Holene
  • 6,920

3 Answers3

10

Just a more beautiful solution with PSTricks.

\documentclass[preview,border=1cm,12pt,varwidth]{standalone}
\usepackage{pst-node,amsmath}
\psset{nodesep=2pt,linearc=2pt,arrows=->,linecolor=blue,arrowinset=0}
\def\lbl#1{\ncput*{\text{\tiny #1}}}
\begin{document}
\abovedisplayskip=0pt\relax% don't use this line in your production
\[
(\rnode{A}{a}+\rnode{B}{b})(\rnode{C}{c}+\rnode{D}{d})=\ldots
\ncbar[angle=90,offsetA=-1pt]{A}{C}\lbl{1}
\ncbar[angle=90,offsetA=1pt,arm=16pt]{A}{D}\lbl{2}
\ncbar[angle=-90,offsetA=1pt]{B}{C}\lbl{3}
\ncbar[angle=-90,offsetA=-1pt,arm=16pt]{B}{D}\lbl{4}
\]
\end{document}

enter image description here

  • 1
    Oh, dude... That was an elegant solution. I'm not into pstricks though, but I'm going to try to adapt the style of the solution to TikZ – Holene Apr 03 '14 at 06:58
  • I cannot compile this code. I use texmaker and it said "undefined control sequence \ncbar...". How to fix it? – Kanegusa199 Jul 04 '18 at 23:41
7

The following code maybe a starting point for you:

\documentclass[]{article}
\usepackage[utf8]{inputenc}
\usepackage{tikz}

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

\newcounter{target}
\newcommand\target[1]{%
    \tikz[remember picture,baseline,inner sep=0pt] {%
        \node [name=target-\thetarget,anchor=base]{$#1$};
    }%
    \setcounter{source}{0}
    \stepcounter{target}%
}
\newcommand\drawarrows{
    \tikz[remember picture, overlay, bend left=45, -latex] {
    \foreach \j [evaluate=\j as \m using int(\j)] in {1,...,\thesource}{
        \foreach \i [evaluate=\i as \n using int(\i-1)] in {1,...,\thetarget} {
            \draw [red](source-0.north) to (target-\n.north) coordinate (UP);
          }
       \node [red] at (UP) [above] {1}; 
    }
}

 \tikz[remember picture, overlay, bend left=-45, -latex] {
    \foreach \j [evaluate=\j as \m using int(\j)] in {1,...,\thesource}{
        \foreach \i [evaluate=\i as \n using int(\i-1)] in {1,...,\thetarget} {
            \draw [blue](source-1.south) to (target-\n.south) coordinate (DOWN) ;
         }
        \node [blue] at (DOWN) [below] {2};
    }
}
}



\begin{document}

\begin{equation}
(\source{a}+\source{4})(\target{b}+\target{3})=\mbox{\drawarrows}
\end{equation}

\end{document}

Output:

enter image description here

Update: Labeling each arrow:

\documentclass[]{article}
\usepackage[utf8]{inputenc}
\usepackage{tikz,pgfplots}

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

\newcounter{target}
\newcommand\target[1]{%
    \tikz[remember picture,baseline,inner xsep=0pt] {%
        \node [name=target-\thetarget,anchor=base]{$#1$};
    }%
    \setcounter{source}{0}
    \stepcounter{target}%
}
\newcommand\drawarrows{
    \tikz[remember picture, overlay, bend left=45, -latex] {
    \foreach \j [evaluate=\j as \m using int(\j)] in {1,...,\thesource}{
        \foreach \i [evaluate=\i as \n using int(\i-1)] in {1,...,\thetarget} {
            \draw [red](source-0.north) to (target-\n.north) ;
              \node [red] at ([xshift=-5mm]target-\n.north) [above=2mm] {\i};
          }

    }
}

 \tikz[remember picture, overlay, bend left=-45, -latex] {
    \foreach \j [evaluate=\j as \m using int(\j)] in {1,...,\thesource}{
        \foreach \i [evaluate=\i as \n using int(\i-1)] in {1,...,\thetarget} {
            \draw [blue](source-1.south) to (target-\n.south)  ;
      \pgfmathsetmacro{\ii}{\i+2)};
         \node [blue] at ([xshift=-2mm]target-\n.south) [below=2mm] {\pgfmathprintnumber \ii};
    }
}
}}



\begin{document}

\begin{equation}
(\source{a}+\source{4})(\target{b}+\target{3})=\mbox{\drawarrows}
\end{equation}

\end{document}

and the output:

enter image description here

  • 1
    It might by better to set only inner x sep=0pt instead of inner sep=0pt, because right now the arrows "touch" the figures which doesn't look good in my opinion. – Henri Menke Apr 01 '14 at 21:59
  • @HenriMenke, you are right. My code is based on Holene's MWE. I didn't focused on details. –  Apr 01 '14 at 22:20
  • @ferahfeza This is sweet! Thank you, this solves my problem perfectly! I'm not quite understanding the way the code works though. How may I label each arrow (if its room for it)? – Holene Apr 02 '14 at 18:07
  • @Holene, yourwelcome. I will edit my answer for labeling. –  Apr 02 '14 at 18:28
  • @HenriMenke Thanks for the inner xsep and inner ysep suggestion. I totally agree! – Holene Apr 02 '14 at 18:34
  • @Holene, I update my answer. You can see the result. –  Apr 02 '14 at 18:50
  • I tried adding another equation like \source{a}(\target{b}+\target{2}). I get a pretty messy result.. http://grab.by/vHGu Somethings needs to be reset after drawing the arrows. – Holene Apr 02 '14 at 19:20
  • For second equation, try \begin{equation} \source{a} \source{}(\target{b}+\target{3})=\mbox{\drawarrows} \end{equation} and adjust [xshift=....] parameter for upper arrows. –  Apr 02 '14 at 19:30
  • @ferahfeza thumbs up – Holene Apr 02 '14 at 19:32
  • Is this correct that it does not work with (\source{6x}+\source{4}+\source{5a})(\target{2x}+\target{5}) ? So it only works with binomial * binomial? Or am I'm doing something wrong? – Arne Timperman Oct 28 '19 at 19:37
  • 1
    @ArneTimperman, right my code only for binomial * binomial. For your example, a new TiKz drawing code must be added, like \tikz[remember picture, overlay, bend left=-45, -latex] { \foreach \j [evaluate=\j as \m using int(\j)] in {1,2,...,\thesource}{ \foreach \i [evaluate=\i as \n using int(\i-1)] in {1,2,...,\thetarget} { \draw [orange](source-2.south) to (target-\n.south) ; \pgfmathsetmacro{\iii}{\i+4)}; \node [orange] at ([xshift=-2mm]target-\n.south) [below=5mm] {\pgfmathprintnumber \iii}; } } } –  Oct 28 '19 at 20:52
4

Another solution with pstricks, compilable with pdflatex, if you launch it with the --enable-write18 switch if you're under MiKTeX, or -shell-escape (TeX Live, MacTeX). Alternatively, you can compile with XeLaTeX:

\documentclass[12pt,a4paper]{article}
\usepackage[utf8]{inputenc}
\usepackage{mathtools}
\usepackage{amsfonts}
\usepackage{amssymb}
\usepackage{pst-node}
\usepackage{auto-pst-pdf}

\begin{document}

\Large
\begin{postscript}
  \begin{align*}
    (\rnode{X1}{2x}+\rnode{Y1}{\smash[b]{3y}})(\rnode{X2}{4x}+\rnode{Y2}{5y}) & = (2x)(4x)+(2x)(5y)+(3y)(4x)+(3y)(5y) \\
                                                                              & = 8x²+10xy+12xy+15y² \\
                                                                              & = 8x²+22xy+15y²
  \end{align*}
  \psset{angle=90,nodesep=2pt, arrows=<->, arrowinset=0.2}
  \ncbar[arm=15pt]{Y1}{Y2}\ncbar[border=1.5pt]{X1}{X2}
  \psset{angle=-90,nodesep=4pt}
  \ncbar{X1}{Y2}\ncbar[arm=8pt]{Y1}{X2}
\end{postscript}

\end{document} 

enter image description here

Bernard
  • 271,350