The type of transformations that CLIM uses are called affine transformations. An affine transformation is a transformation that preserves straight lines. In other words, if you take a number of points that fall on a straight line and apply an affine transformation to their coordinates, the transformed coordinates will fall on a straight line in the new coordinate system. Affine transformations include translations, scalings, rotations, and reflections.
A translation is a transformation that preserves the length, angle, and orientation of all geometric entities.
A rotation is a transformation that preserves the length and angles of all geometric entities. Rotations also preserve one point and the distance of all entities from that point. You can think of that point as the "center of rotation"; it is the point around which everything rotates.
There is no single definition of a scaling transformation. Transformations that preserve all angles and multiply all lengths by the same factor (preserving the "shape" of all entities) are certainly scaling transformations. However, scaling is also used to refer to transformations that scale distances in the x direction by one amount and distances in the y direction by another amount.
A reflection is a transformation that preserves lengths and magnitudes of angles but changes the sign (or "handedness") of angles. If you think of the drawing plane on a transparent sheet of paper, a reflection is a transformation that "turns the paper over".
If we transform from one coordinate system to another, then from the second to a third coordinate system, we can regard the resulting transformation as a single transformation resulting from composing the two component transformations. It is an important and useful property of affine transformations that they are closed under composition.
Note that composition is not commutative; in general, the result of applying transformation A and then applying transformation B is not the same as applying B first, then A.
Any arbitrary transformation can be built up by composing a number of simpler transformations, but that same transformation can often be constructed by a different composition of different transformations.
Transforming a region applies a coordinate transformation to that region, thus moving its position on the drawing plane, rotating it, or scaling it. Note that this creates a new region, but it does not affect the region argument.
The user interface to transformations is the :transformation option to the drawing functions. Users can create transformations with constructors. See 3.5.1 CLIM Transformation Constructors. The other operators documented in this section are used by CLIM itself, and are not often needed by users.
The following functions create transformation objects that can be used, for instance, in a call to compose-transformations. The transformation constructors do not capture any of their inputs. The constructors all create objects that are subclasses of transformation.
make-translation-transformation Function
make-translation-transformation translation-x translation-y
Summary: A translation is a transformation that preserves the length, angle, and orientation of all geometric entities.
make-translation-transformation
returns a transformation that translates all points by translation-x in the x direction and translation-y in the y direction. translation-x and translation-y must be real numbers.
make-rotation-transformation Function
make-rotation-transformation angle &optional origin
make-rotation-transformation* Function
make-rotation-transformation* angle &optional origin-x origin-y
Summary: A rotation is a transformation that preserves the length and angles of all geometric entities. Rotations also preserve one point (the origin) and the distance of all entities from that point.
make-rotation-transformation returns a transformation that rotates all points by angle (which is a real number indicating an angle in radians) around the point origin. If origin is supplied it must be a point; if not supplied, it defaults to (0, 0). origin-x and origin-y must be real numbers.
make-scaling-transformation Function
make-scaling-transformation scale-x scale-y &optional origin
make-scaling-transformation* Function
make-scaling-transformation* scale-x scale-y &optional origin-x origin-y
Summary: As discussed previously, there is no single definition of a scaling transformation. make-scaling-transformation returns a transformation that multiplies the x-coordinate distance of every point from origin by scale-x and the y-coordinate distance of every point from origin by scale-y. scale-x and scale-y must be real numbers. If origin is supplied it must be a point; if not supplied, it defaults to (0, 0). origin-x and origin-y must be real numbers.
make-reflection-transformation Function
make-reflection-transformation point1 point2
make-reflection-transformation* Function
make-reflection-transformation* x1 y1 x2 y2
Summary: A reflection is a transformation that preserves lengths and magnitudes of angles, but changes the sign (or "handedness") of angles. If you think of the drawing plane on a transparent sheet of paper, a reflection is a transformation that "turns the paper over".
make-reflection-transformation returns a transformation that reflects every point through the line passing through the points point1 and point2 (or through the positions (x1, y1) and (x2, y2) in the case of the spread version).
make-transformation a b c d u v
Summary: Returns a general transformation whose effect is:
x' = ax+by+u
y' = cx+dy+v
where x and y are the coordinates of a point before the transformation and x' and y' are the coordinates of the corresponding point after.
All of the arguments to make-transformation
must be real numbers.
make-3-point-transformation Function
make-3-point-transformation point-1 point-2 point-3 point-1-image point-2-image point-3-image
Summary: Returns a transformation that takes points point-1 into point-1-image, point-2 into point-2-image, and point-3 into point-3-image. Three non-collinear points and their images under the transformation are enough to specify any affine transformation.
If point-1, point-2, and point-3 are collinear, the transformation-underspecified error will be signaled. If point-1-image, point-2-image, and point-3-image are collinear, the resulting transformation will be singular (that is, will have no inverse), but this is not an error.
make-3-point-transformation* Function
make-3-point-transformation* x1 y1 x2 y2 x3 y3 x1-image y1-image x2-image y2-image x3-image y3-image
Summary: Returns a transformation that takes the points at the positions (x1, y1) into (x1-image, y1-image), (x2, y2) into (x2-image, y2-image) and (x3, y3) into (x3-image, y3-image). Three non-collinear points and their images under the transformation are enough to specify any affine transformation.
If the positions (x1, y1), (x2, y2), and (x3, y3) are collinear, the transformation-underspecified error will be signaled. If (x1-image, y1-image), (x2-image, y2-image), and (x3-image, y3-image) are collinear, the resulting transformation will be singular, but this is not an error.
This is the spread version of make-3-point-transformation.
Summary: The protocol class of all transformations. There are one or more subclasses of transformation
that implement transformations, the exact names of which are explicitly unspecified. If you want to create a new class that behaves like a transformation, it should be a subclass of transformation
. Subclasses of transformation
obey the transformation protocol.
All of the instantiable transformation classes provided by CLIM are immutable.
transformationp object
Summary: Returns t
if object is a transformation; otherwise, it returns nil
.
+identity-transformation+ Constant
Summary: An instance of a transformation that is guaranteed to be an identity transformation, that is, the transformation that "does nothing".
transformation-error Condition Class
Summary: The class that is the superclass of the following three conditions. This class is a subclass of error.
transformation-underspecified Condition Class
Summary: The error that is signaled when make-3-point-transformation is given three collinear image points.
reflection-underspecified Condition Class
Summary: The error that is signaled when make-reflection-transformation is given two coincident points.
singular-transformation Condition Class
Summary: The error that is signaled when invert-transformation is called on a singular transformation, that is, a transformation that has no inverse.
The following predicates are provided in order to be able to determine whether or not a transformation has a particular characteristic.
transformation-equal Generic Function
transformation-equal transformation1 transformation2
Summary: Returns t
if the two transformations have equivalent effects (that is, are mathematically equal); otherwise, it returns nil
.
identity-transformation-p Generic Function
identity-transformation-p transformation
Summary: Returns t
if transformation is equal (in the sense of transformation-equal) to the identity transformation; otherwise, it returns nil
.
translation-transformation-p Generic Function
translation-transformation-p transformation
Summary: Returns t
if transformation is a pure translation, that is, a transformation that moves every point by the same distance in x and the same distance in y. Otherwise, it returns nil
.
invertible-transformation-p Generic Function
invertible-transformation-p transformation
Summary: Returns t
if transformation has an inverse; otherwise, it returns nil
.
reflection-transformation-p Generic Function
reflection-transformation-p transformation
Summary: Returns t
if transformation inverts the "handedness" of the coordinate system; otherwise, it returns nil
. Note that this is a very inclusive category—transformations are considered reflections even if they distort, scale, or skew the coordinate system, as long as they invert the handedness.
rigid-transformation-p Generic Function
rigid-transformation-p transformation
Summary: Returns t
if transformation transforms the coordinate system as a rigid object, that is, as a combination of translations, rotations, and pure reflections. Otherwise, it returns nil
.
Rigid transformations are the most general category of transformations that preserve magnitudes of all lengths and angles.
even-scaling-transformation-p Generic Function
even-scaling-transformation-p transformation
Summary: Returns t
if transformation multiplies all x-lengths and y-lengths by the same magnitude; otherwise, it returns nil
. This includes pure reflections through vertical and horizontal lines.
scaling-transformation-p Generic Function
scaling-transformation-p transformation
Summary: Returns t
if transformation multiplies all x-lengths by one magnitude and all y-lengths by another magnitude; otherwise, it returns nil
. This category includes even scalings as a subset.
rectilinear-transformation-p Generic Function
rectilinear-transformation-p transformation
Summary: Returns t
if transformation will always transform any axis-aligned rectangle into another axis-aligned rectangle; otherwise, it returns nil
. This category includes scalings as a subset, and also includes 90 degree rotations.
Rectilinear transformations are the most general category of transformations for which the bounding rectangle of a transformed object can be found by transforming the bounding rectangle of the original object.
compose-transformations Generic Function
compose-transformations transformation1 transformation2
Summary: Returns a transformation that is the mathematical composition of its arguments. Composition is in right-to-left order; that is, the resulting transformation represents the effects of applying the transformation transformation2 followed by the transformation transformation1.
invert-transformation Generic Function
invert-transformation transformation
Summary: Returns a transformation that is the inverse of the transformation transformation. The result of composing a transformation with its inverse is equal to the identity transformation.
If transformation is singular, invert-transformation
will signal the singular-transformation error, with a named restart that is invoked with a transformation and makes invert-transformation
return that transformation. This is to allow a drawing application, for example, to use a generalized inverse to transform a region through a singular transformation.
Note that with finite-precision arithmetic there are several low-level conditions that might occur during the attempt to invert a singular or "almost singular" transformation. (These include computation of a zero determinant, floating-point underflow during computation of the determinant, or floating-point overflow during subsequent multiplication.) invert-transformation
signals the singular-transformation error for all of these cases.
compose-translation-with-transformation Function
compose-translation-with-transformation transformation dx dy
compose-scaling-with-transformation Function
compose-scaling-with-transformation transformation sx sy &optional origin
compose-rotation-with-transformation Function
compose-rotation-with-transformation transformation angle &optional origin
Summary: These functions create a new transformation by composing the transformation transformation with a given translation, scaling, or rotation, respectively. The order of composition is that the translation, scaling, or rotation "transformation" is first, followed by transformation.
dx and dy are as for make-translation-transformation. sx and sy are as for make-scaling-transformation. angle and origin are as for make-rotation-transformation.
Note that these functions could be implemented by using the various constructors. They are provided because it is common to build up a transformation as a series of simple transformations.
compose-transformation-with-translation Function
compose-transformation-with-translation transformation dx dy
compose-transformation-with-scaling Function
compose-transformation-with-scaling transformation sx sy &optional origin
compose-transformation-with-rotation Function
compose-transformation-with-rotation transformation angle &optional origin
Summary: These functions create a new transformation by composing a given translation, scaling, or rotation, respectively, with the transformation transformation. The order of composition is transformation first, followed by the translation, scaling, or rotation "transformation".
dx and dy are as for make-translation-transformation. sx and sy are as for make-scaling-transformation. angle and origin are as for make-rotation-transformation.
Note that these functions could be implemented by using the various constructors and compose-transformations. They are provided because it is common to build up a transformation as a series of simple transformations.
The following three functions are no different than using with-drawing-options with the :transformation keyword argument supplied. However, they are sufficiently useful that they are provided as a convenience to programmers.
In order to preserve referential transparency, these three forms apply the translation, rotation, or scaling transformation first, then the rest of the transformation from (medium-transformation medium)
. That is, the following two forms would return the same transformation (assuming that the medium's transformation in the second example is the identity transformation):
(compose-transformations (make-translation-transformation dx dy) (make-rotation-transformation angle)) (with-translation (medium dx dy) (with-rotation (medium angle) (medium-transformation medium)))
with-translation (medium dx dy) &body body
Summary: Establishes a translation on the medium medium that translates by dx in the x direction and dy in the y direction, and then executes body with that transformation in effect.
dx and dy are as for make-translation-transformation.
The medium argument is not evaluated, and must be a symbol that is bound to a sheet or medium. If medium is t
, *standard-output* is used. body may have zero or more declarations as its first forms.
with-scaling (medium sx &optional sy origin) &body body
Summary: Establishes a scaling transformation on the medium medium that scales by sx in the x direction and sy in the y direction, and then executes body with that transformation in effect. If sy is not supplied, it defaults to sx. If origin is supplied, the scaling is about that point; if it is not supplied, it defaults to (0, 0).
sx and sy are as for make-scaling-transformation.
The medium argument is not evaluated, and must be a symbol that is bound to a sheet or medium. If medium is t
, *standard-output* is used. body may have zero or more declarations as its first forms.
with-rotation (medium angle &optional origin) &body body
Summary: Establishes a rotation on the medium medium that rotates by angle, and then executes body with that transformation in effect. If origin is supplied, the rotation is about that point; if it is not supplied, it defaults to (0, 0).
angle and origin are as for make-rotation-transformation.
The medium argument is not evaluated, and must be a symbol that is bound to a sheet or medium. If medium is t
, *standard-output* is used. body may have zero or more declarations as its first forms.
These two functions also compose a transformation into the current transformation of a stream, but have more complex behavior.
with-local-coordinates (medium &optional x y) &body body
Summary: Binds the dynamic environment to establish a local coordinate system on the medium medium with the origin of the new coordinate system at the position (x, y). The "directionality" of the coordinate system is otherwise unchanged. x and y are real numbers, and both default to 0.
The medium argument is not evaluated, and must be a symbol that is bound to a sheet or medium. If medium is t
, *standard-output* is used. body may have zero or more declarations as its first forms.
with-first-quadrant-coordinates Macro
with-first-quadrant-coordinates (medium &optional x y) &body body
Summary: Binds the dynamic environment to establish a local coordinate system on the medium medium with the positive x axis extending to the right and the positive y axis extending upward, with the origin of the new coordinate system at the position (x, y). x and y are real numbers, and both default to 0.
The medium argument is not evaluated, and must be a symbol that is bound to a sheet or medium. If medium is t
, *standard-output* is used. body may have zero or more declarations as its first forms.
Transforming a region applies a coordinate transformation to that region, thus moving its position on the drawing plane, rotating it, or scaling it. Note that transforming a region does not affect the region argument; it is free to either create a new region or return an existing (cached) region.
These generic functions are implemented for all classes of transformations. Furthermore, all subclasses of region and ink
implement methods for transform-region and untransform-region. That is, methods for the following generic functions will typically specialize both the transformation and region arguments.
transform-region Generic Function
transform-region transformation region
Summary: Applies transformation to the region region, and returns the transformed region.
untransform-region Generic Function
untransform-region transformation region
Summary: This is exactly equivalent to:
(transform-region (invert-transformation transformation) region)
CLIM provides a default method for untransform-region
on the transformation protocol class that does exactly this.
transform-position Generic Function
transform-position transformation x y
Summary: Applies the transformation transformation to the point whose coordinates are the real numbers x and y, and returns two values, the transformed x coordinate and the transformed y coordinate.
transform-position
is the spread version of transform-region in the case where the region is a point.
untransform-position Generic Function
untransform-position transformation x y
Summary: This is exactly equivalent to:
(transform-position (invert-transformation transformation) x y)
CLIM provides a default method for untransform-position
on the transformation protocol class that does exactly this.
transform-distance Generic Function
transform-distance transformation dx dy
Summary: Applies the transformation transformation to the distance represented by the real numbers dx and dy, and returns two values, the transformed dx and the transformed dy.
A distance represents the difference between two points. It does not transform like a point.
untransform-distance Generic Function
untransform-distance transformation dx dy
Summary: This is exactly equivalent to:
(transform-distance (invert-transformation transformation) dx dy)
CLIM provides a default method for untransform-distance
on the transformation protocol class that does exactly this.
transform-rectangle* Generic Function
transform-rectangle* transformation x1 y1 x2 y2
Summary: Applies the transformation transformation to the rectangle specified by the four coordinate arguments, which are real numbers. The arguments x1, y1, x2, and y2 are canonicalized in the same way as for make-bounding-rectangle. Returns four values that specify the minimum and maximum points of the transformed rectangle in the order min-x, min-y, max-x, and max-y.
It is an error if transformation does not satisfy rectilinear-transformation-p.
transform-rectangle*
is the spread version of transform-region in the case where the transformation is rectilinear and the region is a rectangle.
untransform-rectangle* Generic Function
untransform-rectangle* transformation x1 y1 x2 y2
Summary: This is exactly equivalent to:
(transform-rectangle* (invert-transformation transformation) x1 y1 x2 y2)
CLIM provides a default method for untransform-rectangle*
on the transformation protocol class that does exactly this.
CLIM 2.0 User Guide - 01 Dec 2021 19:38:56