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.
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.)