Description
These API functions allow you to instantiate and manipulate
Affine transforms. An Affine transformation is a geometrical
transformation which is known to preserve the parallelism of
lines but not lengths and angles.
Affine transforms are usually represented using Homogeneous
coordinates: given a point (x,y) in the traditional plane, its
canonical Homogenous coordinate is (x,y,1).
The Affine transforms are represented in Homogeneous coordinates
because the transformation of point A by any Affine transformation
can be expressed by the multiplication of a 3x3 Matrix and a 3x1
Point vector.
The above property is not trivial. For example, a translation in
normal cartesian space results in the addition of a Point vector
to the Point vector to transform while in Homogeneous space, the
same translation transformation results in a matrix/vector
multiplication. To convince you that I am telling you the truth,
the diagram below summarizes the different kinds of Affine matrixes
used and shows the scaling of point (x,y) by multiplication with a
scaling matrix in homogeneous space.
To compose two Affine transforms, all you need to do is to multiply
their matrices to get the matrix representing the resulting
Affine transform. Given Affines A and B represented the matrices
MA and MB, the Affine C = AoB is represented by the matrix MC = MA x MB.
Hopefully, all the above gory details (which are unfortunatly necessary
to understand the API) are more or less hidden by the API.
LibArt thus represents an Affine transform by an array of six doubles:
Those arrays of six doubles can be easily generated with the
art_affine_shear,
art_affine_scale,
art_affine_rotate,
art_affine_translate and
art_affine_identity functions which
generate the affines corresponding to the given transformations.
It is possible to composite Affine transformation's matrices with
art_affine_multiply
and to invert an Affine transformation:
art_affine_invert.
Finally, I to apply an Affine transformation to a point, you can use
art_affine_point
Affine transformations are reused a little everywhere in LibArt: it is possible
to apply them to Vector Paths and pixel buffers.
art_vpath_affine_transform,
art_bpath_affine_transform and
art_rgb_affine are such examples.
Details
art_affine_point ()
void art_affine_point (ArtPoint *dst,
const ArtPoint *src,
const double affine[6]); |
art_affine_invert ()
void art_affine_invert (double dst_affine[6],
const double src_affine[6]); |
All non-degenerate affine transforms are invertible. If the original
affine is degenerate or nearly so, expect numerical instability and
very likely core dumps on Alpha and other fp-picky architectures.
Otherwise, dst multiplied with src, or src multiplied with dst
will be (to within roundoff error) the identity affine.
art_affine_flip ()
void art_affine_flip (double dst_affine[6],
const double src_affine[6],
int horz,
int vert); |
Flips the affine transform. FALSE for both horiz and vert implements
a simple copy operation. TRUE for both horiz and vert is a
180 degree rotation. It is ok for src_affine and dst_affine to
be equal pointers.
art_affine_to_string ()
void art_affine_to_string (char str[128],
const double src[6]); |
Converts an affine transform into a bit of PostScript code that
implements the transform. Special cases of scaling, rotation, and
translation are detected, and the corresponding PostScript
operators used (this greatly aids understanding the output
generated). The identity transform is mapped to the null string.
art_affine_multiply ()
void art_affine_multiply (double dst[6],
const double src1[6],
const double src2[6]); |
Multiplies two affine transforms together, i.e. the resulting dst
is equivalent to doing first src1 then src2. Note that the
PostScript concat operator multiplies on the left, i.e. "M concat"
is equivalent to "CTM = multiply (M, CTM)";
It is safe to call this function with dst equal to src1 or src2.
art_affine_identity ()
void art_affine_identity (double dst[6]); |
Sets up an identity matrix.
art_affine_scale ()
void art_affine_scale (double dst[6],
double sx,
double sy); |
Sets up a scaling matrix.
art_affine_rotate ()
void art_affine_rotate (double dst[6],
double theta); |
Sets up a rotation matrix. In the standard libart coordinate
system, in which increasing y moves downward, this is a
counterclockwise rotation. In the standard PostScript coordinate
system, which is reversed in the y direction, it is a clockwise
rotation.
art_affine_shear ()
void art_affine_shear (double dst[6],
double theta); |
Sets up a shearing matrix. In the standard libart coordinate system
and a small value for theta, || becomes \\. Horizontal lines remain
unchanged.
art_affine_translate ()
void art_affine_translate (double dst[6],
double tx,
double ty); |
Sets up a translation matrix.
art_affine_expansion ()
double art_affine_expansion (const double src[6]); |
Finds the expansion factor, i.e. the square root of the factor
by which the affine transform affects area. In an affine transform
composed of scaling, rotation, shearing, and translation, returns
the amount of scaling.
art_affine_rectilinear ()
int art_affine_rectilinear (const double src[6]); |
Determines whether src is rectilinear, i.e. grid-aligned
rectangles are transformed to other grid-aligned rectangles. The
implementation has epsilon-tolerance for roundoff errors.
art_affine_equal ()
int art_affine_equal (double matrix1[6],
double matrix2[6]); |
Determines whether matrix1 and matrix2 are equal, with
epsilon-tolerance for roundoff errors.