1 """A couple of classes for decorating diagram elements."""
2
3 import pyx, math
4 from diagrams import FeynDiagram
5 from utils import Visible
6
7
8
9 -class Arrow(pyx.deco.deco, pyx.attr.attr):
10 """Arrow for Feynman diagram lines"""
11 - def __init__(self, pos=0.5, size=6*pyx.unit.v_pt, angle=45, constriction=0.8):
12 self.pos = pos
13 self.size = size
14 self.angle = angle
15 self.constriction = constriction
16
18 dp.ensurenormpath()
19 constrictionlen = self.size*self.constriction*math.cos(self.angle*math.pi/360.0)
20 arrowtopos = self.pos * dp.path.arclen()+0.5*self.size
21 arrowtopath = dp.path.split(arrowtopos)[0]
22 arrowpath = pyx.deco._arrowhead(arrowtopath, self.pos*dp.path.arclen(), 1, self.size, 45, constrictionlen)
23 dp.ornaments.fill(arrowpath)
24 return dp
25
26
27
29 """Label for Feynman diagram lines"""
30 - def __init__(self, line, text, pos=0.5, displace=0.3, angle=0):
31 self.pos = pos
32 self.size = pyx.text.size.normalsize
33 self.displace = pyx.unit.length(displace)
34 self.angle = angle
35 self.text = text
36 self.line = line
37 self.textattrs = []
38
39
41 return self.line
42
43
45 self.line = line
46 return self
47
48
49 - def draw(self, canvas):
50 p = self.line.getPath()
51
52 posparam = p.begin() + self.pos * p.arclen()
53 x, y = p.at(posparam)
54
55
56 displacement = self.displace
57 intrinsicwidth = pyx.unit.length(0.1)
58 if hasattr(self.line, "arcradius"):
59 intrinsicwidth = self.line.arcradius
60 if displacement > 0:
61 displacement += intrinsicwidth
62 else:
63 displacement -= intrinsicwidth
64 if FeynDiagram.options.DEBUG:
65 print "Displacement = ", displacement
66
67
68 tangent = p.tangent(posparam, displacement)
69 normal = tangent.transformed(pyx.trafo.rotate(90, x, y))
70 nx, ny = normal.atend()
71 nxcm, nycm = pyx.unit.tocm(nx - x), pyx.unit.tocm(ny - y)
72 vx, vy = p.atbegin()
73 vxcm, vycm = pyx.unit.tocm(x - vx), pyx.unit.tocm(y - vy)
74
75
76 if (vxcm * nycm - vycm * nxcm) > 0:
77 normal = normal.transformed(pyx.trafo.rotate(180, x, y))
78 nx, ny = normal.atend()
79 if displacement < 0:
80 normal = normal.transformed(pyx.trafo.rotate(180, x, y))
81 nx, ny = normal.atend()
82 if FeynDiagram.options.VDEBUG:
83 FeynDiagram.currentCanvas.stroke(normal)
84
85
86 x, y = nx, ny
87
88 textattrs = pyx.attr.mergeattrs([pyx.text.halign.center, pyx.text.vshift.mathaxis, self.size] + self.textattrs)
89 t = pyx.text.defaulttexrunner.text(x, y, self.text, textattrs)
90
91
92
93 canvas.insert(t)
94