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

# MAT3vec.c

    00001 /* Copyright 1988, Brown Computer Graphics Group.  All Rights Reserved. */
    00002
    00003 /* --------------------------------------------------------------------------
    00004  * This file contains routines that operate on matrices and vectors, or
    00005  * vectors and vectors.
    00006  * -------------------------------------------------------------------------*/
    00007
    00008 /* #include "sphigslocal.h" */
    00009
    00010 /* --------------------------  Static Routines  ---------------------------- */
    00011
    00012 /* -------------------------  Internal Routines  --------------------------- */
    00013
    00014 /* --------------------------  Public Routines  ---------------------------- */
    00015
    00016 /*
    00017  * Multiplies a vector by a matrix, setting the result vector.
    00018  * It assumes all homogeneous coordinates are 1.
    00019  * The two vectors involved may be the same.
    00020  */
    00021
    00022 #include "mat3.h"
    00023
    00024 #ifndef TRUE
    00025 #  define TRUE 1
    00026 #endif
    00027
    00028 #ifndef FALSE
    00029 #  define FALSE 0
    00030 #endif
    00031
    00032 #if !defined( USE_XTRA_MAT3_INLINES )
    00033
    00034 void
    00035 MAT3mult_vec(double *result_vec, register double *vec, register double (*mat)[4])
    00036 {
    00037    MAT3vec              tempvec;
    00038    register double      *temp = tempvec;
    00039
    00040    temp[0] =    vec[0] * mat[0][0] + vec[1] * mat[1][0] +
    00041                 vec[2] * mat[2][0] +          mat[3][0];
    00042    temp[1] =    vec[0] * mat[0][1] + vec[1] * mat[1][1] +
    00043                 vec[2] * mat[2][1] +          mat[3][1];
    00044    temp[2] =    vec[0] * mat[0][2] + vec[1] * mat[1][2] +
    00045                 vec[2] * mat[2][2] +          mat[3][2];
    00046
    00047    MAT3_COPY_VEC(result_vec, temp);
    00048 }
    00049 #endif // !defined( USE_XTRA_MAT3_INLINES )
    00050
    00051 /*
    00052  * Multiplies a vector of size 4 by a matrix, setting the result vector.
    00053  * The fourth element of the vector is the homogeneous coordinate, which
    00054  * may or may not be 1.  If the "normalize" parameter is TRUE, then the
    00055  * result vector will be normalized so that the homogeneous coordinate is 1.
    00056  * The two vectors involved may be the same.
    00057  * This returns zero if the vector was to be normalized, but couldn't be.
    00058  */
    00059
    00060 int
    00061 MAT3mult_hvec(double *result_vec, register double *vec, register double (*mat)[4], int normalize)
    00062 {
    00063    MAT3hvec             tempvec;
    00064    double               norm_fac;
    00065    register double      *temp = tempvec;
    00066    register int         ret = TRUE;
    00067
    00068    temp[0] =    vec[0] * mat[0][0] + vec[1] * mat[1][0] +
    00069                 vec[2] * mat[2][0] + vec[3] * mat[3][0];
    00070    temp[1] =    vec[0] * mat[0][1] + vec[1] * mat[1][1] +
    00071                 vec[2] * mat[2][1] + vec[3] * mat[3][1];
    00072    temp[2] =    vec[0] * mat[0][2] + vec[1] * mat[1][2] +
    00073                 vec[2] * mat[2][2] + vec[3] * mat[3][2];
    00074    temp[3] =    vec[0] * mat[0][3] + vec[1] * mat[1][3] +
    00075                 vec[2] * mat[2][3] + vec[3] * mat[3][3];
    00076
    00077    /* Normalize if asked for, possible, and necessary */
    00078    if (normalize) {
    00079       if (MAT3_IS_ZERO(temp[3])) {
    00080 #ifndef THINK_C
    00081          fprintf (stderr,
    00082                   "Can't normalize vector: homogeneous coordinate is 0");
    00083 #endif
    00084          ret = FALSE;
    00085       }
    00086       else {
    00087          norm_fac = 1.0 / temp[3];
    00088          MAT3_SCALE_VEC(result_vec, temp, norm_fac);
    00089          result_vec[3] = 1.0;
    00090       }
    00091    }
    00092    else MAT3_COPY_HVEC(result_vec, temp);
    00093
    00094    return(ret);
    00095 }
    00096
    00097 #if !defined( USE_XTRA_MAT3_INLINES )
    00098
    00099 /*
    00100  * Sets the first vector to be the cross-product of the last two vectors.
    00101  */
    00102
    00103 void
    00104 MAT3cross_product(double *result_vec, register double *vec1, register double *vec2)
    00105 {
    00106    MAT3vec              tempvec;
    00107    register double      *temp = tempvec;
    00108
    00109    temp[0] = vec1[1] * vec2[2] - vec1[2] * vec2[1];
    00110    temp[1] = vec1[2] * vec2[0] - vec1[0] * vec2[2];
    00111    temp[2] = vec1[0] * vec2[1] - vec1[1] * vec2[0];
    00112
    00113    MAT3_COPY_VEC(result_vec, temp);
    00114 }
    00115 #endif // !defined( USE_XTRA_MAT3_INLINES )
    00116
    00117 /*
    00118  * Finds a vector perpendicular to vec and stores it in result_vec.
    00119  * Method:  take any vector (we use <0,1,0>) and subtract the
    00120  * portion of it pointing in the vec direction.  This doesn't
    00121  * work if vec IS <0,1,0> or is very near it.  So if this is
    00122  * the case, use <0,0,1> instead.
    00123  * If "is_unit" is TRUE, the given vector is assumed to be unit length.
    00124  */
    00125
    00126 #define SELECT  .7071   /* selection constant (roughly .5*sqrt(2) */
    00127
    00128 void
    00129 MAT3perp_vec(double *result_vec, double *vec, int is_unit)
    00130 {
    00131    MAT3vec      norm;
    00132    double       dot;
    00133
    00134    MAT3_SET_VEC(result_vec, 0.0, 1.0, 0.0);
    00135
    00136    MAT3_COPY_VEC(norm, vec);
    00137
    00138    if (! is_unit) MAT3_NORMALIZE_VEC(norm, dot);
    00139
    00140    /* See if vector is too close to <0,1,0>.  If so, use <0,0,1> */
    00141    if ((dot = MAT3_DOT_PRODUCT(norm, result_vec)) > SELECT || dot < -SELECT) {
    00142       result_vec[1] = 0.0;
    00143       result_vec[2] = 1.0;
    00144       dot = MAT3_DOT_PRODUCT(norm, result_vec);
    00145    }
    00146
    00147    /* Subtract off non-perpendicular part */
    00148    result_vec[0] -= dot * norm[0];
    00149    result_vec[1] -= dot * norm[1];
    00150    result_vec[2] -= dot * norm[2];
    00151
    00152    /* Make result unit length */
    00153    MAT3_NORMALIZE_VEC(result_vec, dot);
    00154 }

@ 1.2 log @Oops, try again. @ text @d163 1 a163 1