1 /* #include "HEADERS.h" */
2 /* Copyright 1988, Brown Computer Graphics Group. All Rights Reserved. */
4 /* --------------------------------------------------------------------------
5 * This file contains routines that perform geometry-related operations
7 * -------------------------------------------------------------------------*/
11 /* -------------------------- Static Routines ---------------------------- */
13 /* ------------------------- Internal Routines --------------------------- */
15 /* -------------------------- Public Routines ---------------------------- */
18 * This takes a matrix used to transform points, and returns a corresponding
19 * matrix that can be used to transform direction vectors (between points).
23 MAT3direction_matrix(result_mat, mat)
24 register MAT3mat result_mat, mat;
28 MAT3copy(result_mat, mat);
30 for (i = 0; i < 4; i++) result_mat[i][3] = result_mat[3][i] = 0.0;
32 result_mat[3][3] = 1.0;
36 * This takes a matrix used to transform points, and returns a corresponding
37 * matrix that can be used to transform vectors that must remain perpendicular
38 * to planes defined by the points. It is useful when you are transforming
39 * some object that has both points and normals in its definition, and you
40 * only have the transformation matrix for the points. This routine returns
41 * FALSE if the normal matrix is uncomputable. Otherwise, it returns TRUE.
43 * Spike sez: "This is the adjoint for the non-homogeneous part of the
48 MAT3normal_matrix(result_mat, mat)
49 register MAT3mat result_mat, mat;
54 MAT3direction_matrix(result_mat, mat);
56 if (ret = MAT3invert(tmp_mat, tmp_mat)) MAT3transpose(result_mat, tmp_mat);
62 * Sets the given matrix to be a scale matrix for the given vector of
67 MAT3scale(result_mat, scale)
71 MAT3identity(result_mat);
73 result_mat[0][0] = scale[0];
74 result_mat[1][1] = scale[1];
75 result_mat[2][2] = scale[2];
79 * Sets up a matrix for a rotation about an axis given by the line from
80 * (0,0,0) to axis, through an angle (in radians).
81 * Looking along the axis toward the origin, the rotation is counter-clockwise.
84 #define SELECT .7071 /* selection constant (roughly .5*sqrt(2) */
87 MAT3rotate(result_mat, axis, angle_in_radians)
90 double angle_in_radians;
92 MAT3vec naxis, /* Axis of rotation, normalized */
93 base2, /* 2nd unit basis vec, perp to axis */
94 base3; /* 3rd unit basis vec, perp to axis & base2 */
96 MAT3mat base_mat, /* Change-of-basis matrix */
97 base_mat_trans; /* Inverse of c-o-b matrix */
100 /* Step 1: extend { axis } to a basis for 3-space: { axis, base2, base3 }
101 * which is orthonormal (all three have unit length, and all three are
102 * mutually orthogonal). Also should be oriented, i.e. axis cross base2 =
103 * base3, rather than -base3.
105 * Method: Find a vector linearly independent from axis. For this we
106 * either use the y-axis, or, if that is too close to axis, the
107 * z-axis. 'Too close' means that the dot product is too near to 1.
110 MAT3_COPY_VEC(naxis, axis);
111 MAT3_NORMALIZE_VEC(naxis, dot);
114 /* ERR_ERROR(MAT3_errid, ERR_SEVERE,
115 (ERR_S, "Zero-length axis vector given to MAT3rotate")); */
119 MAT3perp_vec(base2, naxis, TRUE);
120 MAT3cross_product(base3, naxis, base2);
122 /* Set up the change-of-basis matrix, and its inverse */
123 MAT3identity(base_mat);
124 MAT3identity(base_mat_trans);
125 MAT3identity(result_mat);
127 for (i = 0; i < 3; i++){
128 base_mat_trans[i][0] = base_mat[0][i] = naxis[i];
129 base_mat_trans[i][1] = base_mat[1][i] = base2[i];
130 base_mat_trans[i][2] = base_mat[2][i] = base3[i];
133 /* If T(u) = uR, where R is base_mat, then T(x-axis) = naxis,
134 * T(y-axis) = base2, and T(z-axis) = base3. The inverse of base_mat is
138 result_mat[1][1] = result_mat[2][2] = cos(angle_in_radians);
139 result_mat[2][1] = -(result_mat[1][2] = sin(angle_in_radians));
141 MAT3mult(result_mat, base_mat_trans, result_mat);
142 MAT3mult(result_mat, result_mat, base_mat);
146 * Sets the given matrix to be a translation matrix for the given vector of
147 * translation values.
151 MAT3translate(result_mat, trans)
155 MAT3identity(result_mat);
157 result_mat[3][0] = trans[0];
158 result_mat[3][1] = trans[1];
159 result_mat[3][2] = trans[2];
163 * Sets the given matrix to be a shear matrix for the given x and y shear
168 MAT3shear(result_mat, xshear, yshear)
170 double xshear, yshear;
172 MAT3identity(result_mat);
174 result_mat[2][0] = xshear;
175 result_mat[2][1] = yshear;