Page MenuHomeHEPForge

feynmp.mp
No OneTemporary

feynmp.mp

%%
%% This is file `feynmp.mp',
%% generated with the docstrip utility.
%%
%% The original source files were:
%%
%% feynmf.dtx (with options: `base,mp')
%%
%% Copyright (C) 1989, 1990, 1992-1995 by Thorsten.Ohl@Physik.TH-Darmstadt.de
%%
%% This file is NOT the source for feynmf, because almost all comments
%% have been stripped from it. It is NOT the preferred form of feynmf
%% for making modifications to it.
%%
%% Therefore you can NOT redistribute and/or modify THIS file. You can
%% however redistribute the complete source (feynmf.dtx and feynmf.ins)
%% and/or modify it under the terms of the GNU General Public License as
%% published by the Free Software Foundation; either version 2, or (at
%% your option) any later version.
%%
%% As a special exception, you can redistribute parts of this file for
%% the electronic distribution of scientific papers, provided that you
%% include a short note pointing to the complete source.
%%
%% Feynmf is distributed in the hope that it will be useful, but
%% WITHOUT ANY WARRANTY; without even the implied warranty of
%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
%% GNU General Public License for more details.
%%
%% You should have received a copy of the GNU General Public License
%% along with this program; if not, write to the Free Software
%% Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% \CheckSum{924}
%% \CharacterTable
%% {Upper-case \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z
%% Lower-case \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z
%% Digits \0\1\2\3\4\5\6\7\8\9
%% Exclamation \! Double quote \" Hash (number) \#
%% Dollar \$ Percent \% Ampersand \&
%% Acute accent \' Left paren \( Right paren \)
%% Asterisk \* Plus \+ Comma \,
%% Minus \- Point \. Solidus \/
%% Colon \: Semicolon \; Less than \<
%% Equals \= Greater than \> Question mark \?
%% Commercial at \@ Left bracket \[ Backslash \\
%% Right bracket \] Circumflex \^ Underscore \_
%% Grave accent \` Left brace \{ Vertical bar \|
%% Right brace \} Tilde \~}
%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
def subgraph (expr x, y, wd, ht) =
begingroup
save c, ne, nw, sw, se;
pair c, ne, nw, sw, se;
sw = (x,y);
se = sw + (wd,0);
nw = sw + (0,ht);
ne = sw + (wd,ht);
c = .5[sw,ne];
enddef;
def endsubgraph =
endgroup
enddef;
if known cmbase:
errhelp
"feynmf will only work with plain Metafont, as described in the book.";
errmessage "feynmf: CMBASE detected. Please use the PLAIN base.";
forever:
errmessage "No use in trying! You'd better eXit now ...";
errorstopmode;
endfor
fi
vardef parse_RCS (suffix RCS) (expr s) =
save n, c;
numeric n, RCS[];
string c;
RCS[0] := 0;
for n = 1 upto length (s):
c := substring (n-1,n) of s;
exitif ((RCS[0] > 0) and (c = " "));
if ((c = "0") or (c = "1") or (c = "2")
or (c = "3") or (c = "4") or (c = "5")
or (c = "6") or (c = "7") or (c = "8")
or (c = "9")):
if RCS[0] = 0:
RCS[0] := 1;
RCS[RCS[0]] := 0;
fi
RCS[RCS[0]] := 10 * RCS[RCS[0]] + scantokens (c);
elseif c = ".":
RCS[0] := RCS[0] + 1;
RCS[RCS[0]] := 0;
else:
fi
endfor
enddef;
vardef require_RCS_revision expr s =
save n, TeX_rev, mf_rev;
numeric n;
parse_RCS (TeX_rev, s);
parse_RCS (mf_rev, "$Re"&"vision: 1.30 $");
for n = 1 upto min (2, TeX_rev[0], mf_rev[0]):
if TeX_rev[n] > mf_rev[n]:
errhelp
"Your version of `feynmf.sty' is higher that of your `feynmf.mf'.";
errmessage "feynmf: Metafont macros out of date";
elseif TeX_rev[n] < mf_rev[n]:
errhelp
"Your version of `feynmf.mf' is higher that of your `feynmf.sty'.";
errmessage "feynmf: LaTeX style out of date";
fi
exitif (TeX_rev[n] <> mf_rev[n]);
endfor
enddef;
vardef cullit = \ enddef;
color foreground;
foreground = black;
vardef beginchar (expr c, wd, ht, dp) =
LaTeX_file := "";
beginfig(c);
w:=wd;
h:=ht;
enddef;
string LaTeX_file;
vardef endchar =
setbounds currentpicture to (0,0)--(w,0)--(w,h)--(0,h)--cycle;
if LaTeX_file <> "":
write EOF to LaTeX_file;
LaTeX_file := "";
fi
endfig
enddef;
bp# := bp;
cc# := cc;
cm# := cm;
dd# := dd;
in# := in;
mm# := mm;
pc# := pc;
pt# := pt;
vardef define_blacker_pixels(text t) =
forsuffixes $=t:
$:=$.#;
endfor
enddef;
picture unitpixel;
unitpixel = nullpicture;
addto unitpixel contour unitsquare;
def t_ = \ enddef;
boolean feynmfwizard;
feynmfwizard := false;
thin# := 1pt#; % dimension of the lines
thick# := 2thin#;
arrow_len# := 4mm#;
arrow_ang := 15;
curly_len# := 3mm#;
dash_len# := 3mm#; % 'photon' lines
dot_len# := 2mm#; % 'photon' lines
wiggly_len# := 4mm#; % 'photon' lines
wiggly_slope := 60;
zigzag_len# := 2mm#;
zigzag_width# := 2thick#;
decor_size# := 5mm#;
dot_size# := 2thick#;
define_blacker_pixels (thick, thin,
dash_len, dot_len, wiggly_len, curly_len,
zigzag_len, zigzag_width, arrow_len, decor_size, dot_size);
def shrink expr s =
begingroup
if shrinkables <> "":
save tmp_;
forsuffixes $ = scantokens shrinkables:
if known $.#:
tmp_ := $.#;
save $;
$.# := s * tmp_;
define_blacker_pixels ($);
else:
tmp_ := $;
save $;
$ := s * tmp_;
fi
endfor
fi
enddef;
def endshrink =
endgroup
enddef;
string shrinkables;
shrinkables := "";
vardef addto_shrinkables (text l) =
forsuffixes $ = l:
shrinkables := shrinkables & "," & str $;
endfor
enddef;
shrinkables := "thick,thin";
addto_shrinkables (dash_len, dot_len);
addto_shrinkables (wiggly_len, curly_len);
addto_shrinkables (zigzag_len, zigzag_width);
addto_shrinkables (arrow_len);
addto_shrinkables (decor_size, dot_size);
LaTeX_unitlength := mm;
vardef count (text list) =
forsuffixes $ = list: + 1 endfor
enddef;
vardef getopt (suffix opt) (expr s) =
save n, argp, escape, anchor, skip;
numeric opt.first, opt.last, n, anchor;
string opt[], opt[]arg;
boolean opt[]tainted, argp, escape, skip;
opt.first := 0;
opt.last := 0;
opt[opt.last] := "";
argp := false;
escape := false;
anchor := 0;
skip := true;
for n = 1 upto length (s):
if skip and (substring (n-1, n) of s = " "):
anchor := anchor + 1;
else:
skip := false;
if not escape and (substring (n-1, n) of s = ","):
if substring (n, n+1) of s = ",":
escape := true;
opt[opt.last]tainted := true;
else:
if argp:
opt[opt.last]arg := substring (anchor, n-1) of s;
else:
opt[opt.last] := substring (anchor, n-1) of s;
fi
anchor := n;
argp := false;
skip := true;
opt.last := opt.last + 1;
fi
elseif not argp and (substring (n-1, n) of s = "="):
opt[opt.last] := substring (anchor, n-1) of s;
anchor := n;
argp := true;
skip := true;
elseif argp or (substring (n-1, n) of s <> " "):
escape := false;
fi
fi
endfor
if argp:
opt[opt.last]arg := substring (anchor, length s) of s;
else:
opt[opt.last] := substring (anchor, length s) of s;
fi
for n = opt.first upto opt.last:
if known opt[n]tainted:
if opt[n]tainted:
opt[n]arg := untaint_string opt[n]arg;
fi
fi
endfor
enddef;
vardef untaint_string suffix s =
save n, anchor;
numeric n, anchor;
anchor := 0;
for n = 1 upto length (s) - 1:
if substring (n-1,n+1) of s = ",,":
substring (anchor, n-1) of s &
hide (anchor := n)
fi
endfor
substring (anchor, length s) of s
enddef;
vardef split_string (suffix comp) (expr s) =
save n, anchor;
numeric comp.first, comp.last, n, anchor;
string comp[];
comp.first := 0;
comp.last := 0;
comp[comp.last] := "";
anchor := 0;
for n = 1 upto length (s):
if substring (n-1,n) of s = ".":
comp[comp.last] := substring (anchor, n-1) of s;
comp.last := comp.last + 1;
anchor := n;
fi
endfor
comp[comp.last] := substring (anchor, length s) of s;
enddef;
vardef match_prefix (expr prefix, s) =
(prefix = substring (0, length prefix) of s)
enddef;
vardef match_option (expr s, option) =
save sc, optionc, n, i;
numeric sc.first, sc.last, optionc.first, optionc.last;
string sc[], optionc[];
numeric n, i;
split_string (sc, s);
split_string (optionc, option);
n := sc.last - sc.first;
if n <> (optionc.last - optionc.first):
false
else:
true
for i = 0 upto n:
and match_prefix (sc[sc.first+i],
optionc[optionc.first+i])
endfor
fi
enddef;
def save_picture text t =
save t; picture t; forsuffixes p=t: p:=nullpicture; endfor
enddef;
def begin_sketch =
begingroup save_picture currentpicture;
sketchlevel := sketchlevel+1;
enddef;
def end_sketch =
sketchlevel := sketchlevel-1;
sketchpad[sketchlevel] := currentpicture;
endgroup
enddef;
picture sketchpad[];
sketchlevel := 1;
vardef use_sketch text t =
addto currentpicture also (sketchpad[sketchlevel] t)
enddef;
vardef cdraw expr p =
draw p withcolor foreground
enddef;
vardef cfill expr p =
fill p withcolor foreground
enddef;
vardef cfilldraw expr p =
filldraw p withcolor foreground
enddef;
vardef ccutdraw expr p =
cutdraw p withcolor foreground
enddef;
vardef cdrawdot expr p =
drawdot p withcolor foreground
enddef;
vardef isdigit expr s =
save n;
(s = "0")
for n = 1 upto 9:
or (s = decimal n)
endfor
enddef;
vardef digits_index (expr s, start) =
save n, m, from, to;
for n = start upto (length s)-1:
if isdigit (substring (n,n+1) of s):
from := n;
for m = n upto length s:
if not isdigit (substring (m,m+1) of s):
to := m;
fi
exitif known to;
endfor
fi
exitif known from;
endfor
(from, if known to: to else: infinity fi)
enddef;
vardef digits_to_brackets suffix suf =
save s, idx;
string s;
pair idx;
s = str suf;
idx = (0,0);
forever:
idx := digits_index (s, xpart idx);
exitif unknown xpart idx;
s := substring (0,xpart idx) of s
& "[]" & substring (ypart idx,infinity) of s;
endfor
s
enddef;
tile_grain := 1in/300;
vardef def_tile (suffix t) (expr wd, ht) =
if not picture tlist.t:
picture tlist.scantokens (digits_to_brackets t);
fi
tlist.t := nullpicture;
tlist.t.dx := max (floor wd, 1);
tlist.t.dy := max (floor ht, 1);
enddef;
vardef use_tile (suffix t) (expr x, y, wd, ht) =
fill unitsquare xscaled wd yscaled ht shifted (x,y)
withcolor background;
if str t = "shaded":
shade_rectangle (4thin, x, y, wd, ht);
elseif str t = "hatched":
shade_rectangle (5thin, x, y, wd, ht);
shade_rectangle (-5thin, x, y, wd, ht);
else:
if (picture tlist.t):
for nx = 0 upto wd/tlist.t.dx:
for ny = 0 upto ht/tlist.t.dy:
addto currentpicture
also (tlist.t shifted
((x,y) + (nx*tlist.t.dx, ny*tlist.t.dy)) t_);
endfor
endfor
else:
errhelp "feynmf: your tiling has not been defined, "
& "check spelling and reprocess!";
errmessage "feynmf: tiling `" & str t & "' not known, "
& "replaced by `shaded'";
use_tile (shaded, x, y, wd, ht);
fi
fi
enddef;
vardef shade_rectangle (expr dd, x, y, wd, ht) =
save d, u, dx, dy, currentpen;
pen currentpen;
pickup pencircle scaled thin;
d := max (floor (abs dd), 1);
dx := max (wd, ht);
dy := max (wd, ht);
for u = 0 step d/dx until 1:
if dd > 0:
cdraw (x-d,y+u*dy-d)--(x+(1-u)*dx+d,y+dy+d);
cdraw (x+u*dx-d,y-d)--(x+dx+d,y+(1-u)*dy+d);
else:
cdraw (x-d,y+u*dy+d)--(x+u*dx+d,y-d);
cdraw (x+(1-u)*dx-d,y+dy+d)--(x+dx+d,y+(1-u)*dy-d);
fi
endfor
enddef;
def addto_tile (suffix t) =
addto tlist.t
enddef;
vardef tile_from_string (suffix t) (expr str) =
tile_grain := max (floor tile_grain, 1);
save grain, mx, x, y, n, c, pic;
string c;
picture pic;
pic := nullpicture;
grain := tile_grain;
mx := 0;
x := 0;
y := 0;
for n := 1 upto length str:
c := substring (n-1,n) of str;
if c = "/":
mx := max (mx, x);
y := y+1;
x := 0;
elseif c = "*":
addto pic also (unitpixel shifted (x,-y) t_);
x := x+1;
elseif c = ".":
x := x+1;
fi
endfor
def_tile (t, grain*mx, grain*(y+1));
addto_tile (t) also (pic shifted (0,y) scaled grain t_);
pic := nullpicture;
enddef;
tile_from_string (gray10,
" ... /"&
" .*. /"&
" ... ");
tile_from_string (gray25,
" .. /"&
" *. ");
tile_from_string (gray50,
" .* /"&
" *. ");
tile_from_string (gray75,
" ** /"&
" .* ");
tile_from_string (gray90,
" *** /"&
" *.* /"&
" *** ");
vardef make_halftone (suffix t) (expr g, wd, ht) =
def_tile (t, wd, ht);
addto tlist.t contour unitsquare
xscaled wd yscaled ht withcolor ((1-g)*foreground + g*background)
enddef;
vardef tile (suffix t) (expr p) =
save u, x, y, max_x, min_x, max_y, min_y, xx, yy;
-max_x = -max_y = min_x = min_y = infinity;
for u = 0 step 0.1 until length p:
x := xpart (point u of p);
y := ypart (point u of p);
max_x := max(max_x, x);
max_y := max(max_y, y);
min_x := min(min_x, x);
min_y := min(min_y, y);
endfor
begin_sketch
use_tile (t, min_x, min_y, max_x-min_x, max_y-min_y);
clip currentpicture to p;
end_sketch;
use_sketch;
enddef;
vardef drawtile (suffix t) (expr p) =
tile (t, p);
cdraw p
enddef;
vardef use_halftone (expr g, x, y, wd, ht) =
fill unitsquare xscaled wd yscaled ht
shifted (x,y) withcolor ((1-g)*foreground + g*background)
enddef;
vardef halftone (expr g, p) =
fill p withcolor ((1-g)*foreground + g*background)
enddef;
vardef drawhalftone (expr g, p) =
fill p withcolor ((1-g)*foreground + g*background);
cdraw p
enddef;
vardef shade expr p =
tile (shaded, p)
enddef;
vardef hatch expr p =
tile (hatched, p)
enddef;
vardef emptydraw expr p =
cullit;
unfill p;
cullit;
cdraw p;
enddef;
vardef shadedraw expr p =
cullit;
unfill p;
cullit;
shade p;
cdraw p;
enddef;
vardef hatchdraw expr p =
cullit;
unfill p;
cullit;
hatch p;
cdraw p;
enddef;
vardef marrow (expr p, frac) =
save a, t, z;
pair z;
a = angle direction frac*length(p) of p;
z = point frac*length(p) of p;
(t1,whatever) = p intersectiontimes
(halfcircle scaled 2/3arrow_len rotated (a+90) shifted z);
(t2,whatever) = p intersectiontimes
(halfcircle scaled 4/3arrow_len rotated (a-90) shifted z);
arrow_head (p, t1, t2, arrow_ang)
enddef;
vardef tarrow (expr p, frac) =
save a, t, z;
pair z;
t1 = frac*length p;
a = angle direction t1 of p;
z = point t1 of p;
(t2,whatever) = p intersectiontimes
(halfcircle scaled 2arrow_len rotated (a-90) shifted z);
arrow_head (p, t1, t2, arrow_ang)
enddef;
vardef harrow (expr p, frac) =
save a, t, z;
pair z;
t2 = frac*length p;
a = angle direction t2 of p;
z = point t2 of p;
(t1,whatever) = p intersectiontimes
(halfcircle scaled 2arrow_len rotated (a+90) shifted z);
arrow_head (p, t1, t2, arrow_ang)
enddef;
vardef arrow_head (expr p, from, to, ang) =
save tip, ap, t;
pair tip;
path ap;
t1 := from;
t2 := to;
if t1 = -1: t1 := 0; fi
if t2 = -1: t2 := infinity; fi
tip = point t2 of p;
ap = subpath (t1,t2) of p shifted -tip;
(ap rotated ang
forced_join reverse ap rotated -ang
-- cycle) shifted tip
enddef;
vardef arrow expr p =
marrow (p, .5)
enddef;
tertiarydef p forced_join q =
subpath (0, length p - 1) of p
& point (length p - 1) of p
.. controls postcontrol (length p - 1) of p
and precontrol infinity of p
.. .5[point infinity of p, point 0 of q]
.. controls postcontrol 0 of q and precontrol 1 of q
.. point 1 of q
& subpath (1, infinity) of q
enddef;
vardef cut_decors (suffix from) (expr p) (suffix to) =
subpath (if known from.decor.shape:
xpart (p intersectiontimes
(from.decor.shape scaled from.decor.size
shifted from.loc))
else:
0
fi,
if known to.decor.shape:
length p
- xpart (reverse p intersectiontimes
(to.decor.shape scaled to.decor.size
shifted to.loc))
else:
infinity
fi) of p
enddef;
vardef make_blob (expr z_arg, diameter) =
save p,currentpen; path p; pen currentpen;
pickup pencircle scaled thick;
p = fullcircle scaled diameter shifted z_arg;
shadedraw p;
enddef;
vardef draw_blob (expr z_arg, diameter) =
if sketched_blob_diameter <> diameter: % drawn lately?
begin_sketch make_blob (origin, diameter); end_sketch; % redo hard work!
sketched_blob_diameter:= diameter; % record it
fi
use_sketch shifted z_arg; % the easy way ...
enddef;
def force_new_blob = sketched_blob_diameter := -1; enddef;
force_new_blob; % initialize it.
vardef pixlen (expr p, n) =
for k=1 upto length(p): + segment_pixlen (subpath (k-1,k) of p, n) endfor
enddef;
vardef segment_pixlen (expr p, n) =
for k=1 upto n: + abs (point k/n of p - point (k-1)/n of p) endfor
enddef;
vardef wiggly expr p_arg =
save wpp;
numeric wpp;
wpp = ceiling (pixlen (p_arg, 10) / wiggly_len) / length p_arg;
for k=0 upto wpp*length(p_arg) - 1:
point k/wpp of p_arg
{direction k/wpp of p_arg rotated wiggly_slope} ..
point (k+.5)/wpp of p_arg
{direction (k+.5)/wpp of p_arg rotated - wiggly_slope} ..
endfor
if cycle p_arg: cycle else: point infinity of p_arg fi
enddef;
vardef curly expr p =
save cpp;
numeric cpp;
cpp := ceiling (pixlen (p, 10) / curly_len) / length p;
if cycle p:
for k=0 upto cpp*length(p) - 1:
point (k+.33)/cpp of p
{direction (k+.33)/cpp of p rotated 90} ..
point (k-.33)/cpp of p
{direction (k-.33)/cpp of p rotated -90} ..
endfor
cycle
else:
point 0 of p
{direction 0 of p rotated -90} ..
for k=1 upto cpp*length(p) - 1:
point (k+.33)/cpp of p
{direction (k+.33)/cpp of p rotated 90} ..
point (k-.33)/cpp of p
{direction (k-.33)/cpp of p rotated -90} ..
endfor
point infinity of p
{direction infinity of p rotated 90}
fi
enddef;
vardef zigzag expr p =
save zpp;
numeric zpp;
zpp = ceiling (pixlen (p, 10) / zigzag_len) / length p;
if not cycle p:
point 0 of p --
fi
for k = 0 upto zpp*length(p) - 1:
point (k+1/3)/zpp of p shifted
(zigzag_width
* dir angle (direction (k+1/3)/zpp of p rotated 90)) --
point (k+2/3)/zpp of p shifted
(zigzag_width
* dir angle (direction (k+2/3)/zpp of p rotated -90)) --
endfor
if cycle p:
cycle
else:
point infinity of p
fi
enddef;
save vsty_hash;
def style_def suffix s =
vsty_hash.s := 1;
expandafter quote vardef scantokens ("draw_" & str s)
enddef;
vardef vsty_exists suffix s =
known vsty_hash.s
enddef;
vardef valid_style expr s =
expandafter vsty_exists scantokens (s)
enddef;
style_def phantom expr p =
\
enddef;
style_def phantom_arrow expr p =
cfill (arrow p);
enddef;
style_def plain expr p =
cdraw p;
enddef;
style_def plain_arrow expr p =
cdraw p;
cfill (arrow p);
enddef;
style_def dbl_plain expr p =
draw_double p;
enddef;
style_def dbl_plain_arrow expr p =
draw_double_arrow p;
enddef;
style_def wiggly expr p =
cdraw (wiggly p);
enddef;
style_def dbl_wiggly expr p =
draw_double (wiggly p);
enddef;
style_def curly expr p =
cdraw (curly p);
enddef;
style_def dbl_curly expr p =
draw_double (curly p);
enddef;
style_def zigzag expr p =
cdraw (zigzag p);
enddef;
style_def dbl_zigzag expr p =
draw_double (zigzag p);
enddef;
style_def dashes expr p =
save dpp;
numeric dpp;
dpp = ceiling (pixlen (p, 10) / dash_len) / length p;
for k=0 upto dpp*length(p) - 1:
cdraw point k/dpp of p ..
point (k+.5)/dpp of p;
endfor
enddef;
style_def dbl_dashes expr p =
save dpp;
numeric dpp;
dpp = ceiling (pixlen (p, 10) / dash_len) / length p;
for k=0 upto dpp*length(p) - 1:
draw_double point k/dpp of p ..
point (k+.5)/dpp of p;
endfor
enddef;
style_def dbl_dashes_arrow expr p =
draw_dbl_dashes p;
shrink (1.5);
cfill (arrow p);
endshrink;
enddef;
style_def dashes_arrow expr p =
draw_dashes p;
cfill (arrow p);
enddef;
style_def dots expr p =
save dpp;
numeric dpp;
dpp = ceiling (pixlen (p, 10) / dot_len) / length p;
for k=0 upto dpp*length(p):
cdrawdot point k/dpp of p;
endfor
enddef;
style_def dbl_dots expr p =
save dpp;
numeric dpp;
dpp = ceiling (pixlen (p, 10) / dot_len) / length p;
begingroup
save oldpen;
pen oldpen;
oldpen := currentpen;
pickup oldpen scaled 3; % draw a thick linn
for k=0 upto dpp*length(p):
cdrawdot point k/dpp of p;
endfor
pickup oldpen;
cullit;
for k=0 upto dpp*length(p):
undrawdot point k/dpp of p;
endfor
cullit; % and remove the stuffing
endgroup;
enddef;
style_def dbl_dots_arrow expr p =
draw_dbl_dots p;
shrink (1.5);
cfill (arrow p);
endshrink;
enddef;
style_def dots_arrow expr p =
draw_dots p;
cfill (arrow p);
enddef;
style_def double expr p =
save oldpen;
pen oldpen;
oldpen := currentpen;
pickup oldpen scaled 3;
ccutdraw p;
pickup oldpen;
cullit; undraw p; cullit;
enddef;
style_def double_arrow expr p =
draw_double p;
shrink (1.5);
cfill (arrow p);
endshrink;
enddef;
style_def vanilla expr p = draw_plain p enddef;
style_def fermion expr p = draw_plain_arrow p enddef;
style_def quark expr p = draw_plain_arrow p enddef;
style_def electron expr p = draw_plain_arrow p enddef;
style_def photon expr p = draw_wiggly p enddef;
style_def boson expr p = draw_wiggly p enddef;
style_def gluon expr p = draw_curly p enddef;
style_def heavy expr p = draw_dbl_plain_arrow p enddef;
style_def ghost expr p = draw_dots_arrow p enddef;
style_def scalar expr p = draw_dashes_arrow p enddef;
vardef fermion expr path_arg =
cfill (arrow (path_arg));
path_arg
enddef;
vardef photon expr path_arg =
wiggly path_arg
enddef;
vardef gluon expr path_arg =
curly path_arg
enddef;
tracingstats:=1;
boolean vtracing;
vtracing := false; % true
def vinit =
save vhash;
numeric vlist.first, vlist.last;
vlist.first := 1;
vlist.last := 0;
pair vlist[]loc;
numeric vlist[]decor.size, vlist[]decor.ang,
vlist[]arc.first, vlist[]arc.last,
vlist[]arc[], vlist[]arc[]lsr,
vlist[]arc[]tns, vlist[]arc[]lbl.dist,
vlist[]arc[]tag, vlist[]arc[]wd, vlist[]arc[]rub,
vlist[]constr.first, vlist[]constr.last,
vlist[]constr[], lambdax[][], lambday[][];
string vlist[]name, vlist[]lbl, vlist[]decor.sty,
vlist[]arc[]sty, vlist[]arc[]lbl, vlist[]arc[]lbl.side;
numeric vlist[]lbl.ang;
path vlist[]decor.shape;
color vlist[]fore, vlist[]back,
vlist[]arc[]fore, vlist[]arc[]back;
numeric plist.first, plist.last, plist[]cnt, plist[]vtx[],
plist[]pull, plist[]lbl.ang, plist[]lbl.dist;
string plist[]lbl, plist[]sty, plist[]cona, plist[]conb;
plist.first := 1;
plist.last := 0;
numeric vlist[]poly.first, vlist[]poly.last,
vlist[]poly[], vlist[]poly[]idx;
pair lambdap[][];
color plist[]fore, plist[]back;
enddef;
def vertices =
vlist.first upto vlist.last
enddef;
def varcs (text i) =
vlist[i]arc.first upto vlist[i]arc.last
enddef;
def vconstr (text i) =
vlist[i]constr.first upto vlist[i]constr.last
enddef;
def polygons =
plist.first upto plist.last
enddef;
def vpoly (text i) =
vlist[i]poly.first upto vlist[i]poly.last
enddef;
vardef venter suffix v =
if not vexists v:
vlist.last := vlist.last + 1;
vhash.v := vlist.last;
vlist[vhash.v]name := str v;
vlist[vhash.v]loc := (whatever,whatever);
vlist[vhash.v]arc.first := 1;
vlist[vhash.v]arc.last := 0;
vlist[vhash.v]constr.first := 1;
vlist[vhash.v]constr.last := 0;
vlist[vhash.v]lbl := "";
vlist[vhash.v]lbl.ang := whatever;
vlist[vhash.v]lbl.dist := 3thick;
vlist[vhash.v]fore := (whatever, whatever, whatever);
vlist[vhash.v]back := (whatever, whatever, whatever);
vlist[vhash.v]poly.first := 1;
vlist[vhash.v]poly.last := 0;
fi
enddef;
vardef vexists suffix v =
if known vhash.v: true else: false fi
enddef;
vardef vlookup suffix v =
if vexists v: vhash.v else: 0 fi
enddef;
vardef vloc suffix v =
vlist[vlookup v]loc
enddef;
vardef vconnect (expr linesty) (text vl) =
save from, nfrom, nto, nopt, sty;
numeric from, nfrom, nto, nopt;
string sty;
getopt (opt, linesty);
sty := opt[opt.first];
if known opt[opt.first]arg:
message "feynmf: line styles don't take arguments. "
& "Argument `" & opt[opt.first]arg & "' ignored.";
fi
opt.first := opt.first + 1;
forsuffixes to = vl:
venter to;
nto := vlookup to;
if known nfrom:
vlist[nfrom]arc.last := vlist[nfrom]arc.last + 1;
vlist[nfrom]arc[vlist[nfrom]arc.last] := nto;
vlist[nfrom]arc[vlist[nfrom]arc.last]tns := 1;
if nfrom <> nto:
vlist[nto]arc.last := vlist[nto]arc.last + 1;
vlist[nto]arc[vlist[nto]arc.last] := nfrom;
vlist[nto]arc[vlist[nto]arc.last]tns := 1;
fi
vlist[nfrom]arc[vlist[nfrom]arc.last]lbl := "";
vlist[nfrom]arc[vlist[nfrom]arc.last]lbl.side := "";
vlist[nfrom]arc[vlist[nfrom]arc.last]lbl.dist := 3thick;
for nopt = opt.first upto opt.last:
if match_option (opt[nopt], "tension"):
get_argument (opt[nopt], scantokens (opt[nopt]arg),
vlist[nfrom]arc[vlist[nfrom]arc.last]tns);
get_argument (opt[nopt], scantokens (opt[nopt]arg),
vlist[nto]arc[vlist[nto]arc.last]tns);
elseif match_option (opt[nopt], "left"):
if known opt[nopt]arg:
vlist[nfrom]arc[vlist[nfrom]arc.last]lsr
:= - scantokens (opt[nopt]arg);
else:
vlist[nfrom]arc[vlist[nfrom]arc.last]lsr := -1;
fi
elseif match_option (opt[nopt], "straight"):
vlist[nfrom]arc[vlist[nfrom]arc.last]lsr := 0;
ignore_argument (opt[nopt], opt[nopt]arg);
elseif match_option (opt[nopt], "right"):
if known opt[nopt]arg:
vlist[nfrom]arc[vlist[nfrom]arc.last]lsr
:= scantokens (opt[nopt]arg);
else:
vlist[nfrom]arc[vlist[nfrom]arc.last]lsr := 1;
fi
elseif match_option (opt[nopt], "label"):
get_argument (opt[nopt], opt[nopt]arg,
vlist[nfrom]arc[vlist[nfrom]arc.last]lbl);
elseif match_option (opt[nopt], "label.side"):
get_argument (opt[nopt], opt[nopt]arg,
vlist[nfrom]arc[vlist[nfrom]arc.last]lbl.side);
elseif match_option (opt[nopt], "label.dist"):
get_argument (opt[nopt], scantokens (opt[nopt]arg),
vlist[nfrom]arc[vlist[nfrom]arc.last]lbl.dist);
elseif match_option (opt[nopt], "tag"):
if known opt[nopt]arg:
vlist[nfrom]arc[vlist[nfrom]arc.last]tag
:= scantokens (opt[nopt]arg);
else:
vlist[nfrom]arc[vlist[nfrom]arc.last]tag := 0;
fi
elseif match_option (opt[nopt], "width"):
get_argument (opt[nopt], scantokens (opt[nopt]arg),
vlist[nfrom]arc[vlist[nfrom]arc.last]wd);
elseif match_option (opt[nopt], "foreground"):
get_argument (opt[nopt], scantokens (opt[nopt]arg),
vlist[nfrom]arc[vlist[nfrom]arc.last]fore);
elseif match_option (opt[nopt], "background"):
get_argument (opt[nopt], scantokens (opt[nopt]arg),
vlist[nfrom]arc[vlist[nfrom]arc.last]back);
elseif match_option (opt[nopt], "rubout"):
if known opt[nopt]arg:
vlist[nfrom]arc[vlist[nfrom]arc.last]rub
:= scantokens (opt[nopt]arg);
else:
vlist[nfrom]arc[vlist[nfrom]arc.last]rub := 2;
fi
else:
ignore_option (opt[nopt], opt[nopt]arg);
fi
endfor
handle_line_style (vlist[nfrom]arc[vlist[nfrom]arc.last]sty, sty);
vlist[nto]arc[vlist[nto]arc.last]lsr
:= vlist[nfrom]arc[vlist[nfrom]arc.last]lsr;
fi
nfrom := nto;
endfor
enddef;
vardef handle_line_style (suffix sty) (expr name) =
if valid_style name:
sty := name;
else:
errhelp "feynmf: your linestyle is not recognizable, "
& "check spelling and reprocess!";
errmessage "feynmf: line style `" & name & "' not known, "
& "replaced by `vanilla'";
sty := "vanilla";
fi
enddef;
vardef get_argument (expr opt, arg) (suffix variable) =
if known arg:
variable := arg;
else:
message "feynmf: option `" & opt & "' needs an argument. Ignored.";
fi
enddef;
vardef ignore_argument (expr opt, arg) =
if known arg:
message "feynmf: option `" & opt & "' doesn't take an argument. "
& "Argument `" & arg & "' ignored.";
fi
enddef;
vardef ignore_option (expr opt, arg)=
if known arg:
message "feynmf: ignoring option " & opt & "=" & arg & ".";
else:
message "feynmf: ignoring option " & opt & ".";
fi
enddef;
vardef vconnectn (expr linesty) (suffix v) (expr n) =
vconnect (linesty, vmklist (v, n));
enddef;
vardef vpath@# (suffix from, to) =
save nfrom, nto, origin, index, unknown_path;
numeric nfrom, nto, origin, index;
path unknown_path;
if (known vloc from) and (known vloc to):
nfrom := vlookup from;
nto := vlookup to;
vmatch_path (nfrom, nto, maybe_empty@#);
if (unknown origin) or (unknown index):
vmatch_path (nto, nfrom, maybe_empty@#);
fi
fi
if (known origin) and (known index):
vbuild_cut_arc (origin, index)
else:
unknown_path
fi
enddef;
vardef maybe_empty@# =
save _prefix;
_prefix=137;
if known _prefix@#:
whatever
else:
@#
fi
enddef;
vardef vmatch_path (expr nfrom, nto, t) =
save i;
for i = varcs (nfrom):
if (vlist[nfrom]arc[i] = nto) and (known vlist[nfrom]arc[i]sty):
if unknown t:
origin := nfrom;
index := i;
else:
if known vlist[nfrom]arc[i]tag:
if vlist[nfrom]arc[i]tag = t:
origin := nfrom;
index := i;
fi
fi
fi
fi
endfor
enddef;
vardef vcyclen (expr sty) (suffix v) (expr n) =
for $ = 1 upto n - 1:
vconnect (sty, v[$], v[$+1]);
endfor
vconnect (sty, v[n], v[1]);
enddef;
vardef vrcyclen (expr sty) (suffix v) (expr n) =
vconnect (sty, v[1], v[n]);
for $ = n downto 2:
vconnect (sty, v[$], v[$-1]);
endfor
enddef;
vardef vforce (expr z) (suffix v) =
venter v;
vlist[vlookup v]loc := z;
enddef;
vardef vshift (expr z) (text vl) =
forsuffixes $=vl:
if vexists $:
vlist[vlookup $]loc := vlist[vlookup $]loc + z;
fi
endfor
enddef;
vardef vconstraint (expr z) (text vl) =
save nfrom, nto;
numeric nfrom, nto;
forsuffixes to = vl:
venter to;
nto := vlookup to;
if known nfrom:
vlist[nfrom]constr.last := vlist[nfrom]constr.last + 1;
vlist[nto]constr.last := vlist[nto]constr.last + 1;
vlist[nfrom]constr[vlist[nfrom]constr.last] := nto;
vlist[nto]constr[vlist[nto]constr.last] := nfrom;
vlist[nto]loc = vlist[nfrom]loc + z;
fi
nfrom := nto;
endfor
enddef;
vardef vpolygon (expr psty) (suffix v) (text vl) =
save nopt, csty, nfrom, nfrom_, nto, i, n, j;
numeric nopt, nfrom, nfrom_, nto, i, n, j;
string csty;
n := count (vl) + 1;
plist.last := plist.last + 1;
plist[plist.last]cnt := n;
plist[plist.last]lbl := "";
plist[plist.last]lbl.ang := whatever;
plist[plist.last]lbl.dist := 0;
csty := "phantom";
getopt (opt, psty);
for nopt = opt.first upto opt.last:
if match_option (opt[nopt], "filled"):
get_argument (opt[nopt], opt[nopt]arg, plist[plist.last]sty);
elseif match_option (opt[nopt], "tension"):
if known opt[nopt]arg:
csty := csty & ",tension=" & opt[nopt]arg;
else:
message "feynmf: option `tension' needs an argument. Ignored.";
fi
elseif match_option (opt[nopt], "label"):
get_argument (opt[nopt], opt[nopt]arg, plist[plist.last]lbl);
elseif match_option (opt[nopt], "label.angle"):
get_argument (opt[nopt], scantokens (opt[nopt]arg),
plist[plist.last]lbl.ang);
elseif match_option (opt[nopt], "label.dist"):
get_argument (opt[nopt], scantokens (opt[nopt]arg),
plist[plist.last]lbl.dist);
elseif match_option (opt[nopt], "pull"):
get_argument (opt[nopt], scantokens (opt[nopt]arg),
plist[plist.last]pull);
elseif match_option (opt[nopt], "cona"):
get_argument (opt[nopt], opt[nopt]arg, plist[plist.last]cona);
elseif match_option (opt[nopt], "conb"):
get_argument (opt[nopt], opt[nopt]arg, plist[plist.last]conb);
elseif match_option (opt[nopt], "smooth"):
plist[plist.last]cona := "..";
plist[plist.last]conb := "..";
ignore_argument (opt[nopt], opt[nopt]arg);
elseif match_option (opt[nopt], "foreground"):
get_argument (opt[nopt], scantokens (opt[nopt]arg),
plist[plist.last]fore);
elseif match_option (opt[nopt], "background"):
get_argument (opt[nopt], scantokens (opt[nopt]arg),
plist[plist.last]back);
elseif match_option (opt[nopt], "phantom"):
plist[plist.last]sty := "phantom";
elseif match_option (opt[nopt], "empty"):
plist[plist.last]sty := "empty";
elseif match_option (opt[nopt], "full"):
plist[plist.last]sty := "full";
elseif match_option (opt[nopt], "hatched"):
plist[plist.last]sty := "hatched";
elseif match_option (opt[nopt], "shaded"):
plist[plist.last]sty := "shaded";
else:
ignore_option (opt[nopt], opt[nopt]arg);
fi
endfor
canonicalize_filling plist[plist.last]sty;
vconnect (csty, v, vl, v);
i := 1;
forsuffixes to = v, vl, v:
nto := vlookup to;
if known nfrom:
if known nfrom_:
vlist[nto]loc = vlist[nfrom]loc
+ (vlist[nfrom]loc - vlist[nfrom_]loc) rotated (360/n);
fi
vlist[nto]poly.last := vlist[nto]poly.last + 1;
vlist[nto]poly[vlist[nto]poly.last] := plist.last;
vlist[nto]poly[vlist[nto]poly.last]idx := i;
plist[plist.last]vtx[i] := nto;
i := i + 1;
nfrom_ := nfrom;
fi
nfrom := nto;
endfor
enddef;
vardef canonicalize_filling suffix f =
if known f:
if is_a_number (f):
if scantokens f <= 1:
f :=
if scantokens f = 1:
"full"
elseif scantokens f > 0:
"shaded"
elseif scantokens f = 0:
"empty"
else:
"hatched"
fi;
fi
fi
fi
enddef;
vardef vpolygonn (expr sty) (suffix v) (expr n) =
vpolygon (sty, v[1], for $=2 upto n-1: v[$], endfor v[n]);
enddef;
vardef vrpolygonn (expr sty) (suffix v) (expr n) =
vpolygon (sty, v[n], for $=n-1 downto 2: v[$], endfor v[1]);
enddef;
vardef vlabel (expr s) (suffix v) =
venter v;
vlist[vlookup v]lbl := s;
enddef;
vardef vvertex (expr vtxsty) (text vl) =
save nopt, sty, arg;
numeric nopt, arg;
string sty;
getopt (opt, vtxsty);
forsuffixes v = vl:
venter v;
n := vlookup v;
for nopt = opt.first upto opt.last:
handle_vertex_option (vlist[n], opt[nopt], opt[nopt]arg);
endfor
endfor
enddef;
vardef handle_vertex_option (suffix v) (expr opt, arg) =
if match_option (opt, "label"):
get_argument (opt, arg, v.lbl);
elseif match_option (opt, "label.angle"):
get_argument (opt, scantokens (arg), v.lbl.ang);
elseif match_option (opt, "label.dist"):
get_argument (opt, scantokens (arg), v.lbl.dist);
elseif match_option (opt, "decoration.shape"):
if known arg:
make_decor_shape (v.decor.shape, arg);
else:
message "feynmf: option `decor.shape' needs an argument. Ignored.";
fi
elseif match_option (opt, "decoration.filled"):
get_argument (opt, arg, v.decor.sty);
canonicalize_filling v.decor.sty;
elseif match_option (opt, "decoration.size"):
get_argument (opt, scantokens (arg), v.decor.size);
elseif match_option (opt, "decoration.angle"):
get_argument (opt, scantokens (arg), v.decor.ang);
elseif match_option (opt, "foreground"):
get_argument (opt, scantokens (arg), v.fore);
elseif match_option (opt, "background"):
get_argument (opt, scantokens (arg), v.back);
else:
ignore_option (opt, arg);
fi
enddef;
vardef make_decor_shape (suffix p) (expr n) =
if match_prefix (n, "circle"): p := fullcircle;
elseif match_prefix (n, "square"):
p := unitsquare shifted -(.5,.5);
elseif match_prefix (n, "cross"): p := polycross 4;
elseif match_prefix (n, "triangle"): p := polygon 3;
elseif match_prefix (n, "triagon"): p := polygon 3;
elseif match_prefix (n, "diamond"): p := polygon 4;
elseif match_prefix (n, "tetragon"): p := polygon 4;
elseif match_prefix (n, "pentagon"): p := polygon 5;
elseif match_prefix (n, "hexagon"): p := polygon 6;
elseif match_prefix (n, "triagram"): p := polygram 3;
elseif match_prefix (n, "tetragram"): p := polygram 4;
elseif match_prefix (n, "pentagram"): p := polygram 5;
elseif match_prefix (n, "hexagram"): p := polygram 6;
elseif match_prefix (n, "triacross"): p := polycross 3;
elseif match_prefix (n, "tetracross"): p := polycross 4;
elseif match_prefix (n, "pentacross"): p := polycross 5;
elseif match_prefix (n, "hexacross"): p := polycross 6;
else:
if feynmfwizard:
p := scantokens(n);
else:
message "feynmf: invalid argument `" & n
& "' to option `decor.shape'. Ignored.";
fi
fi
enddef;
vardef is_a_number expr s =
save n;
if known s:
(true
for n = 1 upto length s:
and ((substring (n-1,n) of s = ".")
or (substring (n-1,n) of s = "-")
or isdigit substring (n-1,n) of s)
endfor)
else:
false
fi
enddef;
vardef vvertexn (expr vtxsty) (suffix v) (expr n) =
vvertex (vtxsty, vmklist (v, n));
enddef;
vardef vblob (expr bd) (text vl)=
forsuffixes $=vl:
if not vexists $: venter $; fi
vlist[vlookup $]decor.shape := fullcircle;
vlist[vlookup $]decor.size := bd;
vlist[vlookup $]decor.sty := "shaded";
endfor
enddef;
vardef vdot (text vl)=
forsuffixes $=vl:
if not vexists $: venter $; fi
vlist[vlookup $]decor.shape := fullcircle;
vlist[vlookup $]decor.size := dot_size;
vlist[vlookup $]decor.sty := "full";
endfor
enddef;
vardef vdotn (suffix v) (expr n) =
vdot (vmklist (v, n));
enddef;
vardef vblobn (suffix v) (expr n) =
vblob (vmklist (v, n));
enddef;
vardef curved_left_gallery = .9[se,sw] .. .5[sw,nw] .. .1[nw,ne] enddef;
vardef curved_right_gallery = .9[sw,se] .. .5[se,ne] .. .1[ne,nw] enddef;
vardef curved_bottom_gallery = .9[nw,sw] .. .5[sw,se] .. .1[se,ne] enddef;
vardef curved_top_gallery = .9[sw,nw] .. .5[nw,ne] .. .1[ne,se] enddef;
vardef curved_surround_gallery =
superellipse (.5[se,ne], .5[ne,nw], .5[nw,sw], .5[sw,se], .75)
enddef;
vardef straight_left_gallery = sw -- nw enddef;
vardef straight_right_gallery = se -- ne enddef;
vardef straight_bottom_gallery = sw -- se enddef;
vardef straight_top_gallery = nw -- ne enddef;
vardef straight_surround_gallery =
.5[se,ne] -- ne -- .5[ne,nw] -- nw
-- .5[nw,sw] -- sw -- .5[sw,se] -- se -- cycle
enddef;
vardef curved_galleries =
vardef left_gallery = curved_left_gallery enddef;
vardef right_gallery = curved_right_gallery enddef;
vardef bottom_gallery = curved_bottom_gallery enddef;
vardef top_gallery = curved_top_gallery enddef;
vardef surround_gallery = curved_surround_gallery enddef;
enddef;
vardef straight_galleries =
vardef left_gallery = straight_left_gallery enddef;
vardef right_gallery = straight_right_gallery enddef;
vardef bottom_gallery = straight_bottom_gallery enddef;
vardef top_gallery = straight_top_gallery enddef;
vardef surround_gallery = straight_surround_gallery enddef;
enddef;
vardef vleft (text vl) = vdistribute (left_gallery, vl) enddef;
vardef vright (text vl) = vdistribute (right_gallery, vl) enddef;
vardef vbottom (text vl) = vdistribute (bottom_gallery, vl) enddef;
vardef vtop (text vl) = vdistribute (top_gallery, vl) enddef;
vardef vsurround (text vl) = vdistribute (surround_gallery, vl) enddef;
curved_galleries;
vardef vdistribute (expr p) (text vl) =
save numv, len, off;
numeric numv, len, off;
numv = count (vl);
if cycle p: numv := numv + 1; fi
len := length (p);
if numv = 1:
vforce (point len/2 of p, vl);
else:
off := 0;
forsuffixes $ = vl:
vforce (point off of p, $);
off := off + len/(numv-1);
endfor
fi
enddef;
def vmklist (suffix v) (expr n) =
for $ = 1 upto n-1: v[$], endfor v[n]
enddef;
vardef vleftn (suffix v) (expr n) =
vleft (vmklist (v, n));
enddef;
vardef vrightn (suffix v) (expr n) =
vright (vmklist (v, n));
enddef;
vardef vbottomn (suffix v) (expr n) =
vbottom (vmklist (v, n));
enddef;
vardef vtopn (suffix v) (expr n) =
vtop (vmklist (v, n));
enddef;
vardef vsurroundn (suffix v) (expr n) =
vsurround (vmklist (v, n));
enddef;
vardef vfreeze =
for i = vertices:
if unknown vlist[i]loc:
origin = origin
for j = varcs (i):
+ vlist[i]arc[j]tns * (vlist[i]loc - vlist[vlist[i]arc[j]]loc)
endfor
for j = vconstr (i):
if i < vlist[i]constr[j]:
+ lambda (i, vlist[i]constr[j])
elseif i > vlist[i]constr[j]:
- lambda (vlist[i]constr[j], i)
fi
endfor
for j = vpoly (i):
+ lambdapoly (vlist[i]poly[j], plist[vlist[i]poly[j]]cnt,
vlist[i]poly[j]idx)
endfor;
fi
endfor
if vtracing: vdump; fi
enddef;
vardef lambda (expr i, j) =
(if known (xpart(vlist[i]loc - vlist[j]loc)):
lambdax[i][j]
else:
0
fi,
if known (ypart(vlist[i]loc - vlist[j]loc)):
lambday[i][j]
else:
0
fi)
enddef;
vardef lambdapoly (expr p, n, i) =
origin
if i = 1:
+ lambdap[p][2] rotated (-360/n)
elseif i = 2:
- lambdap[p][1]
fi
if i = n - 1:
- lambdap[p][n] rotated (-360/n)
elseif i = n:
+ lambdap[p][n-1]
fi
if (i > 1) and (i < n):
+ lambdap[p][i-1] + lambdap[p][i+1] rotated (-360/n)
- lambdap[p][i] - lambdap[p][i] rotated (-360/n)
fi
enddef;
vardef idraw (expr linesty, p) =
save nopt, sty, lbl, wd, rub;
numeric nopt, lbl.dist, wd, rub;
save fore, back;
color fore, back;
string sty, lbl, lbl.side;
getopt (opt, linesty);
sty := opt[opt.first];
if known opt[opt.first]arg:
message "feynmf: line styles don't take arguments. "
& "Argument `" & opt[opt.first]arg & "' ignored.";
fi
opt.first := opt.first + 1;
lbl := "";
lbl.side := "";
lbl.dist := 3thick;
for nopt = opt.first upto opt.last:
if match_option (opt[nopt], "label"):
get_argument (opt[nopt], opt[nopt]arg, lbl);
elseif match_option (opt[nopt], "label.side"):
get_argument (opt[nopt], opt[nopt]arg, lbl.side);
elseif match_option (opt[nopt], "label.dist"):
get_argument (opt[nopt], scantokens (opt[nopt]arg), lbl.dist);
elseif match_option (opt[nopt], "width"):
get_argument (opt[nopt], scantokens (opt[nopt]arg), wd);
elseif match_option (opt[nopt], "foreground"):
get_argument (opt[nopt], scantokens (opt[nopt]arg), fore);
elseif match_option (opt[nopt], "background"):
get_argument (opt[nopt], scantokens (opt[nopt]arg), back);
elseif match_option (opt[nopt], "rubout"):
if known opt[nopt]arg:
rub := scantokens (opt[nopt]arg);
else:
rub := 2;
fi
else:
ignore_option (opt[nopt], opt[nopt]arg);
fi
endfor
handle_line_style (sty, sty);
begingroup
if known fore:
save foreground;
color foreground;
foreground = fore;
fi
if known back:
save background;
color background;
foreground = back;
fi
vdraw_arc_rubout (rub, sty, wd, p, lbl);
endgroup;
enddef;
vardef ivertex (expr vtxsty, pos) =
save nopt, v;
numeric nopt, v.lbl.ang, v.lbl.dist,
v.decor.size, v.decor.ang;
pair v.loc;
string v.lbl, v.decor.sty;
path v.decor.shape;
v.loc := pos;
v.lbl := "";
v.lbl.ang := whatever;
v.lbl.dist := 3thick;
v.decor.size := decor_size;
getopt (opt, vtxsty);
for nopt = opt.first upto opt.last:
handle_vertex_option (v, opt[nopt], opt[nopt]arg);
endfor
vdraw_label (v.loc, v.lbl);
vdraw_vertex v;
enddef;
vardef vdraw =
if not feynmfwizard:
vcheck_typos;
fi
for i = vertices:
if not known vlist[i]loc:
errhelp "Your graph specification was not complete (probably a "
& "lone vertex). Check logic and reprocess!";
errmessage "feynmf: vertex `" & vlist[i]name & "' not determined, "
& "replaced by `(0,0)'.";
vlist[i]loc := origin;
fi
if unknown vlist[i]decor.size:
vlist[i]decor.size = decor_size;
fi
endfor
for i = vertices:
for j = varcs (i):
if known vlist[i]arc[j]sty:
if vlist[i]arc[j]sty <> "":
if unknown vlist[i]arc[j]rub:
begingroup
if known vlist[i]arc[j]fore:
save foreground; color foreground;
foreground = vlist[i]arc[j]fore;
fi
if known vlist[i]arc[j]back:
save background; color background;
background = vlist[i]arc[j]back;
fi
vdraw_arc (vlist[i]arc[j]sty, vlist[i]arc[j]wd,
vbuild_cut_arc (i, j), vlist[i]arc[j]lbl);
vlist[i]arc[j]sty := "";
endgroup;
fi
fi
fi
endfor;
endfor
for i = polygons:
vdraw_label (pcenter plist[i], plist[i]lbl);
vdraw_polygon plist[i];
endfor
for i = vertices:
vdraw_label (vlist[i]loc, vlist[i]lbl);
vdraw_vertex vlist[i];
endfor
for i = vertices:
for j = varcs (i):
if known vlist[i]arc[j]sty:
if vlist[i]arc[j]sty <> "":
if known vlist[i]arc[j]rub:
begingroup
if known vlist[i]arc[j]fore:
save foreground; color foreground;
foreground = vlist[i]arc[j]fore;
fi
if known vlist[i]arc[j]back:
save background; color background;
background = vlist[i]arc[j]back;
fi
vdraw_arc_rubout (vlist[i]arc[j]rub,
vlist[i]arc[j]sty,
vlist[i]arc[j]wd,
vbuild_cut_arc (i, j),
vlist[i]arc[j]lbl);
vlist[i]arc[j]sty := "";
endgroup;
fi
fi
fi
endfor;
endfor
enddef;
vardef vcheck_typos =
save j, err;
boolean wrn;
wrn := false;
for i = vertices:
save connections;
connections = vlist[i]arc.last - vlist[i]arc.first + 1;
if connections < 1:
if unknown vlist[i]loc:
message "feynmf: warning: disconnected and unspecified vertex `"
& substring (2,infinity) of vlist[i]name
& "'.";
wrn := true;
fi
elseif connections = 1:
j := vlist[i]arc[vlist[i]arc.last];
if j < i:
if vlist[i]loc = vlist[j]loc:
message "feynmf: warning: dangling vertex `"
& substring (2,infinity) of vlist[i]name
& "' colliding with `"
& substring (2,infinity) of vlist[j]name
& "'.";
wrn := true;
fi
fi
fi
endfor
if wrn:
message "feynmf: Have you seen the warning messages above?";
message " They are usually caused by misspelling a vertex'";
message " name and can trigger errors further below!";
message " Fix the typos and run LaTeX and Metafont again.";
fi
enddef;
vardef vbuild_arc (expr lsr, from, to) =
if unknown lsr:
from -- to
else:
if lsr = 0:
from -- to
else:
from
.. (1-lsr)/2 *(to rotatedabout (.5[from,to], 90))
+ (1+lsr)/2 * (to rotatedabout (.5[from,to], -90))
.. to
fi
fi
enddef;
vardef vbuild_cut_arc (expr origin, index) =
cut_decors (vlist[origin],
if vlist[origin]arc[index] <> origin:
vbuild_arc (vlist[origin]arc[index]lsr,
vlist[origin]loc,
vlist[vlist[origin]arc[index]]loc)
else:
vbuild_tadpole (origin, index)
fi,
vlist[vlist[origin]arc[index]])
enddef;
vardef vbuild_tadpole (expr origin, index) =
save j, n, nn, nnn, aidx, aang, agap, bgap, ngap, distsum;
n := 0;
distsum := 0;
for j = varcs (origin):
if vlist[origin]arc[j] <> origin:
ang := angle direction 0 of
vbuild_arc (vlist[origin]arc[j]lsr,
vlist[origin]loc,
vlist[vlist[origin]arc[j]]loc);
n := n + 1;
distsum := distsum
+ abs (vlist[vlist[origin]arc[j]]loc - vlist[origin]loc);
aang[n] := 360;
for nn = 1 upto n:
if ang < aang[nn]:
for nnn = n - 1 downto nn:
aang[nnn+1] := aang[nnn];
aidx[nnn+1] := aidx[nnn];
endfor
aang[nn] := ang;
aidx[nn] := n;
fi
exitif known aidx[n];
endfor
fi
endfor
aidx[n+1] := aidx[1];
aang[n+1] := aang[1] + 360;
for nn = 1 upto n:
agap[nn] = aang[nn+1] - aang[nn];
endfor
if known vlist[origin]arc[index]lsr:
ngap := n;
for nn = 1 upto n:
if (aang[nn] < vlist[origin]arc[index]lsr)
and (vlist[origin]arc[index]lsr < aang[nn+1]):
ngap := nn;
fi
endfor
else:
bgap := 0;
for nn = 1 upto n:
if agap[nn] > bgap:
bgap := agap[nn];
ngap := nn;
fi
endfor
fi
if vtracing: adump (n + 1); fi
vlist[origin]loc{dir(aang[ngap]+agap[ngap]/4)}
... vlist[origin]loc + 2/3 * distsum/n
/ vlist[origin]arc[index]tns
* dir(aang[ngap]+agap[ngap]/2)
... {-dir(aang[ngap+1]-agap[ngap]/4)}vlist[origin]loc
enddef;
vardef adump expr n =
save i;
for i = 1 upto n:
message "aidx[" & decimal_ (i) & "]=" & decimal_ (aidx[i])
& ", aang[" & decimal_ (i) & "]=" & decimal_ (aang[i])
& ", agap[" & decimal_ (i) & "]=" & decimal_ (agap[i]);
endfor
enddef;
vardef vdraw_arc (expr sty, wd, arc) (suffix lbl) =
if known wd:
save currentpen;
pen currentpen;
pickup pencircle scaled wd;
fi
scantokens ("draw_" & sty) (arc);
vdraw_arc_label (arc, lbl);
enddef;
let plain_draw = draw;
vardef vdraw_arc_rubout (expr rub, sty, wd, arc) (suffix lbl) =
if known rub:
begingroup
def draw expr p =
save oldpen; pen oldpen;
oldpen := currentpen;
save currentpen; pen currentpen;
pickup oldpen scaled rub;
erase plain_draw (subpath (.1,.9)*length(p) of p)
enddef;
vdraw_arc (sty, wd, arc, lbl);
let draw = plain_draw;
endgroup;
fi
vdraw_arc (sty, wd, arc, lbl);
enddef;
vardef vbuild_polygon suffix p =
if known p.pull:
save c; pair c;
c := pcenter p;
for i = 1 upto (p.cnt - 1):
vbuild_polygon_section (p, i, i+1)
endfor
vbuild_polygon_section (p, p.cnt, 1)
else:
for i = 1 upto p.cnt:
vlist[p.vtx[i]]loc
if known p.cona: scantokens (p.cona) else: -- fi
endfor
fi
cycle
enddef;
def vbuild_polygon_section (suffix p) (expr from, to) =
vlist[p.vtx[from]]loc
if known p.cona: scantokens (p.cona) else: -- fi
p.pull[c,.5[vlist[p.vtx[from]]loc,vlist[p.vtx[to]]loc]]
if known p.conb: scantokens (p.conb) else: -- fi
enddef;
vardef pcenter suffix p =
(origin for i = 1 upto p.cnt:
+ vlist[p.vtx[i]]loc
endfor) / p.cnt
enddef;
vardef vdraw_arc_label (expr arc) (suffix lbl) =
if lbl <> "":
save _a, _z, _zz, _r;
numeric _a;
pair _z, _zz, _r;
_z := point .5 length (arc) of arc;
if lbl.dist = 0:
LaTeX_text (_z, whatever, lbl);
else:
_r := direction .5 length (arc) of arc rotated - 90;
if lbl.side = "left":
_a := angle (-_r);
elseif lbl.side = "right":
_a := angle (_r);
else:
_zz = _z - .5[point 0 of arc, point infinity of arc];
if ((_zz if length (_zz) > 0: / length (_zz) fi)
dotprod _r) >= 0:
_a := angle (_r);
else:
_a := angle (-_r);
fi
fi
LaTeX_text (_z + lbl.dist * dir _a, _a, lbl);
fi
fi
enddef;
vardef vdraw_label (expr loc) (suffix lbl) =
if lbl <> "":
save a;
numeric a;
if lbl.dist = 0:
LaTeX_text (loc, whatever, lbl);
else:
if unknown lbl.ang:
if loc = (.5w,.5h):
a := 0;
else:
a := angle (loc - (.5w,.5h));
fi
else:
a := lbl.ang;
fi
LaTeX_text (loc + lbl.dist * dir a, a, lbl);
fi
fi
enddef;
vardef vdraw_vertex suffix v =
if known v.decor.shape:
if known v.fore:
save foreground;
color foreground;
foreground = v.fore;
fi
if known v.back:
save background;
color background;
background = v.back;
fi
if known v.decor.sty:
if v.decor.sty = "empty":
emptydraw (
elseif v.decor.sty = "full":
cfilldraw (
elseif is_a_number v.decor.sty:
drawhalftone (1 - scantokens v.decor.sty / 100,
else:
drawtile (scantokens v.decor.sty,
fi
else:
cfilldraw (
fi
v.decor.shape
if known v.decor.ang: rotated v.decor.ang fi
scaled v.decor.size shifted v.loc);
fi
enddef;
vardef polygon expr n =
if n > 2:
for i = 1 upto n:
(.5up rotated (360i/n)) --
endfor
cycle
else:
fullcircle
fi
enddef;
vardef polygram expr n =
if n > 2:
for i = 1 upto n:
(.5up rotated (360i/n)) --
(.2up rotated (360(i+.5)/n)) --
endfor
cycle
else:
fullcircle
fi
enddef;
vardef polycross expr n =
save i;
for i = 1 upto n:
origin -- .5 dir (360(i-.5)/n) --
endfor
cycle
enddef;
vardef vdraw_polygon suffix p =
if known p.fore:
save foreground;
color foreground;
foreground = p.fore;
fi
if known p.back:
save background;
color background;
background = p.back;
fi
if known p.sty:
if p.sty = "phantom":
elseif p.sty = "empty":
emptydraw (vbuild_polygon p);
elseif p.sty = "full":
cfilldraw (vbuild_polygon p);
elseif is_a_number p.sty:
drawhalftone (1 - scantokens p.sty / 100, vbuild_polygon p);
else:
drawtile (scantokens p.sty, vbuild_polygon p);
fi
else:
cdraw (vbuild_polygon p);
fi
enddef;
vardef LaTeX expr text =
if LaTeX_file = "":
LaTeX_file := jobname & ".t" & decimal charcode;
write ("% " & LaTeX_file & " -- generated from " & jobname & ".mp")
to LaTeX_file;
fi
write (text & "%") to LaTeX_file
enddef;
vardef LaTeX_text (expr z, a, txt) =
LaTeX "\fmfL(" & (decimal (xpart z/LaTeX_unitlength)) & ","
& (decimal (ypart z/LaTeX_unitlength)) & ","
& (voctant a) & "){" & txt & "}";
enddef;
vardef voctant expr a =
if known a:
voctant_list[floor (a/45 + .5)]
else:
"c"
fi
enddef;
string voctant_list[];
voctant_list[-4] := "r";
voctant_list[-3] := "rt";
voctant_list[-2] := "t";
voctant_list[-1] := "lt";
voctant_list[0] := "l";
voctant_list[1] := "lb";
voctant_list[2] := "b";
voctant_list[3] := "rb";
voctant_list[4] := "r";
vardef vdump =
message ">>>>> Vertices and arcs for diagram #" & decimal charcode
& " of " & jobname & ".mf:";
for i = vertices:
message "> " & vlist[i]name & "=" & decimal_pair (vlist[i]loc)
& ": #lines="
& decimal (vlist[i]arc.last - vlist[i]arc.first + 1)
if vlist[i]lbl <> "":
& ", lbl=" & vlist[i]lbl
& ", l.angle=" & decimal_ (vlist[i]lbl.ang)
& ", l.dist=" & decimal_ (vlist[i]lbl.dist)
fi
& ".";
endfor
for i = vertices:
for j = varcs (i):
if known vlist[i]arc[j]sty:
message "> " & vlist[i]name & "*" & vlist[vlist[i]arc[j]]name
& ": " & vlist[i]arc[j]sty
& ", tns=" & decimal_ (vlist[i]arc[j]tns)
& ", lsr=" & decimal_ (vlist[i]arc[j]lsr)
& ", wd=" & decimal_ (vlist[i]arc[j]wd)
& ", rub=" & decimal_ (vlist[i]arc[j]rub)
if vlist[i]arc[j]lbl <> "":
& ", lbl=" & vlist[i]arc[j]lbl
& ", l.side=" & vlist[i]arc[j]lbl.side
& ", l.dist=" & decimal_ (vlist[i]arc[j]lbl.dist)
fi
& ".";
fi
endfor
for j = vconstr (i):
if i < vlist[i]constr[j]:
save z;
pair z;
z = vlist[vlist[i]constr[j]]loc - vlist[i]loc;
message "> " & vlist[i]name & "&"
& vlist[vlist[i]constr[j]]name
& ": " & decimal_pair (z);
fi
endfor;
endfor
enddef;
vardef decimal_ (text n) =
if known n: decimal n else: "?" fi
enddef;
vardef decimal_pair (text z) =
"(" & decimal_ (xpart z) & "," & decimal_ (ypart z) & ")"
enddef;
def show_diagram_ expr frame =
if (screen_cols < w + 2 xpart frame) or (screen_rows < h + 2 ypart frame):
screen_cols := w + 2 xpart frame;
screen_rows := h + 2 ypart frame;
openwindow currentwindow
from origin to (screen_rows, screen_cols)
at (- xpart frame, h + ypart frame);
fi
showit_;
if showstopping > 0:
stop "This is diagram #" & decimal charcode
& ". Hit return to continue...";
fi
enddef;
def show_diagram =
def show_diagram =
display blankpicture inwindow currentwindow;
show_diagram_
enddef;
show_diagram_
enddef;
def show_all_diagrams expr frame =
def showit = show_diagram frame enddef;
displaying:=1;
enddef;
endinput;
\endinput
%%
%% End of file `feynmp.mp'.

File Metadata

Mime Type
text/x-python
Expires
Wed, May 14, 11:49 AM (4 h, 16 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
4945184
Default Alt Text
feynmp.mp (57 KB)

Event Timeline