Module - 2 - 2D Transformations
Module - 2 - 2D Transformations
Two-Dimensional Translation
We perform a translation on a single coordinate point by adding offsets to its
coordinates so as to generate a new coordinate position.
We are moving the original point position along a straight-line path to its new location.
To translate a two-dimensional position, we add translation distances tx and ty to the
original coordinates (x, y) to obtain the new coordinate position (x’, y’) as shown in
Figure
The translation distance pair (tx, ty) is called a translation vector or shift vector Column
vector representation is given as
This allows us to write the two-dimensional translation equations in the matrix Form
Two-Dimensional Rotation
We generate a rotation transformation of an object by specifying a rotation axis and a
rotation angle.
A positive value for the angle θ defines a counterclockwise rotation about the pivot point,
as in above Figure , and a negative value rotates objects in the clockwise direction.
The angular and coordinate relationships of the original and transformed point positions
are shown in Figure
In this figure, r is the constant distance of the point from the origin, angle φ is the original
angular position of the point from the horizontal, and θ is the rotation angle.
we can express the transformed coordinates in terms of angles θ and φ as
The transformation equations for rotation of a point about any specified rotation position
(xr , yr ):
Code:
class wcPt2D {
public:
GLfloat x, y;
};
void rotatePolygon (wcPt2D * verts, GLint nVerts, wcPt2D pivPt, GLdouble theta)
{
wcPt2D * vertsRot;
GLint k;
for (k = 0; k < nVerts; k++) {
vertsRot [k].x = pivPt.x + (verts [k].x - pivPt.x) * cos (theta) - (verts [k].y -
pivPt.y) * sin (theta);
vertsRot [k].y = pivPt.y + (verts [k].x - pivPt.x) * sin (theta) + (verts [k].y -
pivPt.y) * cos (theta);
}
glBegin (GL_POLYGON);
for (k = 0; k < nVerts; k++)
glVertex2f (vertsRot [k].x, vertsRot [k].y);
glEnd ( );
}
Two-Dimensional Scaling
To alter the size of an object, we apply a scaling transformation.
A simple twodimensional scaling operation is performed by multiplying object positions
(x, y) by scaling factors sx and sy to produce the transformed coordinates (x’, y’):
The basic two-dimensional scaling equations can also be written in the following matrix
form
Unequal values for sx and sy result in a differential scaling that is often used in design
applications.
In some systems, negative values can also be specified for the scaling parameters. This
not only resizes an object, it reflects it about one or more of the coordinate axes.
Figure below illustrates scaling of a line by assigning the value 0.5 to both sx and sy
We can control the location of a scaled object by choosing a position, called the fixed
point, that is to remain unchanged after the scaling transformation.
Coordinates for the fixed point, (x f , yf ), are often chosen at some object position, such
as its centroid but any other spatial position can be selected.
For a coordinate position (x, y), the scaled coordinates (x’, y’) are then calculated from
the following relationships:
Where the additive terms x f (1 − sx) and yf (1 − sy) are constants for all points in the
object.
Code:
class wcPt2D {
public:
GLfloat x, y;
};
void scalePolygon (wcPt2D * verts, GLint nVerts, wcPt2D fixedPt, GLfloat sx, GLfloat sy)
{
wcPt2D vertsNew;
GLint k;
for (k = 0; k < nVerts; k++) {
vertsNew [k].x = verts [k].x * sx + fixedPt.x * (1 - sx);
vertsNew [k].y = verts [k].y * sy + fixedPt.y * (1 - sy);
}
glBegin (GL_POLYGON);
for (k = 0; k < nVerts; k++)
glVertex2f (vertsNew [k].x, vertsNew [k].y);
glEnd ( );
}
Homogeneous Coordinates
Multiplicative and translational terms for a two-dimensional geometric transformation
can be combined into a single matrix if we expand the representations to 3 × 3 matrices
We can use the third column of a transformation matrix for the translation terms, and all
transformation equations can be expressed as matrix multiplications.
We also need to expand the matrix representation for a two-dimensional coordinate
position to a three-element column matrix
The rotation transformation operator R(θ ) is the 3 × 3 matrix with rotation parameter θ.
We form the inverse matrix for any scaling transformation by replacing the scaling
parameters with their reciprocals. the inverse transformation matrix is
The coordinate position is transformed using the composite matrixM, rather than
applying the individual transformations M1 and thenM2.
By multiplying the two rotation matrices, we can verify that two successive rotations are
additive:
R(θ2) · R(θ1) = R(θ1 + θ2)
So that the final rotated coordinates of a point can be calculated with the composite
rotation matrix as
P’ = R(θ1 + θ2) · P
We can generate a two-dimensional rotation about any other pivot point (xr , yr ) by
performing the following sequence of translate-rotate-translate operations:
1. Translate the object so that the pivot-point position is moved to the coordinate origin.
2. Rotate the object about the coordinate origin.
3. Translate the object so that the pivot point is returned to its original position.
The composite transformation matrix for this sequence is obtained with the concatenation
The composite matrix resulting from the product of these three transformations is
Property 2:
Transformation products, on the other hand, may not be commutative. The matrix
productM2 ·M1 is not equal toM1 ·M2, in general.
This means that if we want to translate and rotate an object, we must be careful about the
order in which the composite matrix is evaluated
Reversing the order in which a sequence of transformations is performed may affect the
transformed position of an object. In (a), an object is first translated in the x direction,
then rotated counterclockwise through an angle of 45◦. In (b), the object is first rotated
45◦ counterclockwise, then translated in the x direction.
The four elements rsjk are the multiplicative rotation-scaling terms in the transformation,
which involve only rotation angles and scaling factors if an object is to be scaled and
rotated about its centroid coordinates (xc , yc ) and then translated, the values for the
elements of the composite transformation matrix are
Although the above matrix requires nine multiplications and six additions, the explicit
calculations for the transformed coordinates are
We need actually perform only four multiplications and four additions to transform
coordinate positions.
Because rotation calculations require trigonometric evaluations and several
multiplications for each transformed point, computational efficiency can become an
important consideration in rotation transformations
If we are rotating in small angular steps about the origin, for instance, we can set cos θ to
1.0 and reduce transformation calculations at each step to two multiplications and two
additions for each set of coordinates to be rotated.
These rotation calculations are
x’= x − y sin θ, y’ = x sin θ + y
where the four elements r jk are the multiplicative rotation terms, and the elements trx
and try are the translational terms
A rigid-body change in coordinate position is also sometimes referred to as a rigid-
motion transformation.
In addition, the above matrix has the property that its upper-left 2 × 2 submatrix is an
orthogonal matrix.
If we consider each row (or each column) of the submatrix as a vector, then the two row
vectors (rxx, rxy) and (ryx, ryy) (or the two column vectors) form an orthogonal set of
unit vectors.
Such a set of vectors is also referred to as an orthonormal vector set. Each vector has unit
length as follows
Therefore, if these unit vectors are transformed by the rotation submatrix, then the vector
(rxx, rxy) is converted to a unit vector along the x axis and the vector (ryx, ryy) is
transformed into a unit vector along the y axis of the coordinate system
For example, the following rigid-body transformation first rotates an object through an
angle θ about a pivot point (xr , yr ) and then translates the object
Here, orthogonal unit vectors in the upper-left 2×2 submatrix are (cos θ, −sin θ) and (sin
θ, cos θ).
The rotation matrix for revolving an object from position (a) to position (b) can be constructed
with the values of the unit orientation vectors u’ and v’ relative to the original orientation.
Reflection
A transformation that produces a mirror image of an object is called a reflection.
For a two-dimensional reflection, this image is generated relative to an axis of reflection
by rotating the object 180◦ about the reflection axis.
Reflection about the line y = 0 (the x axis) is accomplished with the transformation
Matrix
This transformation retains x values, but “flips” the y values of coordinate positions.
The resulting orientation of an object after it has been reflected about the x axis is shown
in Figure
A reflection about the line x = 0 (the y axis) flips x coordinates while keeping y
coordinates the same. The matrix for this transformation is
Figure below illustrates the change in position of an object that has been reflected about
the line x = 0.
We flip both the x and y coordinates of a point by reflecting relative to an axis that is
perpendicular to the xy plane and that passes through the coordinate origin the matrix
representation for this reflection is
If we choose the reflection axis as the diagonal line y = x (Figure below), the reflection
matrix is
To obtain a transformation matrix for reflection about the diagonal y = −x, we could
concatenate matrices for the transformation sequence:
(1) clockwise rotation by 45◦,
(2) reflection about the y axis, and
(3) counterclockwise rotation by 45◦.
The resulting transformation matrix is
Shear
A transformation that distorts the shape of an object such that the transformed shape
appears as if the object were composed of internal layers that had been caused to slide
over each other is called a shear.
Two common shearing transformations are those that shift coordinate x values and those
that shift y values. An x-direction shear relative to the x axis is produced with the
transformation Matrix
Any real number can be assigned to the shear parameter shx Setting parameter shx to the
value 2, for example, changes the square into a parallelogram is shown below. Negative
values for shx shift coordinate positions to the left.
A unit square (a) is converted to a parallelogram (b) using the x -direction shear with shx = 2.
A y-direction shear relative to the line x = xref is generated with the transformation
Matrix
Translating an object from screen position (a) to the destination position shown in (b) by moving
a rectangular block of pixel values. Coordinate positions Pmin and Pmax specify the limits of the
rectangular block to be moved, and P0 is the destination reference position.
For array rotations that are not multiples of 90◦, we need to do some extra processing.
The general procedure is illustrated in Figure below.
Each destination pixel area is mapped onto the rotated array and the amount of overlap
with the rotated pixel areas is calculated.
A color for a destination pixel can then be computed by averaging the colors of the
overlapped source pixels, weighted by their percentage of area overlap.
Pixel areas in the original block are scaled, using specified values for sx and sy, and then
mapped onto a set of destination pixels.
The color of each destination pixel is then assigned according to its area of overlap with
the scaled pixel areas
A block of RGB color values in a buffer can be saved in an array with the function
glReadPixels (xmin, ymin, width, height, GL_RGB, GL_UNSIGNED_BYTE, colorArray);
If color-table indices are stored at the pixel positions, we replace the constant GL RGB
with GL_COLOR_INDEX.
To rotate the color values, we rearrange the rows and columns of the color array, as
described in the previous section. Then we put the rotated array back in the buffer with
glDrawPixels (width, height, GL_RGB, GL_UNSIGNED_BYTE, colorArray);
We can also combine raster transformations with logical operations to produce various
effects with the exclusive or operator
glMatrixMode (GL_MODELVIEW);
GLfloat elems [16];
GLint k;
for (k = 0; k < 16; k++)
elems [k] = float (k);
glLoadMatrixf (elems);
Which produces the matrix
We can also concatenate a specified matrix with the current matrix as follows:
glMultMatrix* (otherElements16);
Again, the suffix code is either f or d, and parameter otherElements16 is a 16-element,
single-subscripted array that lists the elements of some other matrix in column-major
order.
Thus, assuming that the current matrix is the modelview matrix, which we designate as
M, then the updated modelview matrix is computed as
M = M·M’
The glMultMatrix function can also be used to set up any transformation sequence with
individually defined matrices.
For example,
glMatrixMode (GL_MODELVIEW);
glLoadIdentity ( ); // Set current matrix to the identity.
glMultMatrixf (elemsM2); // Postmultiply identity with matrix M2.
glMultMatrixf (elemsM1); // Postmultiply M2 with matrix M1.
produces the following current modelview matrix:
M = M2 ·M1
Viewing Pipeline
The mapping of a two-dimensional, world-coordinate scene description to device
coordinates is called a two-dimensional viewing transformation.
This transformation is simply referred to as the window-to-viewport transformation or the
windowing transformation
We can describe the steps for two-dimensional viewing as indicated in Figure
We must set the parameters for the clipping window as part of the projection
transformation.
Function:
glMatrixMode (GL_PROJECTION);
We can also set the initialization as
glLoadIdentity ( );
This ensures that each time we enter the projection mode, the matrix will be reset
to the identity matrix so that the new viewing parameters are not combined with the
previous ones
vpWidth and vpHeight are pixel width and height of the viewport
Coordinates for the upper-right corner of the viewport are calculated for this
transformation matrix in terms of the viewport width and height:
4. glClearIndex (index);
This function sets the display window color using color-index mode,
Where parameter index is assigned an integer value corresponding to a position
within the color table.
We use the following routine to convert the current display window to an icon in the form
of a small picture or symbol representing the window:
glutIconifyWindow ( );
The label on this icon will be the same name that we assigned to the window, but we can
change this with the following command:
glutSetIconTitle ("Icon Name");
We also can change the name of the display window with a similar command:
glutSetWindowTitle ("New Window Name");
We can choose any display window to be in front of all other windows by first
designating it as the current window, and then issuing the “pop-window” command:
glutSetWindow (windowID);
glutPopWindow ( );
In a similar way, we can “push” the current display window to the back so that it is
behind all other display windows. This sequence of operations is
glutSetWindow (windowID);
glutPushWindow ( );
We can also take the current window off the screen with
glutHideWindow ( );
In addition, we can return a “hidden” display window, or one that has been converted to
an icon, by designating it as the current display window and then invoking the function
glutShowWindow ( );
GLUT Subwindows
Within a selected display window, we can set up any number of second-level display
windows, which are called subwindows.
We create a subwindow with the following function:
glutCreateSubWindow (windowID, xBottomLeft, yBottomLeft, width, height);
Parameter windowID identifies the display window in which we want to set up the
subwindow.
Subwindows are assigned a positive integer identifier in the same way that first-level
display windows are numbered, and we can place a subwindow inside another
subwindow.
Each subwindow can be assigned an individual display mode and other parameters. We
can even reshape, reposition, push, pop, hide, and show subwindows