take into account kerning and inter-character spacing in bounding box
[PyX.git] / manual / deformer.rst
blob15fdad56b46d9ddd26393741b9be4dca6bd3050b
2 .. module:: deformer
4 ======================================
5 Module :mod:`deformer`: Path deformers
6 ======================================
8 The :mod:`deformer` module provides techniques to generate modulated paths. All
9 classes in the :mod:`deformer` module can be used as attributes when
10 drawing/stroking paths onto a canvas. Alternatively new paths can be created by
11 deforming an existing path by means of the :meth:`deform` method.
13 All classes of the :mod:`deformer` module provide the following methods:
16 .. class:: deformer()
18 .. method:: deformer.__call__((specific parameters for the class))
20    Returns a deformer with modified parameters
23 .. method:: deformer.deform(path)
25    Returns the deformed normpath on the basis of the *path*. This method allows
26    using the deformers outside of a drawing call.
28 The deformer classes are the following:
31 .. class:: cycloid(radius, halfloops=10, skipfirst=1*unit.t_cm, skiplast=1*unit.t_cm, curvesperhloop=3, sign=1, turnangle=45)
33    This deformer creates a cycloid around a path. The outcome looks similar to a 3D
34    spring stretched along the original path.
36    *radius*: the radius of the cycloid (this is the radius of the 3D spring)
38    *halfloops*: the number of half-loops of the cycloid
40    *skipfirst* and *skiplast*: the lengths on the original path not to be bent to a
41    cycloid
43    *curvesperhloop*: the number of Bezier curves to approximate a half-loop
45    *sign*: for ``sign>=0`` the cycloid starts to the left of the path, whereas
46    for ``sign<0`` it starts to the right.
48    *turnangle*: the angle of perspective on the 3D spring. At ``turnangle=0``
49    results in a sinusoidal curve, whereas for ``turnangle=90`` one essentially
50    obtains a circle.
53 .. class:: smoothed(radius, softness=1, obeycurv=0, relskipthres=0.01)
55    This deformer creates a smoothed variant of the original path. The smoothing is
56    done on the basis of the corners of the original path, not on a global scope!
57    Therefore, the result might not be what one would draw by hand. At each corner
58    (or wherever two path elements meet) a piece of twice the *radius*
59    is taken out of the original path and replaced by a curve. This curve is
60    determined by the tangent directions and the curvatures at its endpoints. Both
61    are taken from the original path, and therefore, the new curve fits into the gap
62    in a *geometrically smooth* way. Path elements that are shorter than
63    *radius* :math:`\times` *relskipthres* are ignored.
65    The new curve smoothing the corner consists either of one or of two Bezier
66    curves, depending on the surrounding path elements. If there are straight lines
67    before and after the new curve, then two Bezier curves are used. This optimises
68    the bending of curves in rectangular boxes or polygons. Here, the curves have an
69    additional degree of freedom that can be set with *softness* :math:`\in(0,1]`.
70    If one of the concerned path elements is curved, only one Bezier curve is used
71    that is (not always uniquely) determined by its geometrical constraints. There
72    are, nevertheless, some *caveats*:
74    A curve that strictly obeys the sign and magnitude of the curvature might not
75    look very smooth in some cases. Especially when connecting a curved with a
76    straight piece, the smoothed path contains unwanted overshootings. To prevent
77    this, the parameter default *obeycurv=0* releases the curvature constraints a
78    little: The curvature may then change its sign (still looks smooth for human
79    eyes) or, in more extreme cases, even its magnitude (does not look so smooth).
80    If you really need a geometrically smooth path on the basis of Bezier curves,
81    then set *obeycurv=1*.
84 .. class:: parallel(distance, relerr=0.05, sharpoutercorners=0, dointersection=1, checkdistanceparams=[0.5], lookforcurvatures=11)
86    This deformer creates a parallel curve to a given path. The result is similar to
87    what is usually referred to as the *set with constant distance* to the set of
88    points on the path. It differs in one important respect, because the *distance*
89    parameter in the deformer is a signed distance. The resulting parallel normpath
90    is constructed on the level of the original pathitems. For each of them a
91    parallel pathitem is constructed. Then, they are connected by circular arcs (or
92    by sharp edges) around the corners of the original path. Later, everything that
93    is nearer to the original path than distance is cut away.
95    There are some caveats:
97    * When the original path is too curved then the parallel path would contain
98      points with infinte curvature. The resulting path stops at such points and
99      leaves the too strongly curved piece out.
101    * When the original path contains on or more self-intersections, then the
102      resulting parallel path is not continuous in the parameterisation of the
103      original path. This may result in the surprising behaviour that a piece
104      that corresponding to a "later" parameter value is followed by an
105      "earlier" one.
107    The parameters are the following:
109    *distance* is the minimal (signed) distance between the original and the
110    parallel paths.
112    *relerr* is the allowed relative error in the distance.
114    *sharpoutercorners* connects the parallel pathitems by a wegde made of
115    straight lines, instead of taking circular arcs. This preserves the angle of
116    the original corners.
118    *dointersection* is a boolean for performing the last step, the intersection
119    step, in the path construction. Setting this to 0 gives the full parallel path,
120    which can be favourable for self-intersecting paths.
122    *checkdistanceparams* is a list of parameter values in the interval (0,1) where
123    the distance is checked on each parallel pathitem.
125    *lookforcurvatures* is the number of points per normpathitem where its curvature
126    is checked for critical values.