home *** CD-ROM | disk | FTP | other *** search
- /* Copyright 1991, Brown Computer Graphics Group. All Rights Reserved. */
-
- #include "mat3.h"
-
- /* -------------------------------------------------------------------------
- * DESCR : Takes a 3-vector of scale values, and creates a matrix with
- * these as its diagonal entries and zeroes off the diagonal,
- * i.e., a scale matrix with scale factors given by the entries
- * of the given vector.
- *
- * RETURNS : void
- * ------------------------------------------------------------------------- */
- void
- MAT3scale(
- MAT3mat result_mat, /* A diagonal matrix (a scaling matrix) */
- MAT3vec scale /* The entries for the diagonal */
- )
- {
- MAT3identity(result_mat);
-
- result_mat[0][0] = scale[0];
- result_mat[1][1] = scale[1];
- result_mat[2][2] = scale[2];
- }
-
- /* -------------------------------------------------------------------------
- * DESCR : Sets the matrix @result_mat@ to be a translation matrix that
- * will translate by the vector @trans@.
- *
- * RETURNS : void
- * ------------------------------------------------------------------------- */
- void
- MAT3translate(
- MAT3mat result_mat, /* Translation matrix [output] */
- MAT3vec trans /* Translation vector [input] */
- )
- {
- MAT3identity(result_mat);
-
- result_mat[0][3] = trans[0];
- result_mat[1][3] = trans[1];
- result_mat[2][3] = trans[2];
- }
-
- /* -------------------------------------------------------------------------
- * DESCR : Sets @result_mat@ to be a shear matrix that does the
- * following:Given a plane normal (@normal@) and a shear vector
- * (@shear@), the transformation leaves points in the plane
- * (through the origin, perp to the normal) fixed, while moving
- * points at a distance d from the plane by d times the shear
- * vector. (The shear vector is first made to be perpendicular
- * to the normal.) The normal vector is assumed to be unit
- * length, and results are incorrect if it is not.
- *
- * RETURNS : void
- * ------------------------------------------------------------------------- */
- void
- MAT3shear(
- register MAT3mat result_mat, /* A shear matrix generated by this routine */
- register MAT3vec normal, /* The normal to the shear plane */
- register MAT3vec shear /* The shearing vector [perp to normal] */
- )
- {
- register int j;
- register double *shear_used = shear;
- double dot;
- MAT3vec shear2;
-
- MAT3identity(result_mat);
-
- /* Make sure shear vector is perpendicular to the normal */
- dot = MAT3_DOT_PRODUCT(normal, shear);
-
- if (! MAT3_IS_ZERO(dot)) {
- shear_used = shear2;
- MAT3_SCALE_VEC(shear_used, normal, dot);
- MAT3_SUB_VEC(shear_used, shear, shear_used);
- }
-
- /* Set columns to coordinate axes transformed by shear */
- for (j = 0; j < 3; j++) {
- result_mat[j][0] += normal[0] * shear_used[j];
- result_mat[j][1] += normal[1] * shear_used[j];
- result_mat[j][2] += normal[2] * shear_used[j];
- }
- }
-
- /* -------------------------------------------------------------------------
- * DESCR : Sets @m@ to be the identity matrix.
- *
- * RETURNS : void
- * ------------------------------------------------------------------------- */
- void
- MAT3identity(
- MAT3mat m /* Matrix to be set to identity */
- )
- {
- double *mat = (double *)m;
-
- *mat++ = 1.0;
- *mat++ = 0.0;
- *mat++ = 0.0;
- *mat++ = 0.0;
-
- *mat++ = 0.0;
- *mat++ = 1.0;
- *mat++ = 0.0;
- *mat++ = 0.0;
-
- *mat++ = 0.0;
- *mat++ = 0.0;
- *mat++ = 1.0;
- *mat++ = 0.0;
-
- *mat++ = 0.0;
- *mat++ = 0.0;
- *mat++ = 0.0;
- *mat = 1.0;
- }
-
- /* -------------------------------------------------------------------------
- * DESCR : Sets @m@ to be the zero matrix.
- *
- * RETURNS : void
- * ------------------------------------------------------------------------- */
- void
- MAT3zero(
- MAT3mat m /* Matrix to be set to zero */
- )
- {
- double *mat = (double *)m;
-
- *mat++ = 0.0;
- *mat++ = 0.0;
- *mat++ = 0.0;
- *mat++ = 0.0;
-
- *mat++ = 0.0;
- *mat++ = 0.0;
- *mat++ = 0.0;
- *mat++ = 0.0;
-
- *mat++ = 0.0;
- *mat++ = 0.0;
- *mat++ = 0.0;
- *mat++ = 0.0;
-
- *mat++ = 0.0;
- *mat++ = 0.0;
- *mat++ = 0.0;
- *mat = 0.0;
- }
-
- /* -------------------------------------------------------------------------
- * DESCR : Copy the matrix @f@ into the matrix @t@.
- *
- * RETURNS : void
- * ------------------------------------------------------------------------- */
- void
- MAT3copy(
- MAT3mat t, /* Target matrix [output] */
- MAT3mat f /* Source matrix [input] */
- )
- {
- double *to = (double *)t;
- double *from = (double *)f;
-
- *to++ = *from++;
- *to++ = *from++;
- *to++ = *from++;
- *to++ = *from++;
-
- *to++ = *from++;
- *to++ = *from++;
- *to++ = *from++;
- *to++ = *from++;
-
- *to++ = *from++;
- *to++ = *from++;
- *to++ = *from++;
- *to++ = *from++;
-
- *to++ = *from++;
- *to++ = *from++;
- *to++ = *from++;
- *to = *from;
- }
-
- /* -------------------------------------------------------------------------
- * DESCR : Computes the matrix product @mat1@ * @mat2@ and places the
- * result in @result_mat@. The matrices being multiplied may be the
- * same as the result, i.e., a call of the form MAT3mult(a,a,b) is
- * safe.
- *
- * RETURNS : void
- * ------------------------------------------------------------------------- */
- void
- MAT3mult(
- MAT3mat result_mat, /* The computed product of the next two args */
- MAT3mat mat1, /* The first factor of the product */
- MAT3mat mat2 /* The second factor of the product */
- )
- {
- int i, j;
- MAT3mat tmp_mat;
- double *tmp;
-
- if (((tmp = (double*)result_mat) == (double*)mat1) ||
- (tmp == (double*)mat2))
- tmp = (double*)tmp_mat;
-
- for (i = 0; i < 4; i++) for (j = 0; j < 4; j++)
- *(tmp++) = (mat1[i][0] * mat2[0][j] +
- mat1[i][1] * mat2[1][j] +
- mat1[i][2] * mat2[2][j] +
- mat1[i][3] * mat2[3][j]);
-
- if (((double*)result_mat == (double*)mat1) ||
- ((double*)result_mat == (double*)mat2))
- MAT3copy(result_mat, tmp_mat);
-
- return;
- }
-
- /* -------------------------------------------------------------------------
- * DESCR : Multiplies the vector of size 4 (@vec@) by the matrix @mat@,
- * placing the result in @result_vec@. (The multiplication is of
- * the form matrix times vector, and the vector should be
- * considered to be a column vector). The fourth element of the
- * vector is the homogeneous coordinate, which may or may not be
- * 1. If the @homogenize@ parameter is TRUE, then the result
- * vector will be normalized so that the homogeneous coordinate
- * is 1. The two vectors involved may be the same. This returns
- * zero if the vector was to be homogenized, but couldn't be.
- *
- *
- * RETURNS : FALSE if the result vector was to be homogenized, but had
- * homogeneous coordinate zero. In this case, the results should
- * be regarded as garbage. Otherwise the routine returns TRUE.
- * ------------------------------------------------------------------------- */
- int
- MAT3mult_hvec(
- MAT3hvec result_vec, /* The product of vec with mat (output) */
- register MAT3hvec vec, /* The vector to multiply (input) */
- register MAT3mat mat, /* The matrix to multiply (input) */
- int homogenize /* Should we homogenize the result? */
- )
- {
- MAT3hvec tempvec;
- double norm_fac;
- register double *temp = tempvec;
- register int ret = 1;
-
- temp[0] = vec[0] * mat[0][0] + vec[1] * mat[0][1] +
- vec[2] * mat[0][2] + vec[3] * mat[0][3];
- temp[1] = vec[0] * mat[1][0] + vec[1] * mat[1][1] +
- vec[2] * mat[1][2] + vec[3] * mat[1][3];
- temp[2] = vec[0] * mat[2][0] + vec[1] * mat[2][1] +
- vec[2] * mat[2][2] + vec[3] * mat[2][3];
- temp[3] = vec[0] * mat[3][0] + vec[1] * mat[3][1] +
- vec[2] * mat[3][2] + vec[3] * mat[3][3];
-
- /* Homogenize if asked for, possible, and necessary */
- if (homogenize) {
- if (MAT3_IS_ZERO(temp[3])) {
- /* SEVERES("Can't homogenize vec. in MAT3mult_hvec: last coord is 0"); */
- ret = 0;
- }
- else {
- norm_fac = 1.0 / temp[3];
- MAT3_SCALE_VEC(result_vec, temp, norm_fac);
- result_vec[3] = 1.0;
- }
- }
- else MAT3_COPY_HVEC(result_vec, temp);
-
- return(ret);
- }
-
- /* -------------------------------------------------------------------------
- * DESCR : Set @result_vec@ to be the cross product of @vec1@ and
- * @vec2@, in that order.
- *
- * RETURNS : void
- * ------------------------------------------------------------------------- */
- void
- MAT3cross_product(
- MAT3vec result_vec, /* The computed cross-product (output) */
- register MAT3vec vec1, /* The first factor (input) */
- register MAT3vec vec2 /* The second factor (input) */
- )
- {
- MAT3vec tempvec;
- register double *temp = tempvec;
-
- temp[0] = vec1[1] * vec2[2] - vec1[2] * vec2[1];
- temp[1] = vec1[2] * vec2[0] - vec1[0] * vec2[2];
- temp[2] = vec1[0] * vec2[1] - vec1[1] * vec2[0];
-
- MAT3_COPY_VEC(result_vec, temp);
- }
-
-
-