home *** CD-ROM | disk | FTP | other *** search
/ The Fred Fish Collection 1.5 / ffcollection-1-5-1992-11.iso / ff_disks / 300-399 / ff397.lzh / DKBTrace / DKBSource.LZH / matrices.c < prev    next >
C/C++ Source or Header  |  1990-08-26  |  10KB  |  325 lines

  1. /*****************************************************************************
  2. *
  3. *                                   matrices.c
  4. *
  5. *   from DKBTrace (c) 1990  David Buck
  6. *
  7. *  This module contains code to manipulate 4x4 matrices.
  8. *
  9. * This software is freely distributable. The source and/or object code may be
  10. * copied or uploaded to communications services so long as this notice remains
  11. * at the top of each file.  If any changes are made to the program, you must
  12. * clearly indicate in the documentation and in the programs startup message
  13. * who it was who made the changes. The documentation should also describe what
  14. * those changes were. This software may not be included in whole or in
  15. * part into any commercial package without the express written consent of the
  16. * author.  It may, however, be included in other public domain or freely
  17. * distributed software so long as the proper credit for the software is given.
  18. *
  19. * This software is provided as is without any guarantees or warranty. Although
  20. * the author has attempted to find and correct any bugs in the software, he
  21. * is not responsible for any damage caused by the use of the software.  The
  22. * author is under no obligation to provide service, corrections, or upgrades
  23. * to this package.
  24. *
  25. * Despite all the legal stuff above, if you do find bugs, I would like to hear
  26. * about them.  Also, if you have any comments or questions, you may contact me
  27. * at the following address:
  28. *
  29. *     David Buck
  30. *     22C Sonnet Cres.
  31. *     Nepean Ontario
  32. *     Canada, K2H 8W7
  33. *
  34. *  I can also be reached on the following bulleton boards:
  35. *
  36. *     ATX              (613) 526-4141
  37. *     OMX              (613) 731-3419
  38. *     Mystic           (613) 731-0088 or (613) 731-6698
  39. *
  40. *  Fidonet:   1:163/109.9
  41. *  Internet:  David_Buck@Carleton.CA
  42. *
  43. *  IBM Port by Aaron A. Collins. Aaron may be reached on the following BBS'es:
  44. *
  45. *     Lattice BBS                      (708) 916-1200
  46. *     The Information Exchange BBS     (708) 945-5575
  47. *     Stillwaters BBS                  (708) 403-2826
  48. *
  49. *****************************************************************************/
  50.  
  51.  
  52. #include "frame.h"
  53. #include "vector.h"
  54. #include "dkbproto.h"
  55.  
  56. #ifndef PI
  57. #define PI 3.141592653689793
  58. #endif
  59.  
  60. void MZero (result)
  61.    MATRIX *result;
  62.    {
  63. /* Initialize the matrix to the following values:
  64.    0.0   0.0   0.0   0.0
  65.    0.0   0.0   0.0   0.0
  66.    0.0   0.0   0.0   0.0
  67.    0.0   0.0   0.0   0.0
  68. */
  69.    register int i, j;
  70.  
  71.    for (i = 0 ; i < 4 ; i++)
  72.       for (j = 0 ; j < 4 ; j++)
  73.          (*result)[i][j] = 0.0;
  74.    }
  75.  
  76. void MIdentity (result)
  77.    MATRIX *result;
  78.    {
  79. /* Initialize the matrix to the following values:
  80.    1.0   0.0   0.0   0.0
  81.    0.0   1.0   0.0   0.0
  82.    0.0   0.0   1.0   0.0
  83.    0.0   0.0   0.0   1.0
  84. */
  85.    register int i, j;
  86.  
  87.    for (i = 0 ; i < 4 ; i++)
  88.      for (j = 0 ; j < 4 ; j++)
  89.         if (i == j)
  90.            (*result)[i][j] = 1.0;
  91.         else
  92.            (*result)[i][j] = 0.0;
  93.    }
  94.  
  95. void MTimes (result, matrix1, matrix2)
  96.    MATRIX *result, *matrix1, *matrix2;
  97.    {
  98.    register int i, j, k;
  99.    MATRIX temp_matrix;
  100.  
  101.    for (i = 0 ; i < 4 ; i++)
  102.       for (j = 0 ; j < 4 ; j++) {
  103.          temp_matrix[i][j] = 0.0;
  104.          for (k = 0 ; k < 4 ; k++)
  105.             temp_matrix[i][j] += (*matrix1)[i][k] * (*matrix2)[k][j];
  106.          }
  107.  
  108.    for (i = 0 ; i < 4 ; i++)
  109.       for (j = 0 ; j < 4 ; j++)
  110.          (*result)[i][j] = temp_matrix[i][j];
  111.    }
  112.  
  113.  
  114. void MAdd (result, matrix1, matrix2)
  115.    MATRIX *result, *matrix1, *matrix2;
  116.    {
  117.    register int i, j;
  118.  
  119.    for (i = 0 ; i < 4 ; i++)
  120.       for (j = 0 ; j < 4 ; j++)
  121.          (*result)[i][j] = (*matrix1)[i][j] + (*matrix2)[i][j];
  122.    }
  123.  
  124. void MSub (result, matrix1, matrix2)
  125.    MATRIX *result, *matrix1, *matrix2;
  126.    {
  127.    register int i, j;
  128.  
  129.    for (i = 0 ; i < 4 ; i++)
  130.       for (j = 0 ; j < 4 ; j++)
  131.          (*result)[i][j] = (*matrix1)[i][j] - (*matrix2)[i][j];
  132.    }
  133.  
  134. void MScale (result, matrix1, amount)
  135. MATRIX *result, *matrix1;
  136. DBL amount;
  137. {
  138.    register int i, j;
  139.  
  140.    for (i = 0 ; i < 4 ; i++)
  141.       for (j = 0 ; j < 4 ; j++)
  142.      if (amount == 1.0)
  143.         (*result)[i][j] = (*matrix1)[i][j]; /* just copy */
  144.      else
  145.             (*result)[i][j] = (*matrix1)[i][j] * amount;
  146.    return;
  147. }
  148.  
  149. void MTranspose (result, matrix1)
  150.    MATRIX *result, *matrix1;
  151.    {
  152.    register int i, j;
  153.    MATRIX temp_matrix;
  154.  
  155.    for (i = 0 ; i < 4 ; i++)
  156.       for (j = 0 ; j < 4 ; j++)
  157.          temp_matrix[i][j] = (*matrix1)[j][i];
  158.  
  159.    for (i = 0 ; i < 4 ; i++)
  160.       for (j = 0 ; j < 4 ; j++)
  161.          (*result)[i][j] = temp_matrix[i][j];
  162.    }
  163.  
  164.  
  165. void MTransformVector (result, vector, transformation)
  166.    VECTOR *result, *vector;
  167.    TRANSFORMATION *transformation;
  168.    {
  169.    register int i;
  170.    DBL answer_array[4];
  171.    MATRIX *matrix;
  172.  
  173.    matrix = &transformation -> matrix;
  174.  
  175.    for (i = 0 ; i < 4 ; i++)
  176.       answer_array[i] = vector -> x * (*matrix)[0][i]
  177.                       + vector -> y * (*matrix)[1][i]
  178.                       + vector -> z * (*matrix)[2][i]
  179.                       + (*matrix)[3][i];
  180.  
  181.    result -> x  = answer_array[0];
  182.    result -> y  = answer_array[1];
  183.    result -> z  = answer_array[2];
  184.    }
  185.  
  186. void MInverseTransformVector (result, vector, transformation)
  187.    VECTOR *result, *vector;
  188.    TRANSFORMATION *transformation;
  189.    {
  190.    register int i;
  191.    DBL answer_array[4];
  192.    MATRIX *matrix;
  193.  
  194.    matrix = &transformation -> inverse;
  195.  
  196.    for (i = 0 ; i < 4 ; i++)
  197.       answer_array[i] = vector -> x * (*matrix)[0][i]
  198.                       + vector -> y * (*matrix)[1][i]
  199.                       + vector -> z * (*matrix)[2][i]
  200.                       + (*matrix)[3][i];
  201.  
  202.    result -> x  = answer_array[0];
  203.    result -> y  = answer_array[1];
  204.    result -> z  = answer_array[2];
  205.    }
  206.  
  207. void Get_Scaling_Transformation (result, vector)
  208.    TRANSFORMATION *result;
  209.    VECTOR *vector;
  210.    {
  211.    MIdentity (&result -> matrix);
  212.    (result -> matrix)[0][0] = vector -> x;
  213.    (result -> matrix)[1][1] = vector -> y;
  214.    (result -> matrix)[2][2] = vector -> z;
  215.  
  216.    MIdentity (&result -> inverse);
  217.    (result -> inverse)[0][0] = 1.0 / vector -> x;
  218.    (result -> inverse)[1][1]= 1.0 / vector -> y;
  219.    (result -> inverse)[2][2] = 1.0 / vector -> z;
  220.    }
  221.  
  222. void Get_Inversion_Transformation (result)
  223.    TRANSFORMATION *result;
  224.    {
  225.    MIdentity (&result -> matrix);
  226.    (result -> matrix)[0][0] = -1.0;
  227.    (result -> matrix)[1][1] = -1.0;
  228.    (result -> matrix)[2][2] = -1.0;
  229.    (result -> matrix)[3][3] = -1.0;
  230.  
  231.  
  232.    (result -> inverse)[0][0] = -1.0;
  233.    (result -> inverse)[1][1] = -1.0;
  234.    (result -> inverse)[2][2] = -1.0;
  235.    (result -> inverse)[3][3] = -1.0;
  236.    }
  237.  
  238. void Get_Translation_Transformation (transformation, vector)
  239.    TRANSFORMATION *transformation;
  240.    VECTOR *vector;
  241.    {
  242.    MIdentity (&transformation -> matrix);
  243.    (transformation -> matrix)[3][0] = vector -> x;
  244.    (transformation -> matrix)[3][1] = vector -> y;
  245.    (transformation -> matrix)[3][2] = vector -> z;
  246.  
  247.    MIdentity (&transformation -> inverse);
  248.    (transformation -> inverse)[3][0] = 0.0 - vector -> x;
  249.    (transformation -> inverse)[3][1] = 0.0 - vector -> y;
  250.    (transformation -> inverse)[3][2] = 0.0 - vector -> z;
  251.    }
  252.  
  253. void Get_Rotation_Transformation (transformation, vector)
  254.    TRANSFORMATION *transformation;
  255.    VECTOR *vector;
  256.    {
  257.    MATRIX Matrix;
  258.    VECTOR Radian_Vector;
  259.    register DBL cosx, cosy, cosz, sinx, siny, sinz;
  260.  
  261.    VScale (Radian_Vector, *vector, PI/180.0);
  262.    MIdentity (&transformation -> matrix);
  263.    cosx = cos (Radian_Vector.x);
  264.    sinx = sin (Radian_Vector.x);
  265.    cosy = cos (Radian_Vector.y);
  266.    siny = sin (Radian_Vector.y);
  267.    cosz = cos (Radian_Vector.z);
  268.    sinz = sin (Radian_Vector.z);
  269.  
  270.    (transformation -> matrix) [1][1] = cosx;
  271.    (transformation -> matrix) [2][2] = cosx;
  272.    (transformation -> matrix) [1][2] = 0.0 - sinx;
  273.    (transformation -> matrix) [2][1] = sinx;
  274.    MTranspose (&transformation -> inverse, &transformation -> matrix);
  275.  
  276.    MIdentity (&Matrix);
  277.    Matrix [0][0] = cosy;
  278.    Matrix [2][2] = cosy;
  279.    Matrix [0][2] = siny;
  280.    Matrix [2][0] = 0.0 - siny;
  281.    MTimes (&transformation -> matrix, &transformation -> matrix, &Matrix);
  282.    MTranspose (&Matrix, &Matrix);
  283.    MTimes (&transformation -> inverse, &Matrix, &transformation -> inverse);
  284.  
  285.    MIdentity (&Matrix);
  286.    Matrix [0][0] = cosz;
  287.    Matrix [1][1] = cosz;
  288.    Matrix [0][1] = 0.0 - sinz;
  289.    Matrix [1][0] = sinz;
  290.    MTimes (&transformation -> matrix, &transformation -> matrix, &Matrix);
  291.    MTranspose (&Matrix, &Matrix);
  292.    MTimes (&transformation -> inverse, &Matrix, &transformation -> inverse);
  293.    }
  294.  
  295. void Get_Look_At_Transformation (result, Look_At, Up, Right)
  296.    TRANSFORMATION *result;
  297.    VECTOR *Look_At, *Up, *Right;
  298.    {
  299.    MIdentity (&result -> inverse);
  300.    (result -> matrix)[0][0] = Right->x;
  301.    (result -> matrix)[0][1] = Right->y;
  302.    (result -> matrix)[0][2] = Right->z;
  303.    (result -> matrix)[1][0] = Up->x;
  304.    (result -> matrix)[1][1] = Up->y;
  305.    (result -> matrix)[1][2] = Up->z;
  306.    (result -> matrix)[2][0] = Look_At->x;
  307.    (result -> matrix)[2][1] = Look_At->y;
  308.    (result -> matrix)[2][2] = Look_At->z;
  309.  
  310.    MIdentity (&result -> matrix);
  311.    MTranspose (&result -> matrix, &result -> inverse);   
  312.    }
  313.  
  314. void Compose_Transformations (Original_Transformation, New_Transformation)
  315.    TRANSFORMATION *Original_Transformation, *New_Transformation;
  316.    {
  317.    MTimes (&Original_Transformation -> matrix,
  318.            &Original_Transformation -> matrix,
  319.            &New_Transformation -> matrix);
  320.  
  321.    MTimes (&Original_Transformation -> inverse,
  322.            &New_Transformation -> inverse,
  323.            &Original_Transformation -> inverse);
  324.    }
  325.