Advertisement
Guest User

Untitled

a guest
Nov 28th, 2014
158
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 16.49 KB | None | 0 0
  1. #include "fmath.h"
  2.  
  3. /*
  4.  * MATRIX3 BEGIN
  5. */
  6. Matrix3::Matrix3() {
  7.     for (int n=0; n<N; n++)
  8.         for (int m=0; m<N; m++)
  9.             this->operator()(n, m) = 0;
  10. }
  11.  
  12.  
  13. Matrix3::Matrix3(const Matrix3 &another) {
  14.     for (int n=0; n<N; n++)
  15.         for (int m=0; m<N; m++)
  16.             this->operator()(n, m) = another(n, m);
  17. }
  18.  
  19. Matrix3::Matrix3(Matrix4 &mat4) {
  20.     *this = mat4.submatrix();
  21. }
  22.  
  23. Matrix3 Matrix3::identity() {
  24.     Matrix3 mat;
  25.     for (int i=0; i<N; i++)
  26.         mat(i, i) = 1;
  27.  
  28.     return mat;
  29. }
  30.  
  31. const float &Matrix3::operator()(int i, int j) const {
  32.     if ((i <= N) && (j <= N))
  33.         return this->data[i][j];
  34.     else
  35.         throw std::exception();
  36. }
  37.  
  38. Matrix3 Matrix3::operator+(const Matrix3& another) const {
  39.     Matrix3 mat;
  40.  
  41.     for (int n=0; n<N; n++)
  42.         for (int m=0; m<N; m++)
  43.             mat(n, m) = this->operator ()(n, m) + another(n, m);
  44.  
  45.     return mat;
  46. }
  47.  
  48. Matrix3 Matrix3::operator-(const Matrix3& another) const {
  49.     Matrix3 mat;
  50.  
  51.     for (int n=0; n<N; n++)
  52.         for (int m=0; m<N; m++)
  53.             mat(n, m) = this->operator ()(n, m) - another(n, m);
  54.  
  55.     return mat;
  56. }
  57.  
  58. Matrix3 Matrix3::operator*(const Matrix3& another) const {
  59.     Matrix3 mat;
  60.     float current_product;
  61.  
  62.     for (int n=0; n<N; n++)
  63.         for (int m=0; m<N; m++)
  64.         {
  65.             current_product = 0;
  66.             for (int k=0; k<N; k++)
  67.                 current_product += this->operator ()(n, k) * another(k, m);
  68.             mat(n, m) = current_product;
  69.         }
  70.  
  71.     return mat;
  72. }
  73.  
  74. Matrix3 Matrix3::operator*(const float scalar) const {
  75.     Matrix3 mat;
  76.  
  77.     for (int n=0; n<N; n++)
  78.         for (int m=0; m<N; m++)
  79.             mat(n, m) = this->operator ()(n, m) * scalar;
  80.  
  81.     return mat;
  82. }
  83.  
  84. Vector3 Matrix3::operator*(const Vector3& vec) const {
  85.     Vector3 product;
  86.  
  87.     for (int i=0; i<N; i++)
  88.         for (int j=0; j<N; j++)
  89.             product.el(i) += vec.el(j) * this->operator ()(i, j);
  90.  
  91.     return product;
  92. }
  93.  
  94. Matrix3 Matrix3::transposed() const {
  95.     Matrix3 mat;
  96.  
  97.     for (int n=0; n<N; n++)
  98.         for (int m=0; m<N; m++)
  99.             mat(n, m) = this->operator ()(m, n);
  100.  
  101.     return mat;
  102. }
  103.  
  104. void Matrix3::transpose() {
  105.     *this = this->transposed();
  106. }
  107.  
  108. Matrix3 Matrix3::inverse() {
  109.     if (hasInverse)
  110.         return *precomputedInverse;
  111.  
  112.     Matrix3 m(*this);
  113.  
  114.     Matrix3 mat;
  115.     for (unsigned column = 0; column < N; ++column) {
  116.         // Swap row in case our pivot point is not working
  117.         if (m(column, column) == 0) {
  118.             unsigned big = column;
  119.             for (unsigned row = 0; row < N; ++row)
  120.                 if (fabs(m(row, column)) > fabs(m(big, column))) big = row;
  121.             // Print this is a singular matrix, return identity ?
  122.             if (big == column) {}//std::cerr << "Singular matrix" << std::endl;
  123.             // Swap rows
  124.             else for (unsigned j = 0; j < N; ++j) {
  125.                 std::swap(m(column, j), m(big, j));
  126.                 std::swap(mat(column, j), mat(big, j));
  127.             }
  128.         }
  129.         // Set each row in the column to 0
  130.         for (unsigned row = 0; row < N; ++row) {
  131.             if (row != column) {
  132.                 float coeff = m(row, column) / m(column, column);
  133.                 if (coeff != 0) {
  134.                     for (unsigned j = 0; j < N; ++j) {
  135.                         m(row, j) -= coeff * m(column, j);
  136.                         mat(row, j) -= coeff * mat(column, j);
  137.                     }
  138.                     // Set the element to 0 for safety
  139.                     m(row, column) = 0;
  140.                 }
  141.             }
  142.         }
  143.     }
  144.     // Set each element of the diagonal to 1
  145.     for (unsigned row = 0; row < N; ++row) {
  146.         for (unsigned column = 0; column < N; ++column) {
  147.             mat(row, column) /= m(row, row);
  148.         }
  149.     }
  150.     precomputedInverse = new Matrix3(mat);
  151.     hasInverse = true;
  152.     return *precomputedInverse;
  153. }
  154.  
  155. void Matrix3::invert() {
  156.     *this = this->inverse();
  157. }
  158.  
  159. void Matrix3::print() {
  160.     for (int n=0; n<N; n++)
  161.     {
  162.         for (int m=0; m<N; m++)
  163.             std::cout << this->operator ()(n, m) << " ";
  164.         std::cout << std::endl;
  165.     }
  166.     std::cout << std::endl;
  167. }
  168.  
  169. float& Matrix3::operator()(int i, int j) {
  170.     if ((i <= N) && (j <= N))
  171.         return this->data[i][j];
  172.     else
  173.         throw std::exception();
  174. }
  175. /*
  176.  * MATRIX3 END
  177. */
  178.  
  179.  
  180.  
  181. /*
  182.  * MATRIX4 BEGIN
  183. */
  184. Matrix4::Matrix4() {
  185.     for (int n=0; n<N; n++)
  186.         for (int m=0; m<N; m++)
  187.             this->operator()(n, m) = 0;
  188. }
  189.  
  190.  
  191. Matrix4::Matrix4(const Matrix4 &another) {
  192.     for (int n=0; n<N; n++)
  193.         for (int m=0; m<N; m++)
  194.             this->operator()(n, m) = another(n, m);
  195. }
  196.  
  197. Matrix4::Matrix4(const Matrix3 &mat3) {
  198.     *this = Matrix4::identity();
  199.     for (int i=0; i<3; i++)
  200.         for (int j=0; j<3; j++)
  201.             this->operator ()(i, j) = mat3(i, j);
  202. }
  203.  
  204. Matrix4 Matrix4::identity() {
  205.     Matrix4 mat;
  206.     for (int i=0; i<N; i++)
  207.         mat(i, i) = 1;
  208.  
  209.     return mat;
  210. }
  211.  
  212. const float &Matrix4::operator()(int i, int j) const {
  213.     if ((i <= N) && (j <= N))
  214.         return this->data[i][j];
  215.     else
  216.         throw std::exception();
  217. }
  218.  
  219. Matrix4 Matrix4::operator+(const Matrix4 &another) const {
  220.     Matrix4 mat;
  221.  
  222.     for (int n=0; n<N; n++)
  223.         for (int m=0; m<N; m++)
  224.             mat(n, m) = this->operator ()(n, m) + another(n, m);
  225.  
  226.     return mat;
  227. }
  228.  
  229. Matrix4 Matrix4::operator-(const Matrix4 &another) const {
  230.     Matrix4 mat;
  231.  
  232.     for (int n=0; n<N; n++)
  233.         for (int m=0; m<N; m++)
  234.             mat(n, m) = this->operator ()(n, m) - another(n, m);
  235.  
  236.     return mat;
  237. }
  238.  
  239. Matrix4 Matrix4::operator*(const Matrix4 &another) const {
  240.     Matrix4 mat;
  241.     float current_product;
  242.  
  243.     for (int n=0; n<N; n++)
  244.         for (int m=0; m<N; m++)
  245.         {
  246.             current_product = 0;
  247.             for (int k=0; k<N; k++)
  248.                 current_product += this->operator ()(n, k) * another(k, m);
  249.             mat(n, m) = current_product;
  250.         }
  251.  
  252.     return mat;
  253. }
  254.  
  255. Matrix4 Matrix4::operator*(const float scalar) const {
  256.     Matrix4 mat;
  257.  
  258.     for (int n=0; n<N; n++)
  259.         for (int m=0; m<N; m++)
  260.             mat(n, m) = this->operator ()(n, m) * scalar;
  261.  
  262.     return mat;
  263. }
  264.  
  265. Vector4 Matrix4::operator*(const Vector4& vec) const {
  266.     Vector4 product;
  267.  
  268.     for (int i=0; i<N; i++)
  269.         for (int j=0; j<N; j++)
  270.             product.el(i) += vec.el(j) * this->operator ()(i, j);
  271.  
  272.     return product;
  273. }
  274.  
  275. Matrix4 Matrix4::transposed() const {
  276.     Matrix4 mat;
  277.  
  278.     for (int n=0; n<N; n++)
  279.         for (int m=0; m<N; m++)
  280.             mat(n, m) = this->operator ()(m, n);
  281.  
  282.     return mat;
  283. }
  284.  
  285. void Matrix4::transpose() {
  286.     *this = this->transposed();
  287. }
  288.  
  289. Matrix4 Matrix4::inverse() {
  290.     if (hasInverse)
  291.         return *precomputedInverse;
  292.  
  293.     Matrix4 m(*this);
  294.  
  295.     Matrix4 mat = Matrix4::identity();
  296.     for (unsigned column = 0; column < N; ++column) {
  297.         // Swap row in case our pivot point is not working
  298.         if (m(column, column) == 0) {
  299.             unsigned big = column;
  300.             for (unsigned row = 0; row < N; ++row)
  301.                 if (fabs(m(row, column)) > fabs(m(big, column))) big = row;
  302.             // Print this is a singular matrix, return identity ?
  303.             if (big == column) fprintf(stderr, "Singular matrix\n");
  304.             // Swap rows
  305.             else for (unsigned j = 0; j < N; ++j) {
  306.                 std::swap(m(column, j), m(big, j));
  307.                 std::swap(mat(column, j), mat(big, j));
  308.             }
  309.         }
  310.         // Set each row in the column to 0
  311.         for (unsigned row = 0; row < N; ++row) {
  312.             if (row != column) {
  313.                 float coeff = m(row, column) / m(column, column);
  314.                 if (coeff != 0) {
  315.                     for (unsigned j = 0; j < N; ++j) {
  316.                         m(row, j) -= coeff * m(column, j);
  317.                         mat(row, j) -= coeff * mat(column, j);
  318.                     }
  319.                     // Set the element to 0 for safety
  320.                     m(row, column)= 0;
  321.                 }
  322.             }
  323.         }
  324.     }
  325.     // Set each element of the diagonal to 1
  326.     for (unsigned row = 0; row < N; ++row) {
  327.         for (unsigned column = 0; column < N; ++column) {
  328.             mat(row, column) /= m(row, row);
  329.         }
  330.     }
  331.     precomputedInverse = new Matrix4(mat);
  332.     hasInverse = true;
  333.     return *precomputedInverse;
  334. }
  335.  
  336. void Matrix4::invert() {
  337.     *this = this->inverse();
  338. }
  339.  
  340. Matrix3 Matrix4::submatrix() const {
  341.     Matrix3 submat;
  342.     for (int i=0; i<3; i++)
  343.         for (int j=0; j<3; j++)
  344.             submat(i, j) = this->operator ()(i, j);
  345.  
  346.     return submat;
  347. }
  348.  
  349. void Matrix4::setSubmatrix(Matrix3 &mat3) {
  350.     for (int i=0; i<3; i++)
  351.         for (int j=0; j<3; j++)
  352.             this->operator ()(i, j) = mat3(i, j);
  353. }
  354.  
  355. void Matrix4::print() const {
  356.     for (int n=0; n<N; n++)
  357.     {
  358.         for (int m=0; m<N; m++)
  359.             std::cout << this->operator ()(n, m) << " ";
  360.         std::cout << std::endl;
  361.     }
  362.     std::cout << std::endl;
  363. }
  364.  
  365. float &Matrix4::operator()(int i, int j) {
  366.     if ((i <= N) && (j <= N))
  367.         return this->data[i][j];
  368.     else
  369.         throw std::exception();
  370. }
  371. /*
  372.  * MATRIX3 BEGIN
  373. */
  374.  
  375.  
  376.  
  377. /*
  378.  * VECTOR3 BEGIN
  379. */
  380. Vector3::Vector3() {
  381.     for (int i=0; i<N; i++)
  382.         this->data[i] = 0;
  383. }
  384.  
  385. Vector3::Vector3(float x, float y, float z) {
  386.     this->x() = x;
  387.     this->y() = y;
  388.     this->z() = z;
  389. }
  390.  
  391. float& Vector3::x() {
  392.     return this->el(0);
  393. }
  394.  
  395. const float& Vector3::x() const {
  396.     return this->el(0);
  397. }
  398.  
  399. float& Vector3::y() {
  400.     return this->el(1);
  401. }
  402.  
  403. const float& Vector3::y() const{
  404.     return this->el(1);
  405. }
  406.  
  407. float& Vector3::z() {
  408.     return this->el(2);
  409. }
  410.  
  411. const float& Vector3::z() const {
  412.     return this->el(2);
  413. }
  414.  
  415. float& Vector3::el(int idx) {
  416.     return this->data[idx];
  417. }
  418.  
  419. const float& Vector3::el(int idx) const {
  420.     return this->data[idx];
  421. }
  422.  
  423. Vector3 Vector3::operator+(const Vector3& another) const {
  424.     Vector3 vec;
  425.     for (int i=0; i<N; i++)
  426.         vec.el(i) = this->el(i) + another.el(i);
  427.     return vec;
  428. }
  429.  
  430. float Vector3::dot(const Vector3& another) const {
  431.     return this->x() * another.x() +
  432.            this->y() * another.y() +
  433.            this->z() * another.z();
  434. }
  435.  
  436. Vector3 Vector3::cross(const Vector3& another) const {
  437.     return Vector3(this->y() * another.z() - this->z() * another.y(),
  438.                    this->z() * another.x() - this->x() * another.z(),
  439.                    this->x() * another.y() - this->y() * another.x());
  440. }
  441.  
  442. float Vector3::magnitude() const {
  443.     return sqrt(this->x() * this->x() +
  444.                 this->y() * this->y() +
  445.                 this->z() * this->z());
  446. }
  447.  
  448. Vector3 Vector3::normalized() const {
  449.     return *this / this->magnitude();
  450. }
  451.  
  452. void Vector3::normalize() {
  453.     *this = *this / this->magnitude();
  454. }
  455.  
  456. Vector3 Vector3::operator*(const float scalar) const {
  457.     Vector3 vec;
  458.     for (int i=0; i<N; i++)
  459.         vec.el(i) = this->el(i) * scalar;
  460.     return vec;
  461. }
  462.  
  463. Vector3 Vector3::operator*(const Vector3& another) const
  464. {
  465.     Vector3 vec;
  466.     for (int i=0; i<N; i++)
  467.         vec.el(i) = this->el(i) * another.el(i);
  468.     return vec;
  469. }
  470.  
  471. Vector3 Vector3::operator-() const {
  472.     return Vector3(-this->x(), -this->y(), -this->z());
  473. }
  474.  
  475. Vector3 Vector3::operator-(const Vector3& another) const {
  476.     Vector3 vec;
  477.     for (int i=0; i<N; i++)
  478.         vec.el(i) = this->el(i) - another.el(i);
  479.     return vec;
  480. }
  481.  
  482. Vector3 Vector3::operator/(const float scalar) const {
  483.     Vector3 vec;
  484.     for (int i=0; i<N; i++)
  485.         vec.el(i) = this->el(i) / scalar;
  486.     return vec;
  487. }
  488.  
  489. void Vector3::print() const {
  490.     for (int n=0; n<N; n++)
  491.         cout << this->el(n) << " ";
  492.     std::cout << std::endl;
  493. }
  494. /*
  495.  * VECTOR3 END
  496. */
  497.  
  498.  
  499.  
  500. /*
  501.  * VECTOR4 BEGIN
  502. */
  503. Vector4::Vector4() {
  504.     for (int i=0; i<N; i++)
  505.         this->data[i] = 0;
  506. }
  507.  
  508. Vector4::Vector4(float x, float y, float z, float w) {
  509.     this->x() = x;
  510.     this->y() = y;
  511.     this->z() = z;
  512.     this->w() = w;
  513. }
  514.  
  515. Vector4::Vector4(const Vector3& vec3, float w=0) {
  516.     this->x() = vec3.x();
  517.     this->y() = vec3.y();
  518.     this->z() = vec3.z();
  519.     this->w() = w;
  520. }
  521.  
  522. float& Vector4::x() {
  523.     return this->el(0);
  524. }
  525.  
  526. const float& Vector4::x() const {
  527.     return this->el(0);
  528. }
  529.  
  530. float& Vector4::y() {
  531.     return this->el(1);
  532. }
  533.  
  534. const float& Vector4::y() const {
  535.     return this->el(1);
  536. }
  537.  
  538. float& Vector4::z() {
  539.     return this->el(2);
  540. }
  541.  
  542. const float& Vector4::z() const {
  543.     return this->el(2);
  544. }
  545.  
  546. float& Vector4::w() {
  547.     return this->el(3);
  548. }
  549.  
  550. const float& Vector4::w() const {
  551.     return this->el(3);
  552. }
  553.  
  554. float& Vector4::el(int idx) {
  555.     return this->data[idx];
  556. }
  557.  
  558. const float& Vector4::el(int idx) const {
  559.     return this->data[idx];
  560. }
  561.  
  562. Vector3 Vector4::xyz() const {
  563.     return Vector3(this->x(),
  564.                    this->y(),
  565.                    this->z());
  566. }
  567.  
  568. Vector4 Vector4::operator+(const Vector4& another) const {
  569.     Vector4 vec;
  570.     for (int i=0; i<N-1; i++)
  571.         vec.el(i) = this->el(i) + another.el(i);
  572.     return vec;
  573. }
  574.  
  575. float Vector4::dot(const Vector4& another) const {
  576.     return this->x() * another.x() +
  577.            this->y() * another.y() +
  578.            this->z() * another.z();
  579. }
  580.  
  581. Vector4 Vector4::cross(const Vector4& another) const {
  582.     return Vector4(this->y() * another.z() - this->z() * another.y(),
  583.                    this->z() * another.x() - this->x() * another.z(),
  584.                    this->x() * another.y() - this->y() * another.x(),
  585.                    this->w());
  586. }
  587.  
  588. float Vector4::magnitude() const {
  589.     return sqrt(this->x() * this->x() +
  590.                 this->y() * this->y() +
  591.                 this->z() * this->z());
  592. }
  593.  
  594. Vector4 Vector4::normalized() const {
  595.     return *this / this->magnitude();
  596. }
  597.  
  598. void Vector4::normalize() {
  599.     *this = *this / this->magnitude();
  600. }
  601.  
  602. Vector4 Vector4::dehomogenized() const {
  603.     Vector4 vec;
  604.     for (int i=0; i<N; i++)
  605.         vec.el(i) = this->el(i) / this->w();
  606.     return vec;
  607. }
  608.  
  609. void Vector4::dehomogenize() {
  610.     for (int i=0; i<N; i++)
  611.         this->el(i) /= this->w();
  612. }
  613.  
  614. Vector4 Vector4::operator-() const {
  615.     return Vector4(-this->x(), -this->y(), -this->z(), this->w());
  616. }
  617.  
  618. Vector4 Vector4::operator-(const Vector4& another) const {
  619.     Vector4 vec;
  620.     for (int i=0; i<N-1; i++)
  621.         vec.el(i) = this->el(i) - another.el(i);
  622.     return vec;
  623. }
  624.  
  625. Vector4 Vector4::operator*(const float scalar) const {
  626.     Vector4 vec;
  627.     for (int i=0; i<N-1; i++)
  628.         vec.el(i) = this->el(i) * scalar;
  629.     return vec;
  630. }
  631.  
  632. Vector4 Vector4::operator/(const float scalar) const {
  633.     Vector4 vec;
  634.     for (int i=0; i<N-1; i++)
  635.         vec.el(i) = this->el(i) / scalar;
  636.     return vec;
  637. }
  638.  
  639. void Vector4::print() {
  640.     for (int n=0; n<N; n++)
  641.         cout << this->el(n) << " ";
  642.     std::cout << std::endl;
  643. }
  644. /*
  645.  * VECTOR4 END
  646. */
  647.  
  648.  
  649.  
  650. Matrix4 rotation(float angle, Vector3& axis) {
  651.     angle *= PI/180;
  652.  
  653.     Matrix3 dualMatrix;
  654.     dualMatrix(0, 0) = 0;
  655.     dualMatrix(0, 1) = -axis.z();
  656.     dualMatrix(0, 2) = axis.y();
  657.     dualMatrix(1, 0) = axis.z();
  658.     dualMatrix(1, 1) = 0.0;
  659.     dualMatrix(1, 2) = -axis.x();
  660.     dualMatrix(2, 0) = -axis.y();
  661.     dualMatrix(2, 1) = axis.x();
  662.     dualMatrix(2, 2) = 0;
  663.  
  664.     Matrix3 wtfMatrix;
  665.     wtfMatrix(0, 0) = axis.x() * axis.x();
  666.     wtfMatrix(0, 1) = axis.x() * axis.y();
  667.     wtfMatrix(0, 2) = axis.x() * axis.z();
  668.     wtfMatrix(1, 0) = axis.x() * axis.y();
  669.     wtfMatrix(1, 1) = axis.y() * axis.y();
  670.     wtfMatrix(1, 2) = axis.y() * axis.z();
  671.     wtfMatrix(2, 0) = axis.x() * axis.z();
  672.     wtfMatrix(2, 1) = axis.y() * axis.z();
  673.     wtfMatrix(2, 2) = axis.z() * axis.z();
  674.  
  675.  
  676.     Matrix3 rotation = Matrix3::identity();
  677.     rotation = (rotation * cos(angle)) +
  678.             (wtfMatrix * (1-cos(angle))) +
  679.             (dualMatrix * sin(angle));
  680.  
  681.     Matrix4 ret = Matrix4::identity();
  682.     ret.setSubmatrix(rotation);
  683.  
  684.     return ret;
  685. }
  686.  
  687.  
  688. Matrix4 translation(float x, float y, float z) {
  689.     Matrix4 translation = Matrix4::identity();
  690.  
  691.     translation(0, 3) = x;
  692.     translation(1, 3) = y;
  693.     translation(2, 3) = z;
  694.  
  695.     return translation;
  696. }
  697.  
  698.  
  699. Matrix4 scale(float x, float y, float z) {
  700.     Matrix4 scale = Matrix4::identity();
  701.  
  702.     scale(0, 0) = x;
  703.     scale(1, 1) = y;
  704.     scale(2, 2) = z;
  705.  
  706.     return scale;
  707. }
  708.  
  709.  
  710. Vector3 computeReflectedDirection(Vector3& eyeDirection, Vector3& normal)
  711. {
  712.     return eyeDirection - (normal * 2 * eyeDirection.dot(normal));
  713. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement