head 1.3; access; symbols; locks; strict; comment @# @; 1.3 date 2002.09.07.01.50.35; author curt; state Exp; branches; next 1.2; 1.2 date 2002.08.31.19.01.50; author curt; state Exp; branches; next 1.1; 1.1 date 2002.08.31.18.53.58; author curt; state Exp; branches; next ; desc @@ 1.3 log @Updated doxygen docs. @ text @
Main Page Class Hierarchy Compound List File List Compound Members File Members

# MAT3geom.c

    00001 /* #include "HEADERS.h" */
    00002 /* Copyright 1988, Brown Computer Graphics Group.  All Rights Reserved. */
    00003
    00004 /* --------------------------------------------------------------------------
    00005  * This file contains routines that perform geometry-related operations
    00006  * on matrices.
    00007  * -------------------------------------------------------------------------*/
    00008
    00009 #include "mat3defs.h"
    00010
    00011 /* --------------------------  Static Routines  ---------------------------- */
    00012
    00013 /* -------------------------  Internal Routines  --------------------------- */
    00014
    00015 /* --------------------------  Public Routines  ---------------------------- */
    00016
    00017 /*
    00018  * This takes a matrix used to transform points, and returns a corresponding
    00019  * matrix that can be used to transform direction vectors (between points).
    00020  */
    00021
    00022 void
    00023 MAT3direction_matrix(register double (*result_mat)[4], register double (*mat)[4])
    00024 {
    00025    register int i;
    00026
    00027    MAT3copy(result_mat, mat);
    00028
    00029    for (i = 0; i < 4; i++) result_mat[i][3] = result_mat[3][i] = 0.0;
    00030
    00031    result_mat[3][3] = 1.0;
    00032 }
    00033
    00034 /*
    00035  * This takes a matrix used to transform points, and returns a corresponding
    00036  * matrix that can be used to transform vectors that must remain perpendicular
    00037  * to planes defined by the points.  It is useful when you are transforming
    00038  * some object that has both points and normals in its definition, and you
    00039  * only have the transformation matrix for the points.  This routine returns
    00040  * FALSE if the normal matrix is uncomputable.  Otherwise, it returns TRUE.
    00041  *
    00042  * Spike sez: "This is the adjoint for the non-homogeneous part of the
    00043  *             transformation."
    00044  */
    00045
    00046 int
    00047 MAT3normal_matrix(register double (*result_mat)[4], register double (*mat)[4])
    00048 {
    00049    register int ret;
    00050    MAT3mat      tmp_mat;
    00051
    00052    MAT3direction_matrix(result_mat, mat);
    00053
    00054    if ( (ret = MAT3invert(tmp_mat, tmp_mat)) ) {
    00055        MAT3transpose(result_mat, tmp_mat);
    00056    }
    00057
    00058    return(ret);
    00059 }
    00060
    00061 /*
    00062  * Sets the given matrix to be a scale matrix for the given vector of
    00063  * scale values.
    00064  */
    00065
    00066 void
    00067 MAT3scale(double (*result_mat)[4], double *scale)
    00068 {
    00069    MAT3identity(result_mat);
    00070
    00071    result_mat[0][0] = scale[0];
    00072    result_mat[1][1] = scale[1];
    00073    result_mat[2][2] = scale[2];
    00074 }
    00075
    00076 /*
    00077  * Sets up a matrix for a rotation about an axis given by the line from
    00078  * (0,0,0) to axis, through an angle (in radians).
    00079  * Looking along the axis toward the origin, the rotation is counter-clockwise.
    00080  */
    00081
    00082 #define SELECT  .7071   /* selection constant (roughly .5*sqrt(2) */
    00083
    00084 void
    00085 MAT3rotate(double (*result_mat)[4], double *axis, double angle_in_radians)
    00086 {
    00087    MAT3vec      naxis,  /* Axis of rotation, normalized                 */
    00088                 base2,  /* 2nd unit basis vec, perp to axis             */
    00089                 base3;  /* 3rd unit basis vec, perp to axis & base2     */
    00090    double       dot;
    00091    MAT3mat      base_mat,       /* Change-of-basis matrix               */
    00092                 base_mat_trans; /* Inverse of c-o-b matrix              */
    00093    register int i;
    00094
    00095    /* Step 1: extend { axis } to a basis for 3-space: { axis, base2, base3 }
    00096     * which is orthonormal (all three have unit length, and all three are
    00097     * mutually orthogonal). Also should be oriented, i.e. axis cross base2 =
    00098     * base3, rather than -base3.
    00099     *
    00100     * Method: Find a vector linearly independent from axis. For this we
    00101     * either use the y-axis, or, if that is too close to axis, the
    00102     * z-axis. 'Too close' means that the dot product is too near to 1.
    00103     */
    00104
    00105    MAT3_COPY_VEC(naxis, axis);
    00106    MAT3_NORMALIZE_VEC(naxis, dot);
    00107
    00108    if (dot == 0.0) {
    00109        /* ERR_ERROR(MAT3_errid, ERR_SEVERE,
    00110                    (ERR_S, "Zero-length axis vector given to MAT3rotate")); */
    00111       return;
    00112    }
    00113
    00114    MAT3perp_vec(base2, naxis, TRUE);
    00115    MAT3cross_product(base3, naxis, base2);
    00116
    00117    /* Set up the change-of-basis matrix, and its inverse */
    00118    MAT3identity(base_mat);
    00119    MAT3identity(base_mat_trans);
    00120    MAT3identity(result_mat);
    00121
    00122    for (i = 0; i < 3; i++){
    00123       base_mat_trans[i][0] = base_mat[0][i] = naxis[i];
    00124       base_mat_trans[i][1] = base_mat[1][i] = base2[i];
    00125       base_mat_trans[i][2] = base_mat[2][i] = base3[i];
    00126    }
    00127
    00128    /* If T(u) = uR, where R is base_mat, then T(x-axis) = naxis,
    00129     * T(y-axis) = base2, and T(z-axis) = base3. The inverse of base_mat is
    00130     * its transpose.  OK?
    00131     */
    00132
    00133    result_mat[1][1] =   result_mat[2][2] = cos(angle_in_radians);
    00134    result_mat[2][1] = -(result_mat[1][2] = sin(angle_in_radians));
    00135
    00136    MAT3mult(result_mat, base_mat_trans, result_mat);
    00137    MAT3mult(result_mat, result_mat,     base_mat);
    00138 }
    00139
    00140 /*
    00141  * Sets the given matrix to be a translation matrix for the given vector of
    00142  * translation values.
    00143  */
    00144
    00145 void
    00146 MAT3translate(double (*result_mat)[4], double *trans)
    00147 {
    00148    MAT3identity(result_mat);
    00149
    00150    result_mat[3][0] = trans[0];
    00151    result_mat[3][1] = trans[1];
    00152    result_mat[3][2] = trans[2];
    00153 }
    00154
    00155 /*
    00156  * Sets the given matrix to be a shear matrix for the given x and y shear
    00157  * values.
    00158  */
    00159
    00160 void
    00161 MAT3shear(double (*result_mat)[4], double xshear, double yshear)
    00162 {
    00163    MAT3identity(result_mat);
    00164
    00165    result_mat[2][0] = xshear;
    00166    result_mat[2][1] = yshear;
    00167 }
    00168

@ 1.2 log @Oops, try again. @ text @d177 1 a177 1