From: <joergl@us...>  20060519 11:10:52

Revision: 2728 Author: joergl Date: 20060519 04:10:41 0700 (Fri, 19 May 2006) ViewCVS: http://svn.sourceforge.net/pyx/?rev=2728&view=rev Log Message:  show difference between trafo as deformer and as canvas trafo Modified Paths:  trunk/pyx/examples/drawing2/ellipse.py trunk/pyx/examples/drawing2/ellipse.txt Modified: trunk/pyx/examples/drawing2/ellipse.py ===================================================================  trunk/pyx/examples/drawing2/ellipse.py 20060519 10:35:42 UTC (rev 2727) +++ trunk/pyx/examples/drawing2/ellipse.py 20060519 11:10:41 UTC (rev 2728) @@ 1,8 +1,16 @@ from pyx import * c = canvas.canvas() c.stroke(path.circle(0, 0, 1), [trafo.scale(sx=2, sy=1.5),  trafo.rotate(45),  trafo.translate(1, 0)]) +circ = path.circle(0, 0, 1) + +# variant 1: use trafo as a deformer +c.stroke(circ, [style.linewidth.THIck, + trafo.scale(sx=2, sy=0.9), trafo.rotate(45), trafo.translate(1, 0)]) + +# variant 2: transform a subcanvas +sc = canvas.canvas() +sc.stroke(circ, [style.linewidth.THIck]) +c.insert(sc, [trafo.scale(sx=2, sy=0.9), trafo.rotate(45), trafo.translate(5, 0)]) + c.writeEPSfile("ellipse") c.writePDFfile("ellipse") Modified: trunk/pyx/examples/drawing2/ellipse.txt ===================================================================  trunk/pyx/examples/drawing2/ellipse.txt 20060519 10:35:42 UTC (rev 2727) +++ trunk/pyx/examples/drawing2/ellipse.txt 20060519 11:10:41 UTC (rev 2728) @@ 1,35 +1,52 @@ Applying transformations when drawing a path: Creating an ellipse +Applying transformations on a path or canvas: Drawing an ellipse PyX does not directly provide a path corresponding to an ellipse. This example shows how to draw an ellipse using affine transformations. ... +shows two ways how to draw an ellipse using affine transformations. ... In order to create an ellipse, we best start from a unit circle centered around the point of origin of the coordinate system. When stroking this circle on the canvas, we tell PyX to apply a couple of affine transformations first. These affine transformations are contained in the `trafo` module. We first use `trafo.scale` to apply a nonuniform scaling, namely by a factor of 2 in xdirection and a factor of 1.5 in ydirection. Doing so, we define the two principle axes of the ellipse. In a next step, we rotate with `trafo.rotate` the ellipse by an angle of 45 degrees in the mathematical positive direction, i.e. counterclockwise. Last, we shift the origin of the ellipse to the desired point by applying a `trafo.translate` operation. +the point of origin of the coordinate system (here: `circ`). In variant 1, we +tell PyX to apply a couple of affine transformations before stroking this +circle on the canvas `c`. These affine transformations are contained in the +`trafo` module. We first use `trafo.scale` to apply a nonuniform scaling, +namely by a factor of 2 in xdirection and a factor of 0.9 in ydirection. +Doing so, we define the two principle axes of the ellipse. In a next step, we +rotate with `trafo.rotate` the ellipse by an angle of 45 degrees in the +mathematical positive direction, i.e. counterclockwise. Last, we shift the +origin of the ellipse to the desired point by applying a `trafo.translate` +operation. ! Note that the order of the transformations matters. If you, for instance, would first translate the ellipse, the later scaling would also affect the distance by which you have shifted the ellipse. PyX applies the transformations one after the other, from left to right, so the example shown above does the correct thing. ! You can also treat transformations as mathematical objects (they are represented by twodimensional matrices together with an offset vector) and multiply them using the `*` operator. Note, however, that mathematically, transformations are applied from right to left, such that the above example would need to be written as +! You can also treat transformations as mathematical objects (they are +represented by twodimensional matrices together with an offset vector) and +multiply them using the `*` operator. Note, however, that mathematically, +transformations are applied from right to left, such that variant 1 +would need to be written as  c.stroke(path.circle(0, 0, 1), [trafo.translate(1,0) * trafo.rotate(45) * trafo.scale(sx=2, sy=1.5)]) + c.stroke(circ, [trafo.translate(1,0) * trafo.rotate(45) * trafo.scale(sx=2, sy=1.5)]) ! PyX also provides some convenience methods for applying certain transformations with a given point as the origin. These allow one to write the example in yet another form +transformations with a given point as the origin. These allow one to write variant 1 +in yet another form  c.stroke(path.circle(1, 0, 1), [trafo.scale(sx=2, sy=1.5, x=1, y=0), trafo.rotate(45, x=1, y=0)]) + c.stroke(circ, [trafo.scale(sx=2, sy=1.5, x=1, y=0), trafo.rotate(45, x=1, y=0)]) where we have started already from a circle centered around the desired point 1,0. + +When telling the stroke method to apply a number of transformations, we use +that a transformation is a socalled deformer. Deformers take an original path, +do some operation on it and return the modified version. PyX thus internally +converts the circle into a path representing the ellipse. Alternatively, we can +also let the PostScript or PDF interpreter do the same transformation. This is what +is shown in variant 2. There, we first stroke the circle on a new canvas `sc`. +When inserting this canvas in the original canvas `c`, we again pass a set of +transformations as arguments. Since PyX cannot deform an entire canvas, it just +writes these transformations into the output file. If you compare the resulting +output (the right ellipse) with the one of variant 1, you will notice a +difference, though: when transforming a whole canvas, the lineshape is +transformed as well. Often, this is not the intended result, so you better +transform individual objects when stroking or filling them. + This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. 