Bläddra i källkod

Add more tests

Sam Jaffe 7 år sedan
förälder
incheckning
64e3782c8e
3 ändrade filer med 84 tillägg och 1 borttagningar
  1. 2 0
      matrix_dummy.cpp
  2. 81 1
      matrix_helper_test.cpp
  3. 1 0
      matrix_helpers.hpp

+ 2 - 0
matrix_dummy.cpp

@@ -16,4 +16,6 @@ namespace math { namespace matrix {
   template matrix<double, 4, 4> translation(vector::vector<double, 3> const &);
   template matrix<double, 4, 4> scalar(vector::vector<double, 3> const &);
   template vector::vector<double, 3> operator*(matrix<double, 4, 4> const &, vector::vector<double, 3> const &);
+  template matrix<double, 3, 3> rotation(double, rotation_t<3>);
+  template matrix<double, 4, 4> rotation(double, rotation_t<3>);
 } }

+ 81 - 1
matrix_helper_test.cpp

@@ -11,6 +11,22 @@
 
 template <std::size_t N> using vec = math::vector::vector<double, N>;
 
+namespace math { namespace matrix {
+  template <typename T, std::size_t R, std::size_t C>
+  void PrintTo(matrix<T, R, C> const & matr, std::ostream * out) {
+    (*out) << "[\n";
+    VECTOR_FOR_EACH_RANGE(i, R) {
+      (*out) << "  [ ";
+      VECTOR_FOR_EACH_RANGE(j, C) {
+        if (j != 0) (*out) << ", ";
+        (*out) << matr(i, j);
+      }
+      (*out) << " ]\n";
+    }
+    (*out) << "]";
+  }
+} }
+
 TEST(MatrixHelper, IdentityFunctionProducesOnes) {
   auto iden = math::matrix::identity<double, 4>();
   VECTOR_FOR_EACH_RANGE(i, 4) {
@@ -36,5 +52,69 @@ TEST(MatrixHelper, ScalarMatrixPiecewiseStretchesVector) {
   vec<3> const vector({1.5, 0.5, -1.0});
   vec<3> const x({2.0, 3.8, 11.0});
   auto const A = math::matrix::scalar(vector);
-  EXPECT_THAT(A*x, vec<3>({3.0, 1.9, -11.0}));
+  EXPECT_THAT(A*x, vector * x);
+}
+
+TEST(MatrixHelper, TranslationMatrixAddsToEachElement) {
+  vec<3> const vector({1.5, 0.5, -1.0});
+  vec<3> const x({2.0, 3.8, 11.0});
+  auto const A = math::matrix::translation(vector);
+  EXPECT_THAT(A*x, vector + x);
 }
+
+using matr3 = math::matrix::matrix<double, 3, 3>;
+using math::matrix::rotation;
+using math::matrix::rotation_t;
+namespace rotate = math::matrix::rotate;
+
+class RotationTest : public ::testing::TestWithParam<std::tuple<rotation_t<3>, matr3>> {
+  
+};
+
+TEST(MatrixHelper, RotateByHalfPi) {
+  auto const theta = M_PI/2;
+  auto const iden = math::matrix::identity<double, 2>();
+  auto const expected = math::matrix::matrix<double, 2, 2>({{{0, -1},{1, 0}}});
+  
+  auto result = iden * rotation(theta, rotate::ROT_2D);
+  MATRIX_FOR_EACH_RANGE(i, 2, j, 2) {
+    EXPECT_THAT(result(i, j),
+                ::testing::DoubleNear(expected(i, j), std::numeric_limits<double>::epsilon()));
+  }
+}
+
+TEST_P(RotationTest, RotateByHalfPi) {
+  auto const theta = M_PI/2;
+  auto const iden = math::matrix::identity<double, 3>();
+  auto const expected = std::get<1>(GetParam());
+  
+  auto result = iden * rotation(theta, std::get<0>(GetParam()));
+  MATRIX_FOR_EACH_RANGE(i, 3, j, 3) {
+    EXPECT_THAT(result(i, j),
+                ::testing::DoubleNear(expected(i, j), std::numeric_limits<double>::epsilon()));
+  }
+}
+
+TEST(MatrixHelper, RotateIntoLargerMatrixArea) {
+  auto const theta = M_PI/2;
+  auto const iden = math::matrix::identity<double, 4>();
+  auto const expected = math::matrix::matrix<double, 4, 4>({{
+    {0,-1,0,0},
+    {1, 0,0,0},
+    {0, 0,1,0},
+    {0, 0,0,1}
+  }});
+  
+  auto result = iden * rotation<4>(theta, rotate::Z_AXIS);
+  MATRIX_FOR_EACH_RANGE(i, 4, j, 4) {
+    EXPECT_THAT(result(i, j),
+                ::testing::DoubleNear(expected(i, j), std::numeric_limits<double>::epsilon()));
+  }
+}
+
+std::vector<std::tuple<rotation_t<3>, matr3>> values{
+  {rotate::X_AXIS, matr3({{{1, 0,0},{0,0,-1},{ 0,1,0}}})},
+  {rotate::Y_AXIS, matr3({{{0, 0,1},{0,1, 0},{-1,0,0}}})},
+  {rotate::Z_AXIS, matr3({{{0,-1,0},{1,0, 0},{ 0,0,1}}})}
+};
+INSTANTIATE_TEST_CASE_P(MatrixHelper, RotationTest, ::testing::ValuesIn(values));

+ 1 - 0
matrix_helpers.hpp

@@ -76,6 +76,7 @@ namespace math { namespace matrix {
   
   template <size_t D, typename T, size_t RD>
   auto rotation(T theta, rotation_t<RD> r) -> matrix<decltype(sin(theta)), D, D> {
+    static_assert(D > RD, "rotation<D> has to increase the number of dimensions");
     using G = decltype(sin(theta));
     return rotation(theta, r).concat(identity<G, D - RD>(), concat_strategy::diagonal);
   }