EigenValueSymmetricTests.cpp 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657
  1. // Jolt Physics Library (https://github.com/jrouwe/JoltPhysics)
  2. // SPDX-FileCopyrightText: 2024 Jorrit Rouwe
  3. // SPDX-License-Identifier: MIT
  4. #include "UnitTestFramework.h"
  5. #include <Jolt/Math/EigenValueSymmetric.h>
  6. #include <Jolt/Math/Matrix.h>
  7. TEST_SUITE("EigenValueSymmetricTests")
  8. {
  9. TEST_CASE("TestEigenValueSymmetric")
  10. {
  11. default_random_engine random;
  12. uniform_real_distribution<float> angle_distribution(0, 2.0f * JPH_PI);
  13. uniform_real_distribution<float> scale_distribution(0.1f, 10.0f);
  14. for (int i = 0; i < 1000; ++i)
  15. {
  16. // Random scale vector
  17. Vec3 scale(scale_distribution(random), scale_distribution(random), scale_distribution(random));
  18. // Random rotation matrix
  19. Mat44 rotation = Mat44::sRotation(Vec3::sRandom(random), angle_distribution(random));
  20. // Construct a symmetric tensor from this rotation and scale
  21. Mat44 tensor4 = rotation.Multiply3x3(Mat44::sScale(scale)).Multiply3x3RightTransposed(rotation);
  22. // Get the eigenvalues and eigenvectors
  23. Matrix<3, 3> tensor;
  24. Matrix<3, 3> eigen_vec = Matrix<3, 3>::sIdentity();
  25. Vector<3> eigen_val;
  26. tensor.CopyPart(tensor4, 0, 0, 3, 3, 0, 0);
  27. CHECK(EigenValueSymmetric(tensor, eigen_vec, eigen_val));
  28. for (int c = 0; c < 3; ++c)
  29. {
  30. // Check that we found a valid eigenvalue
  31. bool found = false;
  32. for (int c2 = 0; c2 < 3; ++c2)
  33. if (abs(scale[c2] - eigen_val[c]) < 1.0e-5f)
  34. {
  35. found = true;
  36. break;
  37. }
  38. CHECK(found);
  39. // Check if the eigenvector is normalized
  40. CHECK(eigen_vec.GetColumn(c).IsNormalized());
  41. // Check if matrix * eigen_vector = eigen_value * eigen_vector
  42. Vector mat_eigvec = tensor * eigen_vec.GetColumn(c);
  43. Vector eigval_eigvec = eigen_val[c] * eigen_vec.GetColumn(c);
  44. CHECK(mat_eigvec.IsClose(eigval_eigvec, Square(1.0e-5f)));
  45. }
  46. }
  47. }
  48. }