Team Fortress 2 Source Code as on 22/4/2020
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

113 lines
2.2 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //
  7. //=============================================================================//
  8. #include "tier0/platform.h"
  9. #include "linear_solver.h"
  10. #include <stdio.h>
  11. #include <string.h>
  12. #include <math.h>
  13. // BUGBUG: Remove/tune this number somehow!!!
  14. #define DET_EPSILON 1e-6f
  15. // assumes square matrix!
  16. // ONLY SUPPORTS 2x2, 3x3, and 4x4
  17. float Det( float *matrix, int rows )
  18. {
  19. if ( rows == 2 )
  20. {
  21. return matrix[0]*matrix[3] - matrix[1]*matrix[2];
  22. }
  23. if ( rows == 3 )
  24. {
  25. return matrix[0]*matrix[4]*matrix[8] - matrix[0]*matrix[7]*matrix[5] - matrix[1]*matrix[3]*matrix[8] +
  26. matrix[1]*matrix[5]*matrix[6] + matrix[2]*matrix[3]*matrix[7] - matrix[2]*matrix[4]*matrix[6];
  27. }
  28. // ERROR no more than 4x4
  29. if ( rows != 4 )
  30. return 0;
  31. // UNDONE: Generalize this to NxN
  32. float tmp[9];
  33. float det = 0.f;
  34. // do 4 3x3 dets
  35. for ( int i = 0; i < 4; i++ )
  36. {
  37. // develop on row 0
  38. int out = 0;
  39. for ( int j = 1; j < 4; j++ )
  40. {
  41. // iterate each column and
  42. for ( int k = 0; k < 4; k++ )
  43. {
  44. if ( k == i )
  45. continue;
  46. tmp[out] = matrix[(j*rows)+k];
  47. out++;
  48. }
  49. }
  50. if ( i & 1 )
  51. {
  52. det -= matrix[i]*Det(tmp,3);
  53. }
  54. else
  55. {
  56. det += matrix[i]*Det(tmp,3);
  57. }
  58. }
  59. return det;
  60. }
  61. float *SolveCramer( const float *matrix, int rows, int columns )
  62. {
  63. // max 4 equations, 4 unknowns (until determinant routine is more general)
  64. float tmpMain[16*16], tmpSub[16*16];
  65. static float solution[16];
  66. int i, j;
  67. if ( rows > 4 || columns > 5 )
  68. {
  69. return NULL;
  70. }
  71. int outCol = columns - 1;
  72. // copy out the square matrix
  73. for ( i = 0; i < rows; i++ )
  74. {
  75. memcpy( tmpMain + (i*outCol), matrix + i*columns, sizeof(float)*outCol );
  76. }
  77. float detMain = Det( tmpMain, rows );
  78. // probably degenerate!
  79. if ( fabs(detMain) < DET_EPSILON )
  80. {
  81. return NULL;
  82. }
  83. for ( i = 0; i < rows; i++ )
  84. {
  85. // copy the square matrix
  86. memcpy( tmpSub, tmpMain, sizeof(float)*rows*rows );
  87. // copy the column of constants over the row
  88. for ( j = 0; j < rows; j++ )
  89. {
  90. tmpSub[i+j*outCol] = matrix[j*columns+columns-1];
  91. }
  92. float det = Det( tmpSub, rows );
  93. solution[i] = det / detMain;
  94. }
  95. return solution;
  96. }