Often, one wants to perform geometrical operations with a path before placing it on a canvas by stroking or filling it. For instance, one might want to intersect one path with another one, split the paths at the intersection points, and then join the segments together in a new way. PyX supports such tasks by means of a number of path methods, which we will introduce in the following.
Suppose you want to draw the radii to the intersection points of a circle with a straight line. This task can be done using the following code which results in Fig. 2.2
from pyx import *
c = canvas.canvas()
circle = path.circle(0, 0, 2)
line = path.line(-3, 1, 3, 2)
c.stroke(circle, [style.linewidth.Thick])
c.stroke(line, [style.linewidth.Thick])
isects_circle, isects_line = circle.intersect(line)
for isect in isects_circle:
isectx, isecty = circle.at(isect)
c.stroke(path.line(0, 0, isectx, isecty))
c.writeEPSfile("radii")
c.writePDFfile("radii")
![]() |
Another powerful feature of PyX is its ability to split paths at a given set of parameters. For instance, in order to fill in the previous example the segment of the circle delimited by the straight line (cf. Fig. 2.3), one first has to construct a path corresponding to the outline of this segment. The following code snippet yields this segment
arc1, arc2 = circle.split(isects_circle)
if arc1.arclen() < arc2.arclen():
arc = arc1
else:
arc = arc2
isects_line.sort()
line1, line2, line3 = line.split(isects_line)
segment = line2 << arc
![]() |
<< operator, which not only adds
the paths (which could be done using "line2 + arc"), but also
joins the last subpath of line2 and the first one of
arc. Thus, segment consists of only a single subpath
and filling works as expected.
An important issue when operating on paths is the parametrisation
used. Internally, PyX uses a parametrisation which uses an interval
of length
for each path element of a path. For instance, for a
simple straight line, the possible parameter values range from
to
, corresponding to the first and last point, respectively, of the
line. Appending another straight line, would extend this range to a
maximal value of
.
However, the situation becomes more complicated if more complex
objects like a circle are involved. Then, one could be tempted to
assume that again the parameter value ranges from
to
, because
the predefined circle consists just of one arc together with a
closepath element. However, this is not the case: the actual
range is much larger. The reason for this behaviour lies in the
internal path handling of PyX: Before performing any non-trivial
geometrical operation with a path, it will automatically be converted
into an instance of the normpath class (see also
Sect. 2.4.3). These so generated paths are already
separated in their subpaths and only contain straight lines and
Bézier curve segments. Thus, as is easily imaginable, they are much
simpler to deal with.
XXX explain normpathparams and things like p.begin(), p.end()-1,
A more geometrical way of accessing a point on the path is to use the arc length of the path segment from the first point of the path to the given point. Thus, all PyX path methods that accept a parameter value also allow the user to pass an arc length. For instance,
from math import pi r = 2 pt1 = path.circle(0, 0, r).at(r*pi) pt2 = path.circle(0, 0, r).at(r*3*pi/2) c.stroke(path.path(path.moveto(*pt1), path.lineto(*pt2)))
More information on the available path methods can be found in Sect. 2.4.1.