CS-460, Week 6
Spring, 1998
R. Eckert


As seen in class, any two-dimensional affine transformation that maps a
point P into a transformed point P' can implemented by using homogeneous
coordinates. The points are represented by the column vectors P and P':

      |x|           |x'|
  P = |y|      P' = |y'|
      |1|           |1 |

The transformation is achieved by using a 3 X 3 homogeneous transformation
matrix of the form:

      | a0  a1  a2 |
  M = | a3  a4  a5 |
      | 0   0   1  |

The values of the matrix elements determine the type of transformation.
(For example, translations, rotations, scaling, etc.)

In general, we obtain the transformed point P' from the original point P'
by performing a matrix multiplication:

  P' = M * P

This allows us to set up a set of functions that will transform points.
Once these are set up, we can devise other functions that will perform
transformations on polygons--since a polygon is nothing more than an
array of points.

Assume we store the six nontrivial homogeneous transformation elements
in a one-dimensional array A. The elements are a[i]. Then any geometric
transformation can be represented by the following matrix:

      | a[0] a[1] a[2] |
  M = | a[3] a[4] a[5] |
      |  0    0    1   |

We can define the following functions that will enable us to set up and
transform points and polygons:

void settranslate(float a[6],float dx,float dy); // set up translation matrix
void setscale(float a[6], float sx, float sy);  // set up scaling matrix
void setrotate(float a[6], float theta);        // set up rotation matrix
void combine(float c[6], float a[6], float b[6]);   // C = A * B
void xformcoord(float c[6], POINT vi, POINT* vo);   // vo = c * vi
void xformpoly(int n, POINT inpts[], POINT outpts[], float t[6]);

The first three of these functions take the parameters that define
translation, scaling (with respect to the origin) rotation (about the
origin), and compute the transformation matrix elements a[i].

The combine() function computes the nontrivial composite transformation
matrix elements of the matrix C which is equivalent to the concatenation
of transformations A and B (C = A * B).

The xformcoord() function takes an input POINT (vi, with x,y coordinates)
and generates output POINT (vo, with x',y' coordinates) that would result
from the transformation represented by the transformation matrix C whose
nontrivial matrix elements are c[i].

The function xformpoly() takes an array of input POINTs (an input
polygon) and a transformation represented by non-trivial matrix elements
t[i], and generates an array of ouput POINTS (an output polygon) that is
the result of the transformation represented by the t[i]. This function
will make n calls to xformcoord(), where n is the number of points in the
input polygon.


We do this by using the fact that a rotation about the point (dx,dy) can
be achieved by the composite transformation:

1. Translate so the vertex is at the origin (-dx,-dy); 'Matrix' T1
2. Rotate about the origin by theta; 'Matrix R'
3. Translate back (+dx,+dy); Matrix T2

The composite transformation matrix would be:  T = T2*R*T1

The code might be as follows:

POINT p[4];                       // input polygon
POINT px[4];                      // transformed polygon
int n=4;                          // number of vertices
int pts[]={0,0,50,0,50,70,0,70};  // x,y coordinates of polygon vertices
float theta=30;                   // the angle of rotation
float dx=50,dy=70;        // vertex about which polygon will be rotated

float xlate[6];           // the transformation 'matrices'
float rotate[6];
float temp[6];
float final[6];

for (int i=0; i<n; i++)   // set up the input polygon

DrawPolygon(p,n);         // polygon drawing routine--Polygon() in Windows.
                          // Here we're drawing the original polygon.

settranslate(xlate,-dx,-dy);      // set up T1 translation matrix
setrotate(rotate,theta);          // set up R rotaton matrix
combine (temp,rotate,xlate);      // compute R*T1 and save in temp
settranslate(xlate,dx,dy);        // set up T2 translation matrix
combine(final, xlate,temp);       // compute T2*(R*T1) & save in final
xformpoly(n,p,px,final);          // get the transformed polygon px

DrawPolygon(px,n);        // draw the transformed polygon


By making proper calls to the functions declared above, we could implement
a function trans_poly() that translates a polygon by tx,ty, a function
rotate_poly() that rotates a polygon by an angle theta about the point
(tx,ty), and a function scale_poly() that scales a polygon by scaling
factors sx and sy with respect to the point (tx,ty). The function
prototypes might be as follows:

void trans_poly(int n,POINT p[],POINT px[],int tx,int ty);
void rotate_poly(int n,POINT p[],POINT px[],int theta,int tx,int ty);
void scale_poly(int n,POINT p[],POINT px[],float sx,float sy,int tx,int ty);