Module trafo: Linear transformations¶
The trafo module provides affine (linear plus translation) coordinate
transformations. Because trafo inherits from baseclasses.deformer,
transformation instances can be used seamlessly in several ways across PyX:
Passed in the attribute list of
canvas.canvas.stroke(),canvas.canvas.fill(),canvas.canvas.draw(),canvas.canvas.insert(), orcanvas.canvas.text()to transform individual graphical objects.Passed to
canvas.canvas([trafo.scale(2)])orc.set([trafo.rotate(45)])to transform the coordinate system of an entire canvas.Applied directly to a path via
p.transformed(t)ort.deform(p), or to a bounding box viab.transformed(t).
Mathematical Definition and Composition¶
An affine transformation maps a 2D point vector \(\vec{x} = (x, y)^T\) to
where \(\mathsf{A}\) is a non-singular \(2\times 2\) matrix (\(\det \mathsf{A} \ne 0\)) and \(\vec{b}\) is a 2D translation vector.
Transformations can be composed in two ways:
Multiplication (
t1 * t2): Multiplying two transformations corresponds to matrix composition—t1 * t2appliest2first, followed byt1:\[\mathsf{A} = \mathsf{A}_1 \mathsf{A}_2, \qquad \vec{b} = \mathsf{A}_1 \vec{b}_2 + \vec{b}_1\ .\]Chained methods (
t.translated(...),t.rotated(...), etc.): Everytrafoinstance provides methods that return a new transformation obtained by applying the new operation aftert. Thust.rotated(45)is equivalent totrafo.rotate(45) * t:# Translate by (2, 1) first, then rotate by 30 degrees around the origin: t = trafo.translate(2, 1).rotated(30) # Equivalent to: t = trafo.rotate(30) * trafo.translate(2, 1)
Class trafo¶
- class trafo.trafo(matrix=((1, 0), (0, 1)), vector=(0, 0))¶
Constructs an affine transformation with \(2\times 2\) transformation matrix
((a11, a12), (a21, a22))and translation vector(bx, by)(wherebxandbyare PyX lengths or numbers in user units).For internal point-based coordinates,
trafo_pttakesvectordirectly in PostScript points. The module-level constanttrafo.identityprovides a preconstructed identity transformation.- apply(x, y)¶
Applies the transformation to the point
(x, y)(in user units or PyX lengths) and returns the transformed point as a tuple of two true lengths(tx, ty).
- apply_pt(x_pt, y_pt)¶
Applies the transformation to the point
(x_pt, y_pt)in PostScript points and returns(tx_pt, ty_pt)in points.
- deform(path)¶
Returns a transformed copy of path (equivalent to
path.transformed(self)).
- inverse()¶
Returns the inverse transformation \(\mathsf{A}^{-1}\) with translation vector \(-\mathsf{A}^{-1}\vec{b}\).
- mirrored(angle)¶
Returns
selffollowed by a reflection across the line through the origin at angle degrees counter-clockwise from the positive x-axis.
- rotated(angle, x=None, y=None)¶
Returns
selffollowed by a counter-clockwise rotation by angle degrees around the center(x, y)(or(0, 0)if omitted). Also available in point coordinates asrotated_pt().
- scaled(sx, sy=None, x=None, y=None)¶
Returns
selffollowed by scaling by sx in the x-direction and sy in the y-direction (if sy isNone, uniform scalingsy = sxis used) relative to the center(x, y)(or(0, 0)if omitted). Also available in point coordinates asscaled_pt().
- slanted(a, angle=0, x=None, y=None)¶
Returns
selffollowed by a shear (slant) of factor a along the direction angle (in degrees) relative to(x, y)(or(0, 0)if omitted). Also available in point coordinates asslanted_pt().
- translated(x, y)¶
Returns
selffollowed by a translation by(x, y). Also available in point coordinates astranslated_pt().
Standard Transformation Subclasses¶
For each transformation operation, trafo provides a dedicated subclass of
trafo (along with a corresponding _pt class taking coordinates in
PostScript points):
- class trafo.mirror(angle=0)¶
Reflection across the line through the origin
(0, 0)at angle degrees from the positive x-axis.
- class trafo.rotate(angle, x=None, y=None)¶
- class trafo.rotate_pt(angle, x=None, y=None)¶
Counter-clockwise rotation by angle degrees around the point
(x, y), or around(0, 0)if x and y are omitted.
- class trafo.scale(sx, sy=None, x=None, y=None)¶
- class trafo.scale_pt(sx, sy=None, x=None, y=None)¶
Scaling by factor sx along the x-axis and sy along the y-axis (defaults to
sy = sxfor uniform scaling) centered at(x, y), or at(0, 0)if x and y are omitted.
- class trafo.slant(a, angle=0, x=None, y=None)¶
- class trafo.slant_pt(a, angle=0, x=None, y=None)¶
Shear transformation by factor a along the direction angle (in degrees) centered at
(x, y), or at(0, 0)if x and y are omitted. Forangle=0, this maps \((x, y) \mapsto (x + a y, y)\).
- class trafo.translate(x, y)¶
- class trafo.translate_pt(x, y)¶
Translation by the vector
(x, y).