Search code examples
pythongraphicspyx

Filling a closed curve in PyX (python) failing


I am clearly misunderstanding how closed curves and filling a closed curve works in PyX. I'm building a closed curve from four parts, but the filling fails depending on how I define one of the four curves. Below is a minimal working/failing example and the output. Why does the first definition of upArc work but the second one does not?

from pyx import *
c = canvas.canvas()
cL = canvas.canvas()
cR = canvas.canvas()


upArc = path.path(path.arc(0,3,1,180,0))
right = path.line(1,3,1,0)
downArc = path.path(path.arcn(0,0,1,0,180))
left  = path.line(-1,0,-1,3)
p = upArc+right+downArc<<left

cR.fill(p,[color.rgb.blue])
cR.stroke(p)


upArc = path.path(path.arc(0,0,1,180,0)).transformed(trafo.translate(0,3))
right = path.line(1,3,1,0)
downArc = path.path(path.arcn(0,0,1,0,180))
left  = path.line(-1,0,-1,3)
p = upArc+right+downArc<<left

cL.fill(p,[color.rgb.blue])
cL.stroke(p)



c.insert(cL,[trafo.translate(-2,0)])
c.insert(cR,[trafo.translate( 2,0)])
c.writePDFfile("minfail")

A picture of the results. A picture of the results.


Solution

  • PyX uses the postscript path model, which can contain several subpaths within a path. (Think of using a path element moveto within a path.) When filling such paths, things like you observe happen. Note that the arc contains an implicit moveto at the beginning, which for filling is taken like a lineto, but not for stroking. This is why it makes a difference to use the add operator + and the join operator <<. Switching to join resolves your problem.

    (You can use

    print(p.normpath().normsubpaths)
    

    to see, that you have several normsubpaths when adding the paths, even though the arclen does not alter, as the moveto commands from one normsubpath to the next are not part of the arc length.)