The functions acedDragGen(), acedGrVecs(), acedNEntSelP(), and acedXformSS() multiply the input vectors by the transformation matrix defined as a 4x4 array of real values.
typedef ads_real ads_matrix[4][4];
The first three columns of the matrix specify scaling and rotation. The fourth column of the matrix is a translation vector. ObjectARX defines the symbol T to represent the coordinate of this vector, as follows:
#define T 3
The matrix can be expressed as follows:
The following function initializes an identity matrix.
void ident_init(ads_matrix id) { int i, j; for (i=0; i<=3; i++) for (j=0; j<=3; j++) id[i][j] = 0.0; for (i=0; i<=3; i++) id[i][i] = 1.0; }
The functions that pass arguments of the ads_matrix type treat a point as a column vector of dimension 4. The point is expressed in homogeneous coordinates, where the fourth element of the point vector is a scale factor that is normally set to 1.0. The final row of the matrix has the nominal value of [0,0,0,1]; it is ignored by the functions that pass ads_matrix arguments. In this case, the following matrix multiplication results from the application of a transformation to a point:
This multiplication gives us the individual coordinates of the point as follows:
As these equations show, the scale factor and the last row of the matrix have no effect and are ignored. This is known as an affine transformation.
The following function implements the previous equations to transform a single point:
void xformpt(xform, pt, newpt) ads_matrix xform; ads_point pt, newpt; { int i, j; newpt[X] = newpt[Y] = newpt[Z] = 0.0; for (i=X; i<=Z; i++) { for (j=X; j<=Z; j++) newpt[i] += xform[i][j] * pt[j]; // Add the translation vector. newpt[i] += xform[i][T]; } }
The following figure summarizes some basic geometrical transformations. (The values in an ads_matrix are actually ads_real, but they are shown here as integers for readability and to conform to mathematical convention.)
The acedXformSS() function—unlike the acedDragGen(), acedGrVecs(), or acedNEntSelP() functions—requires the matrix to do uniform scaling. That is, in the transformation matrix that you pass to acedXformSS(), the elements in the scaling vector S X S Y S Z must all be equal; in matrix notation, M 00 = M 11 = M 22 . Three-dimensional rotation is a slightly different case, as shown in the following figure:
For uniform rotations, the 3x3 submatrix delimited by [0,0] and [2,2] is orthonormal. That is, each row is a unit vector and is perpendicular to the other rows; the scalar (dot) product of two rows is zero. The columns are also unit vectors that are perpendicular to each other. The product of an orthonormal matrix and its transpose equals the identity matrix. Two complementary rotations have no net effect.
Complex transformations can be accomplished by combining (or composing) nonidentity values in a single matrix.