Advertisement
Guest User

Untitled

a guest
Jun 27th, 2017
76
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.44 KB | None | 0 0
  1. #ifndef _MAT2_H
  2. #define _MAT2_H
  3.  
  4. // This attempts to follow the GLSL data type standards
  5. // Start with floats only then put in templates later
  6.  
  7. #include <cmath>
  8. #include <iostream>
  9. #include <limits>
  10. #include "Vec2.h"
  11.  
  12. // Changed precision from 10e-7 to 10e-6 since it would be too small otherwise
  13. const float Eps = 10 * numeric_limits<float>::epsilon();
  14.  
  15. class mat2
  16. {
  17. public:
  18.     /* Constructors and Deconstructors */
  19.     // No arguments gives an Identity Matrix
  20.     mat2() {
  21.         Identity(1.0f);
  22.     }
  23.     mat2(const float c) {
  24.         Identity(c);
  25.     }
  26.  
  27.     mat2(const float c0, const float c1,
  28.          const float c2, const float c3) {
  29.              m[0] = c0;
  30.              m[1] = c1;
  31.              m[2] = c2;
  32.              m[3] = c3;
  33.     }
  34.     mat2(const mat2 &n) {
  35.         for(int i = 0; i < mat2lim; ++i) {
  36.             m[i] = n.m[i];
  37.         }
  38.     }
  39.     mat2(const float c[]) {
  40.         for(int i = 0; i < mat2lim; ++i) {
  41.             m[i] = c[i];
  42.         }
  43.     }
  44.     ~mat2() {}
  45.  
  46.     /* Array operator */
  47.     float &operator[] (int i);
  48.     const float &operator[] (int i) const;
  49.  
  50.     float operator() (unsigned int i, unsigned int j) const;
  51.     float &operator() (unsigned int i, unsigned int j);
  52.  
  53.     /* Reset floats in Matrix to true zero or one */
  54.     mat2 Zero(mat2 &n);
  55.  
  56.     /* Arithmetic operators */
  57.     mat2 &operator=(const mat2 &n);
  58.     mat2 operator+=(const mat2 &n);
  59.     mat2 operator-=(const mat2 &n);
  60.     mat2 operator*=(const float &c);
  61.     mat2 operator*(const mat2 &n);
  62.     mat2 operator*=(const mat2 &n);
  63.  
  64.     /* Equivalence operators */
  65.     bool operator==(const mat2 &n);
  66.     bool operator!=(const mat2 &n);
  67.  
  68.     /* Other mathematical functions */
  69.     float Determinant() const;
  70.     // Prefer to call these as mat2 A.Transpose() rather than A.Transpose(A)
  71.     mat2 Transpose() const;
  72.     mat2 Invert() const;
  73.  
  74.     /* Output functions */
  75.  
  76.     void Report();
  77.  
  78. private:
  79.     // This is arranged in rows format
  80.     // Each row contains one 2D Vector
  81.     enum {
  82.         mat2lim = 4, row2lim = 2, col2lim = 2
  83.     };
  84.     float m[mat2lim];
  85.     void Identity(const float c) {
  86.         m[0] = c; m[1] = 0;
  87.         m[2] = 0; m[3] = c;
  88.     }
  89. };
  90.  
  91. inline float &mat2::operator[] (int i) {
  92.     return m[i];
  93. }
  94.  
  95. inline const float &mat2::operator[] (int i) const {
  96.     return m[i];
  97. }
  98.  
  99. /* Parenthesis operator */
  100. inline float mat2::operator() (unsigned int i, unsigned int j) const {
  101.     return m[(i * row2lim) + j];
  102. }
  103.  
  104. inline float &mat2::operator() (unsigned int i, unsigned int j) {
  105.     // Row based matrix index
  106.     return m[(i * row2lim) + j];
  107. }
  108.  
  109. /* Ones or Zeros */
  110. inline mat2 mat2::Zero(mat2 &n) {
  111.     for(int i = 0; i < mat2lim; ++i) {
  112.         if((n[i] <= Eps) && (n[i] >= -Eps))
  113.             n[i] = 0.0f;
  114.     }
  115.     return (n);
  116. }
  117.  
  118. /* Arithmetic operators */
  119. inline mat2 &mat2::operator=(const mat2 &n) {
  120.     for(int i = 0; i < mat2lim; ++i) {
  121.         m[i] = n[i];
  122.     }
  123.     return (*this);
  124. }
  125.  
  126. inline mat2 mat2::operator+=(const mat2 &n) {
  127.     return Zero(mat2(m[0] += n[0], m[1] += n[0], m[2] += n[2], m[3] += n[3]));
  128. }
  129.  
  130. inline mat2 mat2::operator-=(const mat2 &n) {
  131.     return Zero(mat2(m[0] -= n[0], m[1] -= n[1], m[2] -= n[2], m[3] -= n[3]));
  132. }
  133.  
  134. /* Non-member overloaded operators */
  135. inline mat2 operator+(const mat2 &a, const mat2 &b) {
  136.     return mat2(a[0] + b[0], a[1] + b[1], a[2] + b[2], a[3] + b[3]);
  137. }
  138.  
  139. inline mat2 operator-(const mat2 &a, const mat2 &b) {
  140.     return mat2(a[0] - b[0], a[1] - b[1], a[2] - b[2], a[3] - b[3]);
  141. }
  142.  
  143. inline mat2 operator*(const mat2 &b, const float &c) {
  144.     return mat2(b[0] * c, b[1] * c, b[2] * c, b[3] * c);
  145. }
  146.  
  147. inline mat2 mat2::operator*=(const float &c) {
  148.     return Zero(mat2(m[0] *= c, m[1] *= c, m[2] *= c, m[3] *= c));
  149. }
  150.  
  151. inline mat2 mat2::operator*(const mat2 &n) {
  152.     mat2 r;
  153.    
  154.     r(0, 0) = (*this)(0, 0) * n(0, 0) + (*this)(0, 1) * n(1, 0); // r[0][0]
  155.     r(0, 1) = (*this)(0, 0) * n(0, 1) + (*this)(0, 1) * n(1, 1); // r[0][1]
  156.     r(1, 0) = (*this)(1, 0) * n(0, 0) + (*this)(1, 1) * n(1, 0); // r[1][0]
  157.     r(1, 1) = (*this)(1, 0) * n(0, 1) + (*this)(1, 1) * n(1, 1); // r[1][1]
  158.  
  159.     return Zero(r);
  160. }
  161.  
  162. inline mat2 mat2::operator*=(const mat2 &n) {
  163.     *this = *this * n;
  164.     return Zero(*this);
  165. }
  166.  
  167. /* Equivelence operators */
  168.  
  169. inline bool mat2::operator==(const mat2 &n) {
  170.     for(int i = 0; i < mat2lim; ++i)
  171.     {
  172.         if(m[i] >= fabs(n[i] + Eps) && m[i] <= fabs(n[i] - Eps)) {
  173.             ; // Keep checking for next index
  174.         }
  175.         else
  176.             return false; // Break if condition not met
  177.     }
  178.     return true;
  179. }
  180.  
  181. inline bool mat2::operator!=(const mat2 &n) {
  182.     for(int i = 0; i < mat2lim; ++i)
  183.     {
  184.         if(m[i] >= fabs(n[i] + Eps) && m[i] <= fabs(n[i] - Eps)) {
  185.             ; // Keep checking for next index
  186.         }
  187.         else
  188.             return true; // Break if condition not met
  189.     }
  190.     return false;
  191. }
  192.  
  193. /* The other mathematical functions */
  194. inline float mat2::Determinant() const {
  195.     return((*this)(0, 0) * (*this)(1, 1) - (*this)(0, 1) * (*this)(1, 0));
  196. }
  197.  
  198. inline mat2 mat2::Transpose() const {
  199.     mat2 r;
  200.    
  201.     for(int i = 0; i < mat2lim; ++i) {
  202.         for(int j = 0; j < mat2lim; ++j) {
  203.             r(i, j) = (*this)(i, j);
  204.         }
  205.     }
  206.     return r;
  207. }
  208.  
  209. inline mat2 mat2::Invert() const {
  210.     mat2 r;
  211.     float Det = (*this).Determinant();
  212.  
  213.     if(fabs(Det) > Eps) {
  214.         // Swap the diagonal
  215.         r(0, 0) = (*this)(1, 1);
  216.         r(1, 1) = (*this)(0, 0);
  217.         // Negate the rest
  218.         r(0, 1) = -(*this)(0, 1);
  219.         r(1, 0) = -(*this)(1, 0);
  220.         // Multiply against 1 over Determinant
  221.         r *= (1.0f / Det);
  222.         return (r);
  223.     }
  224.     else
  225.         cout << "Inverse does not exist" << endl;
  226.         return (*this);
  227. }
  228.  
  229. /* Output functions */
  230.  
  231. void mat2::Report() {
  232.     cout << "[ " << (*this)(0, 0) << " " << (*this)(0, 1) << " ]" << endl;
  233.     cout << "[ " << (*this)(1, 0) << " " << (*this)(1, 1) << " ]" << endl << endl;
  234. }
  235.  
  236. #endif /* _MAT2_H */
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement