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(register double (*result_mat)[4], register double (*mat)[4])
27 MAT3copy(result_mat, mat);
29 for (i = 0; i < 4; i++) result_mat[i][3] = result_mat[3][i] = 0.0;
31 result_mat[3][3] = 1.0;
35 * This takes a matrix used to transform points, and returns a corresponding
36 * matrix that can be used to transform vectors that must remain perpendicular
37 * to planes defined by the points. It is useful when you are transforming
38 * some object that has both points and normals in its definition, and you
39 * only have the transformation matrix for the points. This routine returns
40 * FALSE if the normal matrix is uncomputable. Otherwise, it returns TRUE.
42 * Spike sez: "This is the adjoint for the non-homogeneous part of the
47 MAT3normal_matrix(register double (*result_mat)[4], register double (*mat)[4])
52 MAT3direction_matrix(result_mat, mat);
54 if ( (ret = MAT3invert(tmp_mat, tmp_mat)) ) {
55 MAT3transpose(result_mat, tmp_mat);
62 * Sets the given matrix to be a scale matrix for the given vector of
67 MAT3scale(double (*result_mat)[4], double *scale)
69 MAT3identity(result_mat);
71 result_mat[0][0] = scale[0];
72 result_mat[1][1] = scale[1];
73 result_mat[2][2] = scale[2];
77 * Sets up a matrix for a rotation about an axis given by the line from
78 * (0,0,0) to axis, through an angle (in radians).
79 * Looking along the axis toward the origin, the rotation is counter-clockwise.
82 #define SELECT .7071 /* selection constant (roughly .5*sqrt(2) */
85 MAT3rotate(double (*result_mat)[4], double *axis, double angle_in_radians)
87 MAT3vec naxis, /* Axis of rotation, normalized */
88 base2, /* 2nd unit basis vec, perp to axis */
89 base3; /* 3rd unit basis vec, perp to axis & base2 */
91 MAT3mat base_mat, /* Change-of-basis matrix */
92 base_mat_trans; /* Inverse of c-o-b matrix */
95 /* Step 1: extend { axis } to a basis for 3-space: { axis, base2, base3 }
96 * which is orthonormal (all three have unit length, and all three are
97 * mutually orthogonal). Also should be oriented, i.e. axis cross base2 =
98 * base3, rather than -base3.
100 * Method: Find a vector linearly independent from axis. For this we
101 * either use the y-axis, or, if that is too close to axis, the
102 * z-axis. 'Too close' means that the dot product is too near to 1.
105 MAT3_COPY_VEC(naxis, axis);
106 MAT3_NORMALIZE_VEC(naxis, dot);
109 /* ERR_ERROR(MAT3_errid, ERR_SEVERE,
110 (ERR_S, "Zero-length axis vector given to MAT3rotate")); */
114 MAT3perp_vec(base2, naxis, TRUE);
115 MAT3cross_product(base3, naxis, base2);
117 /* Set up the change-of-basis matrix, and its inverse */
118 MAT3identity(base_mat);
119 MAT3identity(base_mat_trans);
120 MAT3identity(result_mat);
122 for (i = 0; i < 3; i++){
123 base_mat_trans[i][0] = base_mat[0][i] = naxis[i];
124 base_mat_trans[i][1] = base_mat[1][i] = base2[i];
125 base_mat_trans[i][2] = base_mat[2][i] = base3[i];
128 /* If T(u) = uR, where R is base_mat, then T(x-axis) = naxis,
129 * T(y-axis) = base2, and T(z-axis) = base3. The inverse of base_mat is
133 result_mat[1][1] = result_mat[2][2] = cos(angle_in_radians);
134 result_mat[2][1] = -(result_mat[1][2] = sin(angle_in_radians));
136 MAT3mult(result_mat, base_mat_trans, result_mat);
137 MAT3mult(result_mat, result_mat, base_mat);
141 * Sets the given matrix to be a translation matrix for the given vector of
142 * translation values.
146 MAT3translate(double (*result_mat)[4], double *trans)
148 MAT3identity(result_mat);
150 result_mat[3][0] = trans[0];
151 result_mat[3][1] = trans[1];
152 result_mat[3][2] = trans[2];
156 * Sets the given matrix to be a shear matrix for the given x and y shear
161 MAT3shear(double (*result_mat)[4], double xshear, double yshear)
163 MAT3identity(result_mat);
165 result_mat[2][0] = xshear;
166 result_mat[2][1] = yshear;