diff --git a/raytracing/src/matrix.cpp b/raytracing/src/matrix.cpp index a929db2..6c5fc7b 100644 --- a/raytracing/src/matrix.cpp +++ b/raytracing/src/matrix.cpp @@ -267,6 +267,34 @@ bool Matrix::invertible(void) /* ------------------------------------------------------------------------- */ +std::tuple Matrix::inverse(void) +{ + Matrix the_result(m_rows, m_cols); + bool the_status = false; + double the_cofactor, the_determinant, the_value; + + if (!invertible()) + { + return {the_result, false}; + } + + the_determinant = determinant(); + + for (int the_row = 0; the_row < m_rows; the_row++) + { + for (int the_col = 0; the_col < m_cols; the_col++) + { + the_cofactor = cofactor(the_row, the_col); + the_value = the_cofactor / the_determinant; + the_result[the_col][the_row] = the_value; + } + } + + return {the_result, true}; +} + +/* ------------------------------------------------------------------------- */ + Matrix Matrix::identity(void) { Matrix the_identity = { diff --git a/raytracing/src/matrix.h b/raytracing/src/matrix.h index ac94374..70254e7 100644 --- a/raytracing/src/matrix.h +++ b/raytracing/src/matrix.h @@ -30,6 +30,7 @@ #include #include +#include #include #include "tuple.h" @@ -67,6 +68,8 @@ namespace Raytracer bool invertible(void); + std::tuple inverse(void); + static Matrix identity(void); private: diff --git a/tests/03_matrix.cpp b/tests/03_matrix.cpp index 62c04ce..99f1fe1 100644 --- a/tests/03_matrix.cpp +++ b/tests/03_matrix.cpp @@ -27,8 +27,7 @@ #include -#include "matrix.h" -#include "tuple.h" +#include "raytracing.h" using namespace Raytracer; @@ -374,3 +373,32 @@ TEST_CASE("[Matrix] Testing an noninvertible matrix for invertibility", "[Matrix REQUIRE(a.determinant() == 0); REQUIRE(a.invertible() == false); } + +/* ------------------------------------------------------------------------- */ + +TEST_CASE("[Matrix] Calculating the inverse of a matrix", "[Matrix]") +{ + Matrix a = { + {-5, 2, 6, -8}, + { 1, -5, 1, 8}, + { 7, 7, -6, -7}, + { 1, -3, 7, 4} + }; + + Matrix b_inverted = { + { 0.21805, 0.45113, 0.24060, -0.04511}, + {-0.80827, -1.45677, -0.44361, 0.52068}, + {-0.07895, -0.22368, -0.05263, 0.19737}, + {-0.52256, -0.81391, -0.30075, 0.30639} + }; + + auto [b, the_status] = a.inverse(); + + REQUIRE(the_status == true); + REQUIRE(a.determinant() == 532); + REQUIRE(a.cofactor(2, 3) == -160); + REQUIRE(b[3][2] == -160.0 / 532.0); + REQUIRE(a.cofactor(3, 2) == 105); + REQUIRE(b[2][3] == 105.0 / 532.0); + REQUIRE(b == b_inverted); +}