home *** CD-ROM | disk | FTP | other *** search
/ RISC DISC 3 / RISC_DISC_3.iso / resources / etexts / gems / gemsv / ch7_6 / matrix / mat3.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-01-27  |  8.7 KB  |  304 lines

  1. /* Copyright 1991, Brown Computer Graphics Group.  All Rights Reserved. */
  2.  
  3. #include "mat3.h"
  4.  
  5. /* -------------------------------------------------------------------------
  6.  * DESCR   :    Takes a 3-vector of scale values, and creates a matrix with
  7.  *         these as its diagonal entries and zeroes off the diagonal,
  8.  *         i.e., a scale matrix with scale factors given by the entries
  9.  *         of the given vector.
  10.  *
  11.  * RETURNS :    void
  12.  * ------------------------------------------------------------------------- */
  13. void
  14. MAT3scale(
  15.    MAT3mat result_mat,        /* A diagonal matrix (a scaling matrix) */
  16.    MAT3vec scale         /* The entries for the diagonal */
  17.    )
  18. {
  19.    MAT3identity(result_mat);
  20.  
  21.    result_mat[0][0] = scale[0];
  22.    result_mat[1][1] = scale[1];
  23.    result_mat[2][2] = scale[2];
  24. }
  25.  
  26. /* -------------------------------------------------------------------------
  27.  * DESCR :    Sets the matrix @result_mat@ to be a translation matrix that
  28.  *         will translate by the vector @trans@.
  29.  *
  30.  * RETURNS :    void
  31.  * ------------------------------------------------------------------------- */
  32. void
  33. MAT3translate(
  34.    MAT3mat result_mat,    /* Translation matrix [output] */
  35.    MAT3vec trans    /* Translation vector [input]  */
  36.    )
  37. {
  38.    MAT3identity(result_mat);
  39.  
  40.    result_mat[0][3] = trans[0];
  41.    result_mat[1][3] = trans[1];
  42.    result_mat[2][3] = trans[2];
  43. }
  44.  
  45. /* -------------------------------------------------------------------------
  46.  * DESCR :        Sets @result_mat@ to be a shear matrix that does the
  47.  *         following:Given a plane normal (@normal@) and a shear vector
  48.  *         (@shear@), the transformation leaves points in the plane
  49.  *         (through the origin, perp to the normal) fixed, while moving
  50.  *         points at a distance d from the plane by d times the shear
  51.  *         vector.  (The shear vector is first made to be perpendicular
  52.  *         to the normal.) The normal vector is assumed to be unit
  53.  *         length, and results are incorrect if it is not.
  54.  *
  55.  * RETURNS :    void
  56.  * ------------------------------------------------------------------------- */
  57. void
  58. MAT3shear(
  59.    register MAT3mat result_mat,    /* A shear matrix generated by this routine  */
  60.    register MAT3vec normal,    /* The normal to the shear plane */
  61.    register MAT3vec shear     /* The shearing vector [perp to normal] */
  62.    )
  63. {
  64.    register int     j;
  65.    register double    *shear_used = shear;
  66.    double        dot;
  67.    MAT3vec        shear2;
  68.  
  69.    MAT3identity(result_mat);
  70.  
  71.    /* Make sure shear vector is perpendicular to the normal */
  72.    dot = MAT3_DOT_PRODUCT(normal, shear);
  73.  
  74.    if (! MAT3_IS_ZERO(dot)) {
  75.       shear_used = shear2;
  76.       MAT3_SCALE_VEC(shear_used, normal, dot);
  77.       MAT3_SUB_VEC(shear_used, shear, shear_used);
  78.    }
  79.  
  80.    /* Set columns to coordinate axes transformed by shear */
  81.    for (j = 0; j < 3; j++) {
  82.       result_mat[j][0] += normal[0] * shear_used[j];
  83.       result_mat[j][1] += normal[1] * shear_used[j];
  84.       result_mat[j][2] += normal[2] * shear_used[j];
  85.    }
  86. }
  87.  
  88. /* -------------------------------------------------------------------------
  89.  * DESCR   :    Sets @m@ to be the identity matrix.
  90.  *
  91.  * RETURNS :    void
  92.  * ------------------------------------------------------------------------- */
  93. void
  94. MAT3identity(
  95.    MAT3mat m         /* Matrix to be set to identity */
  96.    )
  97. {
  98.     double *mat = (double *)m;
  99.  
  100.     *mat++ = 1.0;
  101.     *mat++ = 0.0;
  102.     *mat++ = 0.0;
  103.     *mat++ = 0.0;
  104.  
  105.     *mat++ = 0.0;
  106.     *mat++ = 1.0;
  107.     *mat++ = 0.0;
  108.     *mat++ = 0.0;
  109.  
  110.     *mat++ = 0.0;
  111.     *mat++ = 0.0;
  112.     *mat++ = 1.0;
  113.     *mat++ = 0.0;
  114.  
  115.     *mat++ = 0.0;
  116.     *mat++ = 0.0;
  117.     *mat++ = 0.0;
  118.     *mat   = 1.0;
  119. }
  120.  
  121. /* -------------------------------------------------------------------------
  122.  * DESCR   :    Sets @m@ to be the zero matrix.
  123.  *
  124.  * RETURNS :    void
  125.  * ------------------------------------------------------------------------- */
  126. void
  127. MAT3zero(
  128.    MAT3mat m         /* Matrix to be set to zero */
  129.    )
  130. {
  131.     double *mat = (double *)m;
  132.  
  133.     *mat++ = 0.0;
  134.     *mat++ = 0.0;
  135.     *mat++ = 0.0;
  136.     *mat++ = 0.0;
  137.  
  138.     *mat++ = 0.0;
  139.     *mat++ = 0.0;
  140.     *mat++ = 0.0;
  141.     *mat++ = 0.0;
  142.  
  143.     *mat++ = 0.0;
  144.     *mat++ = 0.0;
  145.     *mat++ = 0.0;
  146.     *mat++ = 0.0;
  147.  
  148.     *mat++ = 0.0;
  149.     *mat++ = 0.0;
  150.     *mat++ = 0.0;
  151.     *mat   = 0.0;
  152. }
  153.  
  154. /* -------------------------------------------------------------------------
  155.  * DESCR   :    Copy the matrix @f@ into the matrix @t@.
  156.  *
  157.  * RETURNS :    void
  158.  * ------------------------------------------------------------------------- */
  159. void
  160. MAT3copy(
  161.    MAT3mat t,    /* Target matrix [output] */
  162.    MAT3mat f    /* Source matrix [input] */
  163. )
  164. {
  165.     double *to = (double *)t;
  166.     double *from = (double *)f;
  167.     
  168.     *to++ = *from++;
  169.     *to++ = *from++;
  170.     *to++ = *from++;
  171.     *to++ = *from++;
  172.  
  173.     *to++ = *from++;
  174.     *to++ = *from++;
  175.     *to++ = *from++;
  176.     *to++ = *from++;
  177.  
  178.     *to++ = *from++;
  179.     *to++ = *from++;
  180.     *to++ = *from++;
  181.     *to++ = *from++;
  182.  
  183.     *to++ = *from++;
  184.     *to++ = *from++;
  185.     *to++ = *from++;
  186.     *to   = *from;
  187. }
  188.  
  189. /* -------------------------------------------------------------------------
  190.  * DESCR   :    Computes the matrix product @mat1@ * @mat2@ and places the
  191.  *        result in @result_mat@. The matrices being multiplied may be the
  192.  *        same as the result, i.e., a call of the form MAT3mult(a,a,b) is
  193.  *        safe.
  194.  *
  195.  * RETURNS :    void
  196.  * ------------------------------------------------------------------------- */
  197. void
  198. MAT3mult(
  199.    MAT3mat      result_mat,    /* The computed product of the next two args  */
  200.    MAT3mat mat1,    /* The first factor of the product */
  201.    MAT3mat mat2     /* The second factor of the product */
  202.    )
  203. {
  204.    int i, j;
  205.    MAT3mat    tmp_mat;
  206.    double    *tmp;
  207.  
  208.    if (((tmp = (double*)result_mat) == (double*)mat1) || 
  209.        (tmp == (double*)mat2))
  210.       tmp = (double*)tmp_mat;
  211.    
  212.    for (i = 0; i < 4; i++) for (j = 0; j < 4; j++)
  213.       *(tmp++) = (mat1[i][0] * mat2[0][j] +
  214.           mat1[i][1] * mat2[1][j] +
  215.           mat1[i][2] * mat2[2][j] +
  216.           mat1[i][3] * mat2[3][j]);
  217.  
  218.    if (((double*)result_mat == (double*)mat1) || 
  219.        ((double*)result_mat == (double*)mat2))
  220.       MAT3copy(result_mat, tmp_mat);
  221.  
  222.    return;
  223. }
  224.  
  225. /* -------------------------------------------------------------------------
  226.  * DESCR :    Multiplies the vector of size 4 (@vec@) by the matrix @mat@,
  227.  *         placing the result in @result_vec@. (The multiplication is of
  228.  *         the form matrix times vector, and the vector should be
  229.  *         considered to be a column vector). The fourth element of the
  230.  *         vector is the homogeneous coordinate, which may or may not be
  231.  *         1.  If the @homogenize@ parameter is TRUE, then the result
  232.  *         vector will be normalized so that the homogeneous coordinate
  233.  *         is 1. The two vectors involved may be the same. This returns
  234.  *         zero if the vector was to be homogenized, but couldn't be.
  235.  *
  236.  *
  237.  * RETURNS :    FALSE if the result vector was to be homogenized, but had
  238.  *         homogeneous coordinate zero. In this case, the results should
  239.  *         be regarded as garbage. Otherwise the routine returns TRUE.
  240.  * ------------------------------------------------------------------------- */
  241. int
  242. MAT3mult_hvec(
  243.    MAT3hvec          result_vec, /* The product of vec with mat (output) */
  244.    register MAT3hvec vec,     /* The vector to multiply (input) */
  245.    register MAT3mat  mat,     /* The matrix to multiply (input) */
  246.    int               homogenize     /* Should we homogenize the result?  */
  247.    )
  248. {
  249.    MAT3hvec             tempvec;
  250.    double        norm_fac;
  251.    register double    *temp = tempvec;
  252.    register int     ret = 1;
  253.  
  254.    temp[0] =    vec[0] * mat[0][0] + vec[1] * mat[0][1] +
  255.         vec[2] * mat[0][2] + vec[3] * mat[0][3];
  256.    temp[1] =    vec[0] * mat[1][0] + vec[1] * mat[1][1] +
  257.         vec[2] * mat[1][2] + vec[3] * mat[1][3];
  258.    temp[2] =    vec[0] * mat[2][0] + vec[1] * mat[2][1] +
  259.         vec[2] * mat[2][2] + vec[3] * mat[2][3];
  260.    temp[3] =    vec[0] * mat[3][0] + vec[1] * mat[3][1] +
  261.         vec[2] * mat[3][2] + vec[3] * mat[3][3];
  262.  
  263.    /* Homogenize if asked for, possible, and necessary */
  264.    if (homogenize) {
  265.       if (MAT3_IS_ZERO(temp[3])) {
  266. /*     SEVERES("Can't homogenize vec. in MAT3mult_hvec: last coord is 0"); */
  267.      ret = 0;
  268.       }
  269.       else {
  270.      norm_fac = 1.0 / temp[3];
  271.      MAT3_SCALE_VEC(result_vec, temp, norm_fac);
  272.      result_vec[3] = 1.0;
  273.       }
  274.    }
  275.    else MAT3_COPY_HVEC(result_vec, temp);
  276.  
  277.    return(ret);
  278. }
  279.  
  280. /* -------------------------------------------------------------------------
  281.  * DESCR   :    Set @result_vec@ to be the cross product of @vec1@ and
  282.  *         @vec2@, in that order.
  283.  *
  284.  * RETURNS :    void
  285.  * ------------------------------------------------------------------------- */
  286. void
  287. MAT3cross_product(
  288.    MAT3vec      result_vec,    /* The computed cross-product (output) */
  289.    register MAT3vec vec1,    /* The first factor (input) */
  290.    register MAT3vec vec2     /* The second factor (input) */
  291.    )
  292. {
  293.    MAT3vec        tempvec;
  294.    register double    *temp = tempvec;
  295.  
  296.    temp[0] = vec1[1] * vec2[2] - vec1[2] * vec2[1];
  297.    temp[1] = vec1[2] * vec2[0] - vec1[0] * vec2[2];
  298.    temp[2] = vec1[0] * vec2[1] - vec1[1] * vec2[0];
  299.  
  300.    MAT3_COPY_VEC(result_vec, temp);
  301. }
  302.  
  303.  
  304.