How does one draw a momentum arrow along a line in feynmf?

When drawing a Feynman diagram, one often wants to label each line and draw the momentum arrows. How can one draw a satisfactory momentum arrow? Take for example electron-muon scattering, where I've tried to draw arrows myself by putting them in the labels.

\begin{fmfgraph*}(40,25)
\fmfleftn{i}{2}
\fmfrightn{o}{2}
\fmf{fermion,label=$\longrightarrow$}{i1,v1,o1}
\fmf{fermion}{i2,v2,o2}
\fmf{photon,label=$\gamma$}{v1,v2}
\fmfdotn{v}{2}
\fmflabel{$e^-$}{i1}
\fmflabel{$e^-$}{o1}
\fmflabel{$\mu^-$}{i2}
\fmflabel{$\mu^-$}{o2}
\end{fmfgraph*}


The result is silly at most:

If this would be done properly, there would be an arrow parallel to the line, next (in the direction orthogonal to the line and arrow) to which there would be a text like $p_i$. How could this be achieved?

If you don't mind switching to plain Metapost syntax, and making your graphic into an external file, you can import the feynmp definitions and use them in a regular MP diagram. This provides a simple way to do diagrams with layouts that the standard bits of feynmf don't support.

Here's my first attempt at what you describe above.

which was produced with this MP input:

prologues := 3;
outputtemplate := "%j%c.eps";

input feynmp

beginfig(1);

z1 = -z2 = 20 up;
z3 = (-60,40);

draw fermion z3 -- z1;
draw fermion z5 -- z2;
draw fermion z1 -- z4;
draw fermion z2 -- z6;
draw photon  z1 -- z2;

label.lft(btex $\gamma$ etex, .5[z1,z2]);

label.ulft(btex $\mu^-$ etex, z3);
label.urt (btex $\mu^-$ etex, z4);

label.llft(btex $e^-$ etex, z5);
label.lrt (btex $e^-$ etex, z6);

fill fullcircle scaled 4 shifted z1;
fill fullcircle scaled 4 shifted z2;

path a[];

a1 = subpath (0.3,0.6) of (z5--z2) shifted 8 up;
drawarrow a1; label.top(btex $p_i$ etex, point .5 of a1);

a2 = subpath (0.4,0.7) of (z2--z6) shifted 8 up;
drawarrow a2; label.top(btex $p_i$ etex, point .5 of a2);

endfig;
end.


However if you would prefer to stick more closely to your original input, then you can use an fmfcmd to add a new line style to add the momentum arrows. Like this:

\begin{fmfgraph*}(120,55)
\fmfleftn{i}{2}
\fmfrightn{o}{2}
\fmf{fermion}{i1,v1,o1}
\fmf{fermion}{i2,v2,o2}
\fmf{photon,label=$\gamma$}{v1,v2}
\fmfdotn{v}{2}
\fmflabel{$e^-$}{i1}
\fmflabel{$e^-$}{o1}
\fmflabel{$\mu^-$}{i2}
\fmflabel{$\mu^-$}{o2}
\fmffreeze
\fmfcmd{style_def marrow expr p = drawarrow subpath (1/4, 3/4) of p shifted 6 up
withpen pencircle scaled 0.4; label.top(btex $p_i$ etex, point 0.5 of p
shifted 6 up); enddef;}
\fmf{marrow}{i1,v1,o1}
\end{fmfgraph*}


which produces this:

Note that the fmffreeze stops the extra connections messing up the layout. And I freely admit that the labels are a bit of a hack.

To produce this output, by the way, I found it convenient to put the fmfgraph into a LaTeX file like this:

\documentclass{article}
\usepackage{feynmp-auto}
\begin{document}
\begin{fmffile}{first}
\begin{fmfgraph*}(120,55)
... graph commands here ...
\end{fmfgraph*}
\end{fmffile}
\end{document}


Note that I had to change the size of the OP to something that came out readable on my system.

• Especially the \fmfcmd approach is beautiful here. There are two problems though. One, you can only have one text. For example, when making the command \newcommand{\marrow}[2]{\fmfcmd{style_def marrow expr p = drawarrow subpath (1/4, 3/4) of p shifted 6 up withpen pencircle scaled 0.4; label.top(btex #1 etex, point 0.5 of p shifted 6 up); enddef;} \fmf{marrow}{#2}} and calling \marrow{$p_1$}{i1,v1}\marrow{$p_2$}{v1,o1}, the text p_2 is shown with both lines. Second, it doesn't work on vertical lines. Any thoughts on a possible solution (my Metapost is terrible)? Oct 12 '14 at 21:02
• The first problem could be solved by giving the arrows names through \newcommand{\marrow}[3]{\fmfcmd{style_def marrow#1 expr p = drawarrow subpath (1/4, 3/4) of p shifted 6 up withpen pencircle scaled 0.4; label.top(btex #2 etex, point 0.5 of p shifted 6 up); enddef;} \fmf{marrow#1}{#3}} and \marrow{a}{$p_1$}{i1,v1}\marrow{b}{$p_2$}{v1,o1}. But this is far from best practice, and should only be used as last resort by lack of a better solution. Oct 12 '14 at 21:12
• Or you could simply define another line style with the different text, but again this is a bit of a hack. Oct 12 '14 at 21:14
• Similarly, for vertical lines, define another line style replacing up with left... Oct 12 '14 at 21:14
• Or learn plain Metapost :-) (or even TikZ...) Oct 12 '14 at 21:16

Just to recapitulate the discussion that arose underneath Thruston's answer, here's a somewhat hacky approach to drawing momentum arrows next to lines in Feynman diagrams.

The command \marrow, essentially a combination of \fmfcmd (definition of a new style) and fmf (drawing an arrow with this style) is defined with 5 arguments:

\marrow{name}{arrow_pos}{text_pos}{text}{nodes}


The first argument is needed since essentially a new style is created for each arrow (letter symbols only), the second is any of up, down, left, right, the third is any of top, bot, lft, rt, the fourth is your text and the fifth is a list of nodes or vertices in your Feynman diagram (e.g. i1,v1).

A MWE is the following.

\documentclass{article}
\usepackage{feynmp-auto}
\newcommand{\marrow}[5]{%
\fmfcmd{style_def marrow#1
expr p = drawarrow subpath (1/4, 3/4) of p shifted 6 #2 withpen pencircle scaled 0.4;
label.#3(btex #4 etex, point 0.5 of p shifted 6 #2);
enddef;}
\fmf{marrow#1,tension=0}{#5}}
\begin{document}
\setlength{\unitlength}{1mm}
\begin{fmffile}{marrows}
\begin{fmfgraph*}(50,30)
\fmfleftn{i}{2}
\fmfrightn{o}{2}
\fmf{fermion}{i1,v1,o1}
\fmf{fermion}{i2,v2,o2}
\fmf{photon,label=$\gamma$}{v1,v2}
\fmfdotn{v}{2}
\fmflabel{$e^-$}{i1}
\fmflabel{$e^-$}{o1}
\fmflabel{$\mu^-$}{i2}
\fmflabel{$\mu^-$}{o2}
% Momentum arrows
\marrow{a}{down}{bot}{$p_1$}{i1,v1}
\marrow{b}{up}{top}{$p_2$}{i2,v2}
\marrow{c}{left}{lft}{$q$}{v1,v2}
\marrow{d}{down}{bot}{$p_3$}{v1,o1}
\marrow{e}{up}{top}{$p_4$}{v2,o2}
\end{fmfgraph*}
\end{fmffile}
\end{document}


With output:

The lines in \marrow are given tension 0 to prevent them from influencing the shape of the graph (Thruston's initial approach was calling \fmffreeze before the inclusion of the arrows, but I think it is best practice to avoid that command as one might want to continue adding lines and vertices after the momentum arrows are drawn).

For the more adventurous: you could allow the user to choose the spacing himself for every arrow, such as in this loop diagram.

\documentclass{article}
\usepackage{feynmp-auto}
\newcommand{\marrow}[5]{%
\fmfcmd{style_def marrow#1
expr p = drawarrow subpath (1/4, 3/4) of p shifted 6 #2 withpen pencircle scaled 0.4;
label.#3(btex #4 etex, point 0.5 of p shifted 6 #2);
enddef;}
\fmf{marrow#1,tension=0}{#5}}
\newcommand{\Marrow}[6]{%
\fmfcmd{style_def marrow#1
expr p = drawarrow subpath (1/4, 3/4) of p shifted #6 #2 withpen pencircle scaled 0.4;
label.#3(btex #4 etex, point 0.5 of p shifted #6 #2);
enddef;}
\fmf{marrow#1,tension=0}{#5}}
\begin{document}
\setlength{\unitlength}{1mm}
\begin{fmffile}{marrow2}
\begin{fmfgraph*}(50,50)
\fmfleftn{i}{2}
\fmfrightn{o}{2}
\fmf{fermion}{i1,v1,o1}
\fmf{fermion}{i2,v4,o2}
\fmf{photon}{v1,v2}
\fmf{fermion,right,tension=0.4}{v2,v3,v2}
\fmf{photon}{v3,v4}
\fmfdotn{v}{4}
\marrow{a}{down}{bot}{$p_1$}{i1,v1}
\marrow{b}{up}{top}{$p_2$}{i2,v4}
\marrow{c}{left}{lft}{$q$}{v1,v2}
\Marrow{d}{right}{rt}{$k$}{v2,v3}{26}
\Marrow{e}{left}{lft}{$q-k$}{v2,v3}{26}
\marrow{f}{left}{lft}{$q$}{v3,v4}
\marrow{g}{down}{bot}{$p_3$}{v1,o1}
\marrow{h}{up}{top}{$p_4$}{v4,o2}
\end{fmfgraph*}
\end{fmffile}
\end{document}