Exemple #1
0
    def draw(self, canvas):
        """Draw the line on the supplied canvas."""
        styles = self.styles + self.arrows
        if config.getOptions().DEBUG:
            print("Drawing " + str(self.__class__) + " with styles = " + str(styles))
        mypath = [self.getVisiblePath(), self.getDeformedPath(+1), self.getDeformedPath(-1)]
        if self.inverted:
            mypath = mypath[::-1]
        if config.getOptions().DRAFT or not self.is3D:
            for i in range(3):
                canvas.stroke(mypath[i], styles)
        else:
            ass, bs = mypath[0].intersect(mypath[1])
            ass, cs = mypath[0].intersect(mypath[2])
            ps = [ass[:], bs[:], cs[:]]

            for i in range(3):
                params = []
                for a in range(len(ps[i])): ## TODO: better endpoint cut vetoing
                    if (a%3)!=i:
                        params.append(ps[i][a] - self.skipsize3D)
                        params.append(ps[i][a] + self.skipsize3D)
                pathbits = mypath[i].split(params)
                on = True
                for pathbit in pathbits:
                    if on:
                        canvas.stroke(pathbit, styles)
                    on = not on

        for l in self.labels:
            l.draw(canvas)
Exemple #2
0
    def draw(self, canvas):
        """Draw the line on the supplied canvas."""
        styles = self.styles + self.arrows
        if config.getOptions().DEBUG:
            print("Drawing " + str(self.__class__) + " with styles = " + str(styles))
        mypath = self.getDeformedPath()
        if config.getOptions().DRAFT or not self.is3D:
            canvas.stroke(mypath, styles)
        else:
            para = pyx.deformer.parallel(0.001)
            ass, bs, cs = para.normpath_selfintersections(mypath.normpath(), epsilon=0.01)
            coil_params = []
            for b in bs:
                coil_params.append(b[self.parity3D] - self.skipsize3D)
                coil_params.append(b[self.parity3D] + self.skipsize3D)
            pathbits = mypath.split(coil_params)
            on = True
            for pathbit in pathbits:
                if on:
                    canvas.stroke(pathbit, styles)
                on = not on

        ## Labels
        for l in self.labels:
            l.draw(canvas)
Exemple #3
0
    def draw(self, canvas):
        """Draw the line on the supplied canvas."""
        styles = self.styles + self.arrows
        if config.getOptions().DEBUG:
            print "Drawing " + str(self.__class__) + " with styles = " + str(styles)
        mypath = self.getDeformedPath()
        if config.getOptions().DRAFT or not self.is3D:
            canvas.stroke(mypath, styles)
        else:
            para = pyx.deformer.parallel(0.001)
            ass, bs, cs = para.normpath_selfintersections(mypath.normpath(), epsilon=0.01)
            coil_params = []
            for b in bs:
                coil_params.append(b[self.parity3D] - self.skipsize3D)
                coil_params.append(b[self.parity3D] + self.skipsize3D)
            pathbits = mypath.split(coil_params)
            on = True
            for pathbit in pathbits:
                if on:
                    canvas.stroke(pathbit, styles)
                on = not on

        ## Labels
        for l in self.labels:
            l.draw(canvas)
Exemple #4
0
    def draw(self, canvas):
        """Draw the line on the supplied canvas."""
        styles = self.styles + self.arrows
        if config.getOptions().DEBUG:
            print "Drawing " + str(self.__class__) + " with styles = " + str(styles)
        mypath = [self.getVisiblePath(), self.getDeformedPath(+1), self.getDeformedPath(-1)]
        if self.inverted:
            mypath = mypath[::-1]
        if config.getOptions().DRAFT or not self.is3D:
            for i in range(3):
                canvas.stroke(mypath[i], styles)
        else:
            ass, bs = mypath[0].intersect(mypath[1])
            ass, cs = mypath[0].intersect(mypath[2])
            ps = [ass[:], bs[:], cs[:]]

            for i in range(3):
                params = []
                for a in range(len(ps[i])): ## TODO: better endpoint cut vetoing
                    if (a%3)!=i:
                        params.append(ps[i][a] - self.skipsize3D)
                        params.append(ps[i][a] + self.skipsize3D)
                pathbits = mypath[i].split(params)
                on = True
                for pathbit in pathbits:
                    if on:
                        canvas.stroke(pathbit, styles)
                    on = not on

        for l in self.labels:
            l.draw(canvas)
Exemple #5
0
 def bend(self, amount):
     """Bend the line to the right by a given distance."""
     if amount == 0:
         self.arcthrupoint = None
         return self
     middle = self.p1.midpoint(self.p2)
     nx = (middle.y() - self.p1.y()) / abs(self.p1.distance(middle))
     ny = (self.p1.x() - middle.x()) / abs(self.p1.distance(middle))
     vx = middle.x() - self.p1.x()
     vy = middle.y() - self.p1.y()
     if (vx * ny - vy * nx) > 0:
         nx *= -1
         ny *= -1
     arcpoint = Point(middle.x() + amount * nx, middle.y() + amount * ny)
     if config.getOptions().VDEBUG:
         FeynDiagram.currenDiagram.currentCanvas.stroke(
             pyx.path.line(middle.x(), middle.y(), arcpoint.x(),
                           arcpoint.y()), [color.rgb.blue])
     self.arcThru(arcpoint)
     if config.getOptions().DEBUG:
         print(self.getVisiblePath())
     if config.getOptions().VDEBUG:
         FeynDiagram.currenDiagram.currentCanvas.stroke(
             self.getVisiblePath(), [color.rgb.blue])
     return self
Exemple #6
0
 def addLabel(self, text, displace=0.3, angle = 0):
     """Add a LaTeX label to this point, either via parameters or actually as
     a PointLable object."""
     if config.getOptions().DEBUG:
         print "Adding label: " + text
     self.labels.append(PointLabel(text=text, point=self, displace=displace, angle=angle))
     if config.getOptions().DEBUG:
         print "Labels = " + str(self.labels)
     return self
Exemple #7
0
 def addLabel(self, text, displace=-0.15, angle = 0, size=pyx.text.size.normalsize, halign=CENTER, valign=None):
     """Add a label."""
     if config.getOptions().DEBUG:
         print("Adding label: " + text)
     self.labels.append(PointLabel(text=text, point=self,
                                   displace=displace, angle=angle, size=size, halign=halign, valign=valign))
     if config.getOptions().DEBUG:
         print("Labels = " + str(self.labels))
     return self
Exemple #8
0
    def draw(self, canvas):
        """Draw the line on the supplied canvas."""
        styles = self.styles + self.arrows
        if config.getOptions().DEBUG:
            print("Drawing " + str(self.__class__) + " with styles = " +
                  str(styles))
        mypath1 = self.getVisiblePath()
        mypath2 = self.getDeformedPath()
        if config.getOptions().DRAFT or not self.is3D:
            canvas.stroke(mypath1, styles)
            canvas.stroke(mypath2, styles)
        else:
            ass, bs = mypath1.intersect(mypath2)
            params1, params2 = [], []

            parity1 = True
            if self.parity3D == 0:
                parity1 = False
            for a in ass:
                if parity1:
                    params1.append(a - self.skipsize3D)
                    params1.append(a + self.skipsize3D)
                parity1 = not parity1
            pathbits1 = mypath1.split(params1)
            on = True
            for pathbit in pathbits1:
                if on:
                    canvas.stroke(pathbit, styles)
                on = not on

            parity2 = False
            if self.parity3D == 0:
                parity2 = True

            for b in bs:
                if parity2:
                    params2.append(b - self.skipsize3D)
                    params2.append(b + self.skipsize3D)
                parity2 = not parity2
            para = pyx.deformer.parallel(0.001)
            sas, sbs, scs = para.normpath_selfintersections(mypath2.normpath(),
                                                            epsilon=0.01)
            coil_params = []
            for b in sbs:
                coil_params.append(b[self.parity3D] - self.skipsize3D)
                coil_params.append(b[self.parity3D] + self.skipsize3D)
            params2 += coil_params
            params2.sort()
            pathbits2 = mypath2.split(params2)
            on = True
            for pathbit in pathbits2:
                if on:
                    canvas.stroke(pathbit, styles)
                on = not on

        for l in self.labels:
            l.draw(canvas)
Exemple #9
0
 def addLabel(self, text, displace=-0.15, angle = 0):
     """Add a label."""
     if config.getOptions().DEBUG:
         print "Adding label: " + text
     self.labels.append(PointLabel(text=text, point=self,
                                   displace=displace, angle=angle))
     if config.getOptions().DEBUG:
         print "Labels = " + str(self.labels)
     return self
Exemple #10
0
    def draw(self, canvas):
        """Draw the line on the supplied canvas."""
        styles = self.styles + self.arrows
        if config.getOptions().DEBUG:
            print "Drawing " + str(self.__class__) + " with styles = " + str(styles)
        mypath1 = self.getVisiblePath()
        mypath2 = self.getDeformedPath()
        if config.getOptions().DRAFT or not self.is3D:
            canvas.stroke(mypath1, styles)
            canvas.stroke(mypath2, styles)
        else:
            ass, bs = mypath1.intersect(mypath2)
            params1, params2 = [], []

            parity1 = True
            if self.parity3D == 0:
                parity1 = False
            for a in ass:
                if parity1:
                    params1.append(a - self.skipsize3D)
                    params1.append(a + self.skipsize3D)
                parity1 = not parity1
            pathbits1 = mypath1.split(params1)
            on = True
            for pathbit in pathbits1:
                if on:
                    canvas.stroke(pathbit, styles)
                on = not on

            parity2 = False
            if self.parity3D == 0:
                parity2 = True

            for b in bs:
                if parity2:
                    params2.append(b - self.skipsize3D)
                    params2.append(b + self.skipsize3D)
                parity2 = not parity2
            para = pyx.deformer.parallel(0.001)
            sas, sbs, scs = para.normpath_selfintersections(mypath2.normpath(), epsilon=0.01)
            coil_params = []
            for b in sbs:
                coil_params.append(b[self.parity3D] - self.skipsize3D)
                coil_params.append(b[self.parity3D] + self.skipsize3D)
            params2 += coil_params
            params2.sort()
            pathbits2 = mypath2.split(params2)
            on = True
            for pathbit in pathbits2:
                if on:
                   canvas.stroke(pathbit, styles)
                on = not on

        for l in self.labels:
            l.draw(canvas)
Exemple #11
0
 def addLabel(self, text, pos=0.5, displace=-0.25, angle = 0, size=pyx.text.size.normalsize, halign=CENTER, valign=None, **kwargs):
     """Add a LaTeX label to this line, either via parameters or actually as
     a TeXLabel object."""
     if config.getOptions().DEBUG:
         print("Adding label: " + text)
     #if text.__class__ == "Label":
     #    self.labels.append(label)
     #else:
     self.labels.append(LineLabel(text=text, line=self, pos=pos, displace=displace, angle=angle, size=size, halign=halign, valign=valign))
     if config.getOptions().DEBUG:
         print("Labels = " + str(self.labels))
     return self
Exemple #12
0
 def addLabel(self, text, pos=0.5, displace=-0.25, angle = 0, size=pyx.text.size.normalsize):
     """Add a LaTeX label to this line, either via parameters or actually as
     a TeXLable object."""
     if config.getOptions().DEBUG:
         print "Adding label: " + text
     #if text.__class__ == "Label":
     #    self.labels.append(label)
     #else:
     self.labels.append(LineLabel(text=text, line=self, pos=pos, displace=displace, angle=angle, size=size))
     if config.getOptions().DEBUG:
         print "Labels = " + str(self.labels)
     return self
Exemple #13
0
    def draw(self, canvas):
        """Draw this arrow on the supplied canvas."""
        p = self.line.getPath()
        posparam = p.begin() + self.pos * p.arclen() 
        x, y = self.line.fracpoint(self.pos).getXY()
        arrx, arry = self.line.fracpoint(self.pos+self.length/2./p.arclen()).getXY()
        endx, endy = self.line.fracpoint(self.pos-self.length/2./p.arclen()).getXY() 

        ## Calculate the displacement from the line
        displacement = self.displace
        intrinsicwidth = pyx.unit.length(0.1)
        if hasattr(self.line, "arcradius"):
            intrinsicwidth = self.line.arcradius
        if displacement > 0:
            displacement += intrinsicwidth
        else:
            displacement -= intrinsicwidth
        if config.getOptions().DEBUG:
            print "Displacement = ", displacement

        ## Position the arrow on the right hand side of lines
        tangent = p.tangent(posparam, displacement)
        normal = tangent.transformed(pyx.trafo.rotate(90, x, y))
        nx, ny = normal.atend()
        nxcm, nycm = pyx.unit.tocm(nx - x), pyx.unit.tocm(ny - y)
        vx, vy = p.atbegin()
        vxcm, vycm = pyx.unit.tocm(x - vx), pyx.unit.tocm(y - vy)

        ## If the arrow is on the left, flip it by 180 degrees
        if (vxcm * nycm - vycm * nxcm) > 0:
            normal = normal.transformed(pyx.trafo.rotate(180, x, y))
            nx, ny = normal.atend()
        if displacement < 0:
            normal = normal.transformed(pyx.trafo.rotate(180, x, y))
            nx, ny = normal.atend()
        if config.getOptions().VDEBUG:
            FeynDiagram.currentCanvas.stroke(normal)

        ## Displace the arrow by this normal vector
        endx, endy = endx + (nx-x), endy + (ny-y)
        arrx, arry = arrx + (nx-x), arry + (ny-y)

        if self.sense<0.:
           arrx, arry, endx, endy = endx, endy, arrx, arry

        linepath = pyx.deco.decoratedpath(
                       pyx.path.path(pyx.path.moveto(endx,endy),
                                     pyx.path.lineto(arrx,arry)))
        styles = [pyx.deco.earrow(size=self.size, angle=self.angle,
                        constriction=self.constriction)]
        canvas.stroke(linepath.path,styles)
Exemple #14
0
    def draw(self, canvas):
        """Draw the line on the supplied canvas."""
        styles = self.styles + self.arrows
        if config.getOptions().DEBUG:
            print("Drawing " + str(self.__class__) + " with styles = " +
                  str(styles))
        mypath1 = self.getDeformedPath(+1)
        mypath2 = self.getDeformedPath(-1)
        if self.inverted:
            mypathtmp = mypath1
            mypath1 = mypath2
            mypath2 = mypathtmp
        if config.getOptions().DRAFT or not self.is3D:
            canvas.stroke(mypath1, styles)
            canvas.stroke(mypath2, styles)
        else:
            ass, bs = mypath1.intersect(mypath2)
            params1, params2 = [], []

            parity1 = True
            if self.parity3D == 0:
                parity1 = False
            for a in ass[1:]:  ## TODO: better endpoint cut vetoing
                if parity1:
                    params1.append(a - self.skipsize3D)
                    params1.append(a + self.skipsize3D)
                parity1 = not parity1
            pathbits1 = mypath1.split(params1)
            on = True
            for pathbit in pathbits1:
                if on:
                    canvas.stroke(pathbit, styles)
                on = not on

            parity2 = False
            if self.parity3D == 0:
                parity2 = True
            for b in bs[1:]:  ## TODO: better endpoint cut vetoing
                if parity2:
                    params2.append(b - self.skipsize3D)
                    params2.append(b + self.skipsize3D)
                parity2 = not parity2
            pathbits2 = mypath2.split(params2)
            on = True
            for pathbit in pathbits2:
                if on:
                    canvas.stroke(pathbit, styles)
                on = not on

        for l in self.labels:
            l.draw(canvas)
Exemple #15
0
    def draw(self, canvas):
        """Draw the line on the supplied canvas."""
        styles = self.styles + self.arrows
        if config.getOptions().DEBUG:
            print "Drawing " + str(self.__class__) + " with styles = " + str(styles)
        mypath1 = self.getDeformedPath(+1)
        mypath2 = self.getDeformedPath(-1)
        if self.inverted:
            mypathtmp = mypath1
            mypath1 = mypath2
            mypath2 = mypathtmp
        if config.getOptions().DRAFT or not self.is3D:
            canvas.stroke(mypath1, styles)
            canvas.stroke(mypath2, styles)
        else:
            ass, bs = mypath1.intersect(mypath2)
            params1, params2 = [], []

            parity1 = True
            if self.parity3D == 0:
                parity1 = False
            for a in ass[1:]: ## TODO: better endpoint cut vetoing
                if parity1:
                    params1.append(a - self.skipsize3D)
                    params1.append(a + self.skipsize3D)
                parity1 = not parity1
            pathbits1 = mypath1.split(params1)
            on = True
            for pathbit in pathbits1:
                if on:
                    canvas.stroke(pathbit, styles)
                on = not on

            parity2 = False
            if self.parity3D == 0:
                parity2 = True
            for b in bs[1:]: ## TODO: better endpoint cut vetoing
                if parity2:
                    params2.append(b - self.skipsize3D)
                    params2.append(b + self.skipsize3D)
                parity2 = not parity2
            pathbits2 = mypath2.split(params2)
            on = True
            for pathbit in pathbits2:
                if on:
                    canvas.stroke(pathbit, styles)
                on = not on

        for l in self.labels:
            l.draw(canvas)
Exemple #16
0
    def draw(self, canvas):
        """Draw this label on the supplied canvas."""
        p = self.line.getPath()
        #x, y = self.line.fracPoint(self.pos).getXY()
        posparam = p.begin() + self.pos * p.arclen()
        x, y = p.at(posparam)

        ## Calculate the displacement from the line
        displacement = self.displace
        intrinsicwidth = pyx.unit.length(0.1)
        if hasattr(self.line, "arcradius"):
            intrinsicwidth = self.line.arcradius
        if displacement > 0:
            displacement += intrinsicwidth
        else:
            displacement -= intrinsicwidth
        if config.getOptions().DEBUG:
            print("Displacement = ", displacement)

        ## Position the label on the right hand side of lines
        tangent = p.tangent(posparam, displacement)
        normal = tangent.transformed(pyx.trafo.rotate(90, x, y))
        nx, ny = normal.atend()
        nxcm, nycm = pyx.unit.tocm(nx - x), pyx.unit.tocm(ny - y)
        vx, vy = p.atbegin()
        vxcm, vycm = pyx.unit.tocm(x - vx), pyx.unit.tocm(y - vy)

        ## If the label is on the left, flip it by 180 degrees
        if (vxcm * nycm - vycm * nxcm) > 0:
            normal = normal.transformed(pyx.trafo.rotate(180, x, y))
            nx, ny = normal.atend()
        if displacement < 0:
            normal = normal.transformed(pyx.trafo.rotate(180, x, y))
            nx, ny = normal.atend()
        if config.getOptions().VDEBUG:
            FeynDiagram.currentDiagram.currentCanvas.stroke(normal)

        ## Displace the label by this normal vector
        x, y = nx, ny

        textattrs = pyx.attr.mergeattrs(
            [pyx.text.halign.center, pyx.text.vshift.mathaxis, self.size] +
            self.textattrs)
        t = pyx.text.defaulttexrunner.text(x, y, self.text, textattrs)
        #t.linealign(self.displace,
        #            math.cos(self.angle * math.pi/180),
        #            math.sin(self.angle * math.pi/180))
        canvas.insert(t)
Exemple #17
0
    def draw(self, canvas):
        """Draw this label on the supplied canvas."""
        p = self.line.getPath()
        #x, y = self.line.fracPoint(self.pos).getXY()
        posparam = p.begin() + self.pos * p.arclen()
        x, y = p.at(posparam)

        ## Calculate the displacement from the line
        displacement = self.displace
        intrinsicwidth = pyx.unit.length(0.1)
        if hasattr(self.line, "arcradius"):
            intrinsicwidth = self.line.arcradius
        if displacement > 0:
            displacement += intrinsicwidth
        else:
            displacement -= intrinsicwidth
        if config.getOptions().DEBUG:
            print "Displacement = ", displacement

        ## Position the label on the right hand side of lines
        tangent = p.tangent(posparam, displacement)
        normal = tangent.transformed(pyx.trafo.rotate(90, x, y))
        nx, ny = normal.atend()
        nxcm, nycm = pyx.unit.tocm(nx - x), pyx.unit.tocm(ny - y)
        vx, vy = p.atbegin()
        vxcm, vycm = pyx.unit.tocm(x - vx), pyx.unit.tocm(y - vy)

        ## If the label is on the left, flip it by 180 degrees
        if (vxcm * nycm - vycm * nxcm) > 0:
            normal = normal.transformed(pyx.trafo.rotate(180, x, y))
            nx, ny = normal.atend()
        if displacement < 0:
            normal = normal.transformed(pyx.trafo.rotate(180, x, y))
            nx, ny = normal.atend()
        if config.getOptions().VDEBUG:
            FeynDiagram.currentDiagram.currentCanvas.stroke(normal)

        ## Displace the label by this normal vector
        x, y = nx, ny

        textattrs = pyx.attr.mergeattrs([pyx.text.halign.center,
                                         pyx.text.vshift.mathaxis,
                                         self.size] + self.textattrs)
        t = pyx.text.defaulttexrunner.text(x, y, self.text, textattrs)
        #t.linealign(self.displace,
        #            math.cos(self.angle * math.pi/180),
        #            math.sin(self.angle * math.pi/180))
        canvas.insert(t)
Exemple #18
0
 def add(self, *objs):
     """Add an object to the diagram."""
     for obj in objs:
         if config.getOptions().DEBUG:
             print "#objs = %d" % len(self.__objs)
         offset = 0
         if obj.__dict__.has_key("layeroffset"):
             #print "offset =", obj.layeroffset
             offset = obj.layeroffset
         self.highestautolayer += 1
         obj.setDepth(self.highestautolayer + offset)
         if config.getOptions().DEBUG:
             print "Object %s layer = %d + %d = %d" % \
                   (obj.__class__, self.highestautolayer, offset,
                    self.highestautolayer + offset)
         self.__objs.append(obj)
Exemple #19
0
    def getDeformedPath(self):
        """Get the path with the decorative deformation."""
        intwindings = int(self.frequency * pyx.unit.tocm(self.getVisiblePath().arclen()) /
                          pyx.unit.tocm(self.arcradius))
        intwindings += self.extras
        sign = 1
        if self.inverted: sign = -1        
        vispath = self.getVisiblePath()
        curveradii = vispath.curveradius([i/10.0 for i in range(0,11)])
        mincurveradius = None
        for curveradius in curveradii:
            try:
                curveradius = abs(curveradius/pyx.unit.m)
                #if config.getOptions().DEBUG:
                #    print self.__class__, "- curve radius = ", curveradius
                if (mincurveradius is None or curveradius < mincurveradius):
                    mincurveradius = curveradius
            except:
                pass
        numhloopcurves = 5
        if mincurveradius is not None:
            numhloopcurves += int(0.1/mincurveradius)
        if config.getOptions().DEBUG:
            print(self.__class__, "- min curvature radius = ", mincurveradius, "->", numhloopcurves, "curves/hloop")

        defo = pyx.deformer.cycloid(self.arcradius, intwindings, curvesperhloop=numhloopcurves,
                                    skipfirst=0.0, skiplast=0.0, turnangle=0, sign=sign)
        return defo.deform(vispath)
Exemple #20
0
 def add(self, *objs):
     """Add an object to the diagram."""
     for obj in objs:
         if config.getOptions().DEBUG:
             print("#objs = %d" % len(self.__objs))
         offset = 0
         if "layeroffset" in obj.__dict__:
             #print "offset =", obj.layeroffset
             offset = obj.layeroffset
         self.highestautolayer += 1
         obj.setDepth(self.highestautolayer + offset)
         if config.getOptions().DEBUG:
             print("Object %s layer = %d + %d = %d" % \
                   (obj.__class__, self.highestautolayer, offset,
                    self.highestautolayer + offset))
         self.__objs.append(obj)
Exemple #21
0
    def getDeformedPath(self):
        """Get the path with the decorative deformation."""
        intwindings = int(pyx.unit.tocm(self.getVisiblePath().arclen()) /
                          pyx.unit.tocm(self.arcradius))
        sign = 1
        if self.inverted: sign = -1

        vispath = self.getVisiblePath()
        curveradii = vispath.curveradius([i/10.0 for i in range(0,11)])
        mincurveradius = None
        for curveradius in curveradii:
            try:
                curveradius = abs(mincurveradius/pyx.unit.m)
                #if config.getOptions().DEBUG:
                #    print self.__class__, "- curvature radius = ", curveradius
                if (mincurveradius is None or curveradius < mincurveradius):
                    mincurveradius = curveradius
            except:
                pass

        ## Use curvature info to increase number of curve sections
        numhloopcurves = 5
        if mincurveradius is not None:
            numhloopcurves += int(0.1/mincurveradius)
        if config.getOptions().DEBUG:
            print self.__class__, "- min curve radius = ", mincurveradius, "->", numhloopcurves, "curves/hloop"

        defo = pyx.deformer.cycloid(self.arcradius, intwindings, curvesperhloop=numhloopcurves,
                                    skipfirst=0.0, skiplast=0.0, turnangle=0, sign=sign)
        return defo.deform(vispath)
Exemple #22
0
 def draw(self, canvas):
     """Draw the line on the supplied canvas."""
     styles = self.styles + self.arrows
     if config.getOptions().DEBUG:
         print "Drawing " + str(self.__class__) + " with styles = " + str(styles)
     canvas.stroke(self.getDeformedPath(), styles)
     for l in self.labels:
         l.draw(canvas)
Exemple #23
0
 def draw(self, canvas):
     """Draw the line on the supplied canvas."""
     styles = self.styles + self.arrows
     if config.getOptions().DEBUG:
         print("Drawing " + str(self.__class__) + " with styles = " + str(styles))
     canvas.stroke(self.getDeformedPath(), styles)
     for l in self.labels:
         l.draw(canvas)
Exemple #24
0
    def __cmp__(self, other):
        """Compare with another visible class, just using layers."""
        if other is None:
            return -1

        if config.getOptions().DEBUG:
            print "Comparing visible classes: ", self.__class__, "->", self.getDepth(), "vs.", other.__class__, "->", other.getDepth()
        else:
            return cmp(self.getDepth(), other.getDepth())
Exemple #25
0
 def addLabel(self,
              text,
              displace=0.3,
              angle=0,
              size=pyx.text.size.normalsize):
     """Add a LaTeX label to this point, either via parameters or actually as
     a PointLable object."""
     if config.getOptions().DEBUG:
         print("Adding label: " + text)
     self.labels.append(
         PointLabel(text=text,
                    point=self,
                    displace=displace,
                    angle=angle,
                    size=size))
     if config.getOptions().DEBUG:
         print("Labels = " + str(self.labels))
     return self
Exemple #26
0
 def draw(self, canvas):
     """Drwa this line on the given canvas."""
     path = self.getVisiblePath()
     styles = self.styles + self.arrows
     if config.getOptions().DEBUG:
         print("Drawing " + str(self.__class__) + " with styles = " + str(styles))
         print(path)
     canvas.stroke(path, styles)
     for l in self.labels:
         l.draw(canvas)
Exemple #27
0
 def draw(self, canvas):
     """Drwa this line on the given canvas."""
     path = self.getVisiblePath()
     styles = self.styles + self.arrows
     if config.getOptions().DEBUG:
         print "Drawing " + str(self.__class__) + " with styles = " + str(styles)
         print path
     canvas.stroke(path, styles)
     for l in self.labels:
         l.draw(canvas)
Exemple #28
0
 def draw(self, canvas):
     """Draw this scalar line on the given canvas."""
     path = self.getVisiblePath()
     styles = self.styles + [self.linestyle] + self.arrows
     ## TODO: call base class method?
     if config.getOptions().DEBUG:
         print("Drawing " + str(self.__class__) + " with styles = " + str(styles))
         print(path)
     canvas.stroke(path, styles)
     for l in self.labels:
         l.draw(canvas)
Exemple #29
0
    def __cmp__(self, other):
        """Compare with another visible class, just using layers."""
        if other is None:
            return -1

        if config.getOptions().DEBUG:
            print("Comparing visible classes: ", \
                  self.__class__, "->", self.getDepth(), "vs.", \
                  other.__class__, "->", other.getDepth())
        else:
            return cmp(self.getDepth(), other.getDepth())
Exemple #30
0
 def draw(self, canvas):
     """Draw this scalar line on the given canvas."""
     path = self.getVisiblePath()
     styles = self.styles + [pyx.style.linestyle.dotted] + self.arrows
     ## TODO: call base class method?
     if config.getOptions().DEBUG:
         print "Drawing " + str(self.__class__) + " with styles = " + str(styles)
         print path
     canvas.stroke(path, styles)
     for l in self.labels:
         l.draw(canvas)
Exemple #31
0
    def drawToCanvas(self):
        """Draw the components of this diagram in a well-defined order."""
        if config.getOptions().DEBUG:
            print("Final #objs = %d" % len(self.__objs))
        if config.getOptions().VDEBUG:
            print("Running in visual debug mode")

        ## Sort drawing objects by layer
        drawingobjs = self.__objs
        try:
            drawingobjs.sort()
        except:
            pass

        ## Draw each object
        for obj in drawingobjs:
            if config.getOptions().DEBUG:
                print("Depth = ", obj.getDepth())
            obj.draw(self.currentCanvas)

        return self.currentCanvas
Exemple #32
0
 def draw(self, canvas):
     """Draw this label on the supplied canvas."""
     if config.getOptions().VDEBUG:
         canvas.fill(pyx.path.circle(self.point.getX(),
                                     self.point.getY(), 0.05), [pyx.color.rgb.green])
     x = self.point.getX() + self.displace * math.cos(math.radians(self.angle))
     y = self.point.getY() + self.displace * math.sin(math.radians(self.angle))
     textattrs = pyx.attr.mergeattrs([pyx.text.halign.center,
                                      pyx.text.vshift.mathaxis,
                                      self.size] + self.textattrs)
     t = pyx.text.defaulttexrunner.text(x, y, self.text, textattrs)
     canvas.insert(t)
Exemple #33
0
 def bend(self, amount):
     """Bend the line to the right by a given distance."""
     middle = self.p1.midpoint(self.p2)
     nx = (middle.y() - self.p1.y()) / abs(self.p1.distance(middle))
     ny = (self.p1.x() - middle.x()) / abs(self.p1.distance(middle))
     vx = middle.x() - self.p1.x()
     vy = middle.y() - self.p1.y()
     if (vx * ny - vy * nx) > 0:
         nx *= -1
         ny *= -1
     arcpoint = Point(middle.x() + amount * nx, middle.y() + amount * ny)
     if config.getOptions().VDEBUG:
         FeynDiagram.currenDiagram.currentCanvas.stroke(
             pyx.path.line(middle.x(), middle.y(), arcpoint.x(),
                           arcpoint.y()), [color.rgb.blue] )
     self.arcThru(arcpoint)
     if config.getOptions().DEBUG:
         print self.getVisiblePath()
     if config.getOptions().VDEBUG:
         FeynDiagram.currenDiagram.currentCanvas.stroke(self.getVisiblePath(), [color.rgb.blue])
     return self
Exemple #34
0
    def drawToCanvas(self):
        """Draw the components of this diagram in a well-defined order."""
        if config.getOptions().DEBUG:
            print "Final #objs = %d" % len(self.__objs)
        if config.getOptions().VDEBUG:
            print "Running in visual debug mode"

        ## Sort drawing objects by layer
        drawingobjs = self.__objs
        try:
            drawingobjs.sort()
        except:
            pass
            
        ## Draw each object
        for obj in drawingobjs:
            if config.getOptions().DEBUG:
                print "Depth = ", obj.getDepth()
            obj.draw(self.currentCanvas)

        return self.currentCanvas
Exemple #35
0
 def getVisiblePath(self):
     """Find the subpath between the endpoints which isn't overshadowed by a blob of some kind"""
     p1path = self.p1.getPath()
     p2path = self.p2.getPath()
     vispath = self.getPath()
     if config.getOptions().VDEBUG:
         FeynDiagram.currenDiagram.currentCanvas.stroke(vispath, [color.rgb.green])
     if p1path:
         ass, bs = p1path.intersect(vispath)
         for b in bs:
             subpaths = vispath.split(b)
             if len(subpaths) > 1:
                 if config.getOptions().DEBUG:
                     print "Num subpaths 1 = %d" % len(subpaths)
                 subpaths.sort(
                     lambda x, y :
                     int(pyx.unit.tocm(x.arclen() - y.arclen()) /
                         math.fabs(pyx.unit.tocm(x.arclen() - y.arclen()))) )
                 vispath = subpaths[-1]
                 if config.getOptions().VDEBUG:
                     FeynDiagram.currenDiagram.currentCanvas.stroke(subpaths[0], [color.rgb.blue])
             if config.getOptions().VDEBUG:
                 for a in ass:
                     ix, iy = p1path.at(a)
                     FeynDiagram.currenDiagram.currentCanvas.fill(pyx.path.circle(ix, iy, 0.05),
                                                    [color.rgb.green])
     if p2path:
         ass, bs = p2path.intersect(vispath)
         for b in bs:
             subpaths = vispath.split(b)
             if len(subpaths) > 1:
                 if config.getOptions().DEBUG:
                     print "Num subpaths 2 = %d" % len(subpaths)
                 subpaths.sort(
                     lambda x, y :
                     int(pyx.unit.tocm(x.arclen() - y.arclen()) /
                         math.fabs(pyx.unit.tocm(x.arclen() - y.arclen()))) )
                 vispath = subpaths[-1]
                 if config.getOptions().VDEBUG:
                     FeynDiagram.currenDiagram.currentCanvas.stroke(subpaths[0], [color.rgb.red])
             if config.getOptions().VDEBUG:
                 for a in ass:
                     ix, iy = p2path.at(a)
                     FeynDiagram.currenDiagram.currentCanvas.fill(pyx.path.circle(ix, iy, 0.05),
                                                    [color.rgb.blue])
     if config.getOptions().VDEBUG:
         FeynDiagram.currenDiagram.currentCanvas.stroke(vispath, [color.rgb.red])
     #return pyx.path.circle(-2,-1,0.2)
     return vispath
Exemple #36
0
 def draw(self, canvas):
     """Draw this label on the supplied canvas."""
     if config.getOptions().VDEBUG:
         canvas.fill(
             pyx.path.circle(self.point.getX(), self.point.getY(), 0.05),
             [pyx.color.rgb.green])
     x = self.point.getX() + self.displace * math.cos(
         math.radians(self.angle))
     y = self.point.getY() + self.displace * math.sin(
         math.radians(self.angle))
     textattrs = pyx.attr.mergeattrs([pyx.text.vshift.mathaxis, self.size] +
                                     self.textattrs)
     t = pyx.text.defaulttexrunner.text(x, y, self.text, textattrs)
     canvas.insert(t)
Exemple #37
0
 def getVisiblePath(self):
     """Find the subpath between the endpoints which isn't overshadowed by a blob of some kind"""
     p1path = self.p1.getPath()
     p2path = self.p2.getPath()
     vispath = self.getPath()
     if config.getOptions().VDEBUG:
         FeynDiagram.currenDiagram.currentCanvas.stroke(
             vispath, [color.rgb.green])
     if p1path:
         ass, bs = p1path.intersect(vispath)
         for b in bs:
             subpaths = vispath.split(b)
             if len(subpaths) > 1:
                 if config.getOptions().DEBUG:
                     print("Num subpaths 1 = %d" % len(subpaths))
                 subpaths.sort(key=lambda x: pyx.unit.tocm(x.arclen()))
                 vispath = subpaths[-1]
                 if config.getOptions().VDEBUG:
                     FeynDiagram.currenDiagram.currentCanvas.stroke(
                         subpaths[0], [color.rgb.blue])
             if config.getOptions().VDEBUG:
                 for a in ass:
                     ix, iy = p1path.at(a)
                     FeynDiagram.currenDiagram.currentCanvas.fill(
                         pyx.path.circle(ix, iy, 0.05), [color.rgb.green])
     if p2path:
         ass, bs = p2path.intersect(vispath)
         for b in bs:
             subpaths = vispath.split(b)
             if len(subpaths) > 1:
                 if config.getOptions().DEBUG:
                     print("Num subpaths 2 = %d" % len(subpaths))
                 subpaths.sort(key=lambda x: pyx.unit.tocm(x.arclen()))
                 vispath = subpaths[-1]
                 if config.getOptions().VDEBUG:
                     FeynDiagram.currenDiagram.currentCanvas.stroke(
                         subpaths[0], [color.rgb.red])
             if config.getOptions().VDEBUG:
                 for a in ass:
                     ix, iy = p2path.at(a)
                     FeynDiagram.currenDiagram.currentCanvas.fill(
                         pyx.path.circle(ix, iy, 0.05), [color.rgb.blue])
     if config.getOptions().VDEBUG:
         FeynDiagram.currenDiagram.currentCanvas.stroke(
             vispath, [color.rgb.red])
     #return pyx.path.circle(-2,-1,0.2)
     return vispath
Exemple #38
0
    def getDeformedPath(self):
        """Get the path with the decorative deformation."""
        needwindings = 1.2 * \
                       pyx.unit.tocm(self.getVisiblePath().arclen()) / \
                       pyx.unit.tocm(self.arcradius)
        ## Get the whole number of windings and make sure that it's odd so we
        ## don't get a weird double-back thing
        intwindings = int(needwindings)
        if intwindings % 2 == 0:
            intwindings -= 1
        deficit = needwindings - intwindings
        sign = 1
        if self.inverted: sign = -1

        ## Get list of curvature radii in the visible path
        vispath = self.getVisiblePath()
        curveradii = vispath.curveradius([i / 10.0 for i in range(0, 11)])
        mincurveradius = None

        ## Find the maximum curvature (set None if straight line)
        for curveradius in curveradii:
            try:
                curveradius = abs(curvature / pyx.unit.m)
                #if config.getOptions().DEBUG:
                #    print self.__class__, "- curvature radius = ", curveradius
                if (mincurveradius is None or curveradius < mincurveradius):
                    mincurveradius = curveradius
            except:
                pass

        ## Use curvature info to increase number of curve sections
        numhloopcurves = 10
        if mincurveradius is not None:
            numhloopcurves += int(0.2 / mincurveradius)
        if config.getOptions().DEBUG:
            print(self.__class__, "- min curve radius = ", mincurveradius,
                  "->", numhloopcurves, "curves/hloop")

        defo = pyx.deformer.cycloid(self.arcradius,
                                    intwindings,
                                    curvesperhloop=numhloopcurves,
                                    skipfirst=0.0,
                                    skiplast=0.0,
                                    sign=sign)
        return defo.deform(vispath)
Exemple #39
0
    def getDeformedPath(self):
        """Get the path with the decorative deformation."""
        needwindings = 1.2 * \
                       pyx.unit.tocm(self.getVisiblePath().arclen()) / \
                       pyx.unit.tocm(self.arcradius)
        ## Get the whole number of windings and make sure that it's odd so we
        ## don't get a weird double-back thing
        intwindings = int(needwindings)
        if intwindings % 2 == 0:
            intwindings -= 1
        deficit = needwindings - intwindings
        sign = 1
        if self.inverted: sign = -1

        ## Get list of curvature radii in the visible path
        vispath = self.getVisiblePath()
        curveradii = vispath.curveradius([i/10.0 for i in range(0,11)])
        mincurveradius = None

        ## Find the maximum curvature (set None if straight line)
        for curveradius in curveradii:
            try:
                curveradius = abs(curvature/pyx.unit.m)
                #if config.getOptions().DEBUG:
                #    print self.__class__, "- curvature radius = ", curveradius
                if (mincurveradius is None or curveradius < mincurveradius):
                    mincurveradius = curveradius
            except:
                pass

        ## Use curvature info to increase number of curve sections
        numhloopcurves = 10
        if mincurveradius is not None:
            numhloopcurves += int(0.2/mincurveradius)
        if config.getOptions().DEBUG:
            print self.__class__, "- min curve radius = ", mincurveradius, "->", numhloopcurves, "curves/hloop"

        defo = pyx.deformer.cycloid(self.arcradius, intwindings, curvesperhloop=numhloopcurves,
                                    skipfirst=0.0, skiplast=0.0, sign=sign)
        return defo.deform(vispath)
Exemple #40
0
    def getPath(self):
        """Get the path taken by this line."""
        if self.arcthrupoint is None:
            ## This is a simple straight line
            return pyx.path.path( pyx.path.moveto( *(self.p1.getXY()) ),
                              pyx.path.lineto( *(self.p2.getXY()) ) )
        elif (self.p1.x() == self.p2.x() and self.p1.y() == self.p2.y()):
            ## This is a tadpole-type loop and needs special care;
            ## We shall assume that the arcthrupoint is meant to be
            ## the antipode of the basepoint
            arccenter = self.p1.midpoint(self.arcthrupoint)
            arcradius = self.p1.distance(self.arcthrupoint) / 2.0

            ## TODO Why does a circle work and an arc doesn't?
            cargs = (arccenter.x(), arccenter.y(), arcradius)
            circle = pyx.path.circle(*cargs)
            line = pyx.path.line( self.p1.x(), self.p1.y(), arccenter.x(), arccenter.y())
            if config.getOptions().VDEBUG:
                FeynDiagram.currenDiagram.currentCanvas.stroke(line, [color.rgb.green])
            ass, bs = circle.intersect(line)
            subpaths = circle.split(ass[0])
            cpath = subpaths[0]
            return cpath

            ## or, with an arc...
            arcangle1 = arccenter.arg(self.p1)
            arcangle2 = arccenter.arg(self.p1) + 360
            arcargs = (arccenter.x(), arccenter.y(), arcradius, arcangle1, arcangle2)
            return pyx.path.path( pyx.path.arc(*arcargs) )

        else:
            n13, n23 = None, None
            ## Work out line gradients
            try:
                n13 = (self.p1.y() - self.arcthrupoint.y()) / (self.p1.x() - self.arcthrupoint.x())
            except ZeroDivisionError:
                if config.getOptions().DEBUG:
                    print "Grad 1 diverges"
                n13 = 1e100

            try:
                n23 = (self.p2.y() - self.arcthrupoint.y()) / (self.p2.x() - self.arcthrupoint.x())
            except ZeroDivisionError:
                if config.getOptions().DEBUG:
                    print "Grad 2 diverges"
                n23 = 1e100

            ## If gradients match,
            ## then we have a straight line, so bypass the complexity
            if n13 == n23:
                return pyx.path.path( pyx.path.moveto(*(self.p1.getXY())),
                                      pyx.path.lineto(*(self.p2.getXY())) )

            ## Otherwise work out conjugate gradients and midpoints
            m13, m23 = None, None
            try:
                m13 = -1.0 / n13
            except ZeroDivisionError:
                m13 = 1e100
            try:
                m23 = -1.0 / n23
            except ZeroDivisionError:
                m23 = 1e100
            mid13 = self.p1.midpoint(self.arcthrupoint)
            mid23 = self.p2.midpoint(self.arcthrupoint)

            ## Line y-intercepts
            c13 = mid13.y() - m13 * mid13.x()
            c23 = mid23.y() - m23 * mid23.x()

            ## Find the centre of the arc
            xcenter =  - (c23 - c13) / (m23 - m13)
            ycenter = m13 * xcenter + c13
            arccenter = Point(xcenter, ycenter)

            ## Get the angles required for drawing the arc
            arcradius = arccenter.distance(self.arcthrupoint)
            arcangle1 = arccenter.arg(self.p1)
            arcangle2 = arccenter.arg(self.p2)
            arcangle3 = arccenter.arg(self.arcthrupoint)
            arcargs = (arccenter.x(), arccenter.y(), arcradius, arcangle1, arcangle2)

            if config.getOptions().DEBUG and arcangle1 == arcangle2:
                print "Arc angles are the same - not drawing anything"

            ## Calculate cross product to determine direction of arc
            vec12 = [self.p2.x()-self.p1.x(), self.p2.y()-self.p1.y(), 0.0]
            vec13 = [self.arcthrupoint.x()-self.p1.x(), self.arcthrupoint.y()-self.p1.y(), 0.0]
            crossproductZcoord = vec12[0]*vec13[1] - vec12[1]*vec13[0]

            if crossproductZcoord < 0:
                return pyx.path.path( pyx.path.moveto(*(self.p1.getXY())),
                                      pyx.path.arc(*arcargs))
            else:
                return pyx.path.path( pyx.path.moveto(*(self.p1.getXY())),
                                      pyx.path.arcn(*arcargs))
Exemple #41
0
    def draw(self, canvas):
        """Draw this arrow on the supplied canvas."""
        p = self.line.getPath()

        x, y = self.line.fracpoint(self.pos).getXY()
        posparam = p.begin() + self.pos * p.arclen()
        arrx, arry = self.line.fracpoint(self.pos+self.length/2./p.arclen()).getXY()
        endx, endy = self.line.fracpoint(self.pos-self.length/2./p.arclen()).getXY()

        ## Calculate the displacement from the line
        displacement = self.displace
        intrinsicwidth = pyx.unit.length(0.1)
        if hasattr(self.line, "arcradius"):
            intrinsicwidth = self.line.arcradius
        if displacement > 0:
            displacement += intrinsicwidth
        else:
            displacement -= intrinsicwidth
        if config.getOptions().DEBUG:
            print "Displacement = ", displacement

        ## Position the arrow on the right hand side of lines
        tangent = p.tangent(posparam, displacement)
        normal = tangent.transformed(pyx.trafo.rotate(90, x, y))
        nx, ny = normal.atend()
        nxcm, nycm = pyx.unit.tocm(nx - x), pyx.unit.tocm(ny - y)
        vx, vy = p.atbegin()
        vxcm, vycm = pyx.unit.tocm(x - vx), pyx.unit.tocm(y - vy)

        ## If the arrow is on the left, flip it by 180 degrees
        if (vxcm * nycm - vycm * nxcm) > 0:
            normal = normal.transformed(pyx.trafo.rotate(180, x, y))
            nx, ny = normal.atend()
        if displacement < 0:
            normal = normal.transformed(pyx.trafo.rotate(180, x, y))
            nx, ny = normal.atend()
        if config.getOptions().VDEBUG:
            FeynDiagram.currentDiagram.currentCanvas.stroke(normal)

        ## Displace the arrow by this normal vector
        endx, endy = endx + (nx-x), endy + (ny-y)
        arrx, arry = arrx + (nx-x), arry + (ny-y)

        if self.sense<0.:
           arrx, arry, endx, endy = endx, endy, arrx, arry

        if not self.curved:
            linepath = pyx.path.path(pyx.path.moveto(endx,endy),
                                     pyx.path.lineto(arrx,arry))
            if self.rotation:
                rotx, roty = 0.5*(endx+arrx), 0.5*(endy+arry)
                linepath = linepath.transformed(pyx.trafo.rotate(self.rotation, rotx, roty))
            styles = [pyx.deco.earrow(size=self.size, angle=self.angle,
                                      constriction=self.constriction)]
            # Allow us to add colouring etc. to the line
            styles.extend(self.getCustomStyles())

            dist = self.stemsep
            n = self.stems
            if n>1: # helicity style arrow
                arrowtopath = linepath.split(0.8*linepath.arclen())[0]
                constrictionlen = self.size * self.constriction * \
                                  math.cos(self.angle*math.pi/360.0)
                arrowpath = pyx.deco._arrowhead(arrowtopath,
                                                linepath.arclen(),
                                                1, self.size, 45,
                                                constrictionlen)
                canvas.fill(arrowpath, self.getCustomStyles())
                path = pyx.deformer.parallel(-(n+1)/2. * dist).deform(arrowtopath)
                defo = pyx.deformer.parallel(dist)
                for m in range(n):
                    path = defo.deform(path)
                    canvas.stroke(path, self.getCustomStyles())
            else: # ordinary (momentum) arrow
                canvas.stroke(linepath, styles)
        else: # curved arrow (always momentum-style)
            curvepiece = self.line.getPath().split([
                     (self.pos*p.arclen()-self.length/2.),
                     (self.pos*p.arclen()+self.length/2.)])
            arrpiece = curvepiece[1]
            if self.sense<0:
               arrpiece = arrpiece.reversed()
            linepath = pyx.deco.decoratedpath(pyx.deformer.parallel(displacement).deform(arrpiece))
            styles = [pyx.deco.earrow(size=self.size, angle=self.angle,
                            constriction=self.constriction)]
            # Allow us to add colouring etc. to the line
            styles.extend(self.getCustomStyles())
            canvas.stroke(linepath.path,styles)
Exemple #42
0
    def draw(self, canvas):
        """Draw this arrow on the supplied canvas."""
        p = self.line.getPath()
        posparam = p.begin() + self.pos * p.arclen()
        x, y = self.line.fracpoint(self.pos).getXY()
        arrx, arry = self.line.fracpoint(self.pos + self.length / 2. /
                                         p.arclen()).getXY()
        endx, endy = self.line.fracpoint(self.pos - self.length / 2. /
                                         p.arclen()).getXY()

        ## Calculate the displacement from the line
        displacement = self.displace
        intrinsicwidth = pyx.unit.length(0.1)
        if hasattr(self.line, "arcradius"):
            intrinsicwidth = self.line.arcradius
        if displacement > 0:
            displacement += intrinsicwidth
        else:
            displacement -= intrinsicwidth
        if config.getOptions().DEBUG:
            print("Displacement = ", displacement)

        ## Position the arrow on the right hand side of lines
        tangent = p.tangent(posparam, displacement)
        normal = tangent.transformed(pyx.trafo.rotate(90, x, y))
        nx, ny = normal.atend()
        nxcm, nycm = pyx.unit.tocm(nx - x), pyx.unit.tocm(ny - y)
        vx, vy = p.atbegin()
        vxcm, vycm = pyx.unit.tocm(x - vx), pyx.unit.tocm(y - vy)

        ## If the arrow is on the left, flip it by 180 degrees
        if (vxcm * nycm - vycm * nxcm) > 0:
            normal = normal.transformed(pyx.trafo.rotate(180, x, y))
            nx, ny = normal.atend()
        if displacement < 0:
            normal = normal.transformed(pyx.trafo.rotate(180, x, y))
            nx, ny = normal.atend()
        if config.getOptions().VDEBUG:
            FeynDiagram.currentDiagram.currentCanvas.stroke(normal)

        ## Displace the arrow by this normal vector
        endx, endy = endx + (nx - x), endy + (ny - y)
        arrx, arry = arrx + (nx - x), arry + (ny - y)

        if self.sense < 0.:
            arrx, arry, endx, endy = endx, endy, arrx, arry

        if not self.curved:
            linepath = pyx.path.path(pyx.path.moveto(endx, endy),
                                     pyx.path.lineto(arrx, arry))
            styles = [
                pyx.deco.earrow(size=self.size,
                                angle=self.angle,
                                constriction=self.constriction)
            ]
            dist = self.stemsep
            n = self.stems
            if n > 1:  # helicity style arrow
                arrowtopath = linepath.split(0.8 * linepath.arclen())[0]
                constrictionlen = self.size * self.constriction * \
                                  math.cos(self.angle*math.pi/360.0)
                arrowpath = getarrowpath(arrowtopath, linepath.arclen(), 1,
                                         self.size, 45, self.constriction,
                                         constrictionlen)
                canvas.fill(arrowpath)
                path = pyx.deformer.parallel(-(n + 1) / 2. *
                                             dist).deform(arrowtopath)
                defo = pyx.deformer.parallel(dist)
                for m in range(n):
                    path = defo.deform(path)
                    canvas.stroke(path, [])
            else:  # ordinary (momentum) arrow
                canvas.stroke(linepath, styles)
        else:  # curved arrow (always momentum-style)
            curvepiece = self.line.getPath().split([
                (self.pos * p.arclen() - self.length / 2.),
                (self.pos * p.arclen() + self.length / 2.)
            ])
            arrpiece = curvepiece[1]
            if self.sense < 0:
                arrpiece = arrpiece.reversed()
            linepath = pyx.deco.decoratedpath(
                pyx.deformer.parallel(displacement).deform(arrpiece))
            styles = [
                pyx.deco.earrow(size=self.size,
                                angle=self.angle,
                                constriction=self.constriction)
            ]
            canvas.stroke(linepath.path, styles)
Exemple #43
0
    def getPath(self):
        """Get the path taken by this line."""
        if self.arcthrupoint is None:
            ## This is a simple straight line
            return pyx.path.path( pyx.path.moveto( *(self.p1.getXY()) ),
                              pyx.path.lineto( *(self.p2.getXY()) ) )
        elif (self.p1.x() == self.p2.x() and self.p1.y() == self.p2.y()):
            ## This is a tadpole-type loop and needs special care;
            ## We shall assume that the arcthrupoint is meant to be
            ## the antipode of the basepoint
            arccenter = self.p1.midpoint(self.arcthrupoint)
            arcradius = self.p1.distance(self.arcthrupoint) / 2.0

            ## TODO Why does a circle work and an arc doesn't?
            cargs = (arccenter.x(), arccenter.y(), arcradius)
            circle = pyx.path.circle(*cargs)
            line = pyx.path.line( self.p1.x(), self.p1.y(), arccenter.x(), arccenter.y())
            if config.getOptions().VDEBUG:
                FeynDiagram.currenDiagram.currentCanvas.stroke(line, [color.rgb.green])
            ass, bs = circle.intersect(line)
            subpaths = circle.split(ass[0])
            cpath = subpaths[0]
            return cpath

            ## or, with an arc...
            arcangle1 = arccenter.arg(self.p1)
            arcangle2 = arccenter.arg(self.p1) + 360
            arcargs = (arccenter.x(), arccenter.y(), arcradius, arcangle1, arcangle2)
            return pyx.path.path( pyx.path.arc(*arcargs) )

        else:
            n13, n23 = None, None
            ## Work out line gradients
            try:
                n13 = (self.p1.y() - self.arcthrupoint.y()) / (self.p1.x() - self.arcthrupoint.x())
            except ZeroDivisionError:
                if config.getOptions().DEBUG:
                    print("Grad 1 diverges")
                n13 = 1e100

            try:
                n23 = (self.p2.y() - self.arcthrupoint.y()) / (self.p2.x() - self.arcthrupoint.x())
            except ZeroDivisionError:
                if config.getOptions().DEBUG:
                    print("Grad 2 diverges")
                n23 = 1e100

            ## If gradients match,
            ## then we have a straight line, so bypass the complexity
            if n13 == n23:
                return pyx.path.path( pyx.path.moveto(*(self.p1.getXY())),
                                      pyx.path.lineto(*(self.p2.getXY())) )

            ## Otherwise work out conjugate gradients and midpoints
            m13, m23 = None, None
            try:
                m13 = -1.0 / n13
            except ZeroDivisionError:
                m13 = 1e100
            try:
                m23 = -1.0 / n23
            except ZeroDivisionError:
                m23 = 1e100
            mid13 = self.p1.midpoint(self.arcthrupoint)
            mid23 = self.p2.midpoint(self.arcthrupoint)

            ## Line y-intercepts
            c13 = mid13.y() - m13 * mid13.x()
            c23 = mid23.y() - m23 * mid23.x()

            ## Find the centre of the arc
            xcenter =  - (c23 - c13) / (m23 - m13)
            ycenter = m13 * xcenter + c13
            arccenter = Point(xcenter, ycenter)

            ## Get the angles required for drawing the arc
            arcradius = arccenter.distance(self.arcthrupoint)
            arcangle1 = arccenter.arg(self.p1)
            arcangle2 = arccenter.arg(self.p2)
            arcangle3 = arccenter.arg(self.arcthrupoint)
            arcargs = (arccenter.x(), arccenter.y(), arcradius, arcangle1, arcangle2)

            if config.getOptions().DEBUG and arcangle1 == arcangle2:
                print("Arc angles are the same - not drawing anything")

            ## Calculate cross product to determine direction of arc
            vec12 = [self.p2.x()-self.p1.x(), self.p2.y()-self.p1.y(), 0.0]
            vec13 = [self.arcthrupoint.x()-self.p1.x(), self.arcthrupoint.y()-self.p1.y(), 0.0]
            crossproductZcoord = vec12[0]*vec13[1] - vec12[1]*vec13[0]

            if crossproductZcoord < 0:
                return pyx.path.path( pyx.path.moveto(*(self.p1.getXY())),
                                      pyx.path.arc(*arcargs))
            else:
                return pyx.path.path( pyx.path.moveto(*(self.p1.getXY())),
                                      pyx.path.arcn(*arcargs))