cotmatrix_entries.cpp 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. #include <test_common.h>
  2. #include <igl/cotmatrix_entries.h>
  3. TEST_CASE("cotmatrix_entries: simple", "[igl]")
  4. {
  5. //The allowed error for this test
  6. const double epsilon = 1e-15;
  7. Eigen::MatrixXd V;
  8. Eigen::MatrixXi F;
  9. //This is a cube of dimensions 1.0x1.0x1.0
  10. test_common::load_mesh("cube.obj", V, F);
  11. //Prepare another mesh with triangles along side diagonals of the cube
  12. //These triangles are form a regular tetrahedron of side sqrt(2)
  13. Eigen::MatrixXi F_tet(4,3);
  14. F_tet << 4,6,1,
  15. 6,4,3,
  16. 4,1,3,
  17. 1,6,3;
  18. //1. Check cotmatrix_entries
  19. Eigen::MatrixXd C1;
  20. igl::cotmatrix_entries(V,F,C1);
  21. REQUIRE (C1.rows() == F.rows());
  22. REQUIRE (C1.cols() == 3);
  23. //All angles in unit cube measure 45 or 90 degrees
  24. //Their (half)cotangent must value 0.5 or 0.0
  25. for(int f = 0;f<C1.rows();f++)
  26. {
  27. #ifdef IGL_EDGE_LENGTHS_SQUARED_H
  28. //Hard assert if we have edge_lenght_squared
  29. for(int v = 0;v<3;v++)
  30. if (C1(f,v) > 0.1)
  31. REQUIRE (C1(f,v) == 0.5);
  32. else
  33. REQUIRE (C1(f,v) == 0.0);
  34. //All cotangents sum 1.0 for those triangles
  35. REQUIRE (C1.row(f).sum() == 1.0);
  36. #else
  37. //Soft assert if we have not edge_lenght_squared
  38. for(int v = 0;v<3;v++)
  39. if (C1(f,v) > 0.1)
  40. REQUIRE (C1(f,v) == Approx (0.5).margin( epsilon));
  41. else
  42. REQUIRE (C1(f,v) == Approx (0.0).margin( epsilon));
  43. //All cotangents sum 1.0 for those triangles
  44. REQUIRE (C1.row(f).sum() == Approx (1.0).margin( epsilon));
  45. #endif
  46. }
  47. //Check the regular tetrahedron
  48. Eigen::MatrixXd C2;
  49. igl::cotmatrix_entries(V,F_tet,C2);
  50. REQUIRE (C2.rows() == F_tet.rows());
  51. REQUIRE (C2.cols() == 3);
  52. for(int f = 0;f<C2.rows();f++)
  53. {
  54. //Their (half)cotangent must value 0.5 / tan(M_PI / 3.0)
  55. for(int v = 0;v<3;v++)
  56. REQUIRE (C2(f,v) == Approx (0.5 / tan(M_PI / 3.0)).margin( epsilon));
  57. }
  58. //Scale the cube to have huge sides
  59. Eigen::MatrixXd V_huge = V * 1.0e8;
  60. igl::cotmatrix_entries(V_huge,F,C1);
  61. REQUIRE (C1.rows() == F.rows());
  62. REQUIRE (C1.cols() == 3);
  63. //All angles still measure 45 or 90 degrees
  64. //Their (half)cotangent must value 0.5 or 0.0
  65. for(int f = 0;f<C1.rows();f++)
  66. {
  67. #ifdef IGL_EDGE_LENGTHS_SQUARED_H
  68. //Hard assert if we have edge_lenght_squared
  69. for(int v = 0;v<3;v++)
  70. if (C1(f,v) > 0.1)
  71. REQUIRE (C1(f,v) == 0.5);
  72. else
  73. REQUIRE (C1(f,v) == 0.0);
  74. //All cotangents sum 1.0 for those triangles
  75. REQUIRE (C1.row(f).sum() == 1.0);
  76. #else
  77. //Soft assert if we have not edge_lenght_squared
  78. for(int v = 0;v<3;v++)
  79. if (C1(f,v) > 0.1)
  80. REQUIRE (C1(f,v) == Approx (0.5).margin( epsilon));
  81. else
  82. REQUIRE (C1(f,v) == Approx (0.0).margin( epsilon));
  83. //All cotangents sum 1.0 for those triangles
  84. REQUIRE (C1.row(f).sum() == Approx (1.0).margin( epsilon));
  85. #endif
  86. }
  87. //Check the huge regular tetrahedron
  88. igl::cotmatrix_entries(V_huge,F_tet,C2);
  89. REQUIRE (C2.rows() == F_tet.rows());
  90. REQUIRE (C2.cols() == 3);
  91. for(int f = 0;f<C2.rows();f++)
  92. {
  93. //Their (half)cotangent must value 0.5 / tan(M_PI / 3.0)
  94. for(int v = 0;v<3;v++)
  95. REQUIRE (C2(f,v) == Approx (0.5 / tan(M_PI / 3.0)).margin( epsilon));
  96. }
  97. //Scale the cube to have tiny sides
  98. Eigen::MatrixXd V_tiny = V * 1.0e-8;
  99. igl::cotmatrix_entries(V_tiny,F,C1);
  100. REQUIRE (C1.rows() == F.rows());
  101. REQUIRE (C1.cols() == 3);
  102. //All angles still measure 45 or 90 degrees
  103. //Their (half)cotangent must value 0.5 or 0.0
  104. for(int f = 0;f<C1.rows();f++)
  105. {
  106. for(int v = 0;v<3;v++)
  107. if (C1(f,v) > 0.1)
  108. REQUIRE (C1(f,v) == Approx (0.5).margin( epsilon));
  109. else
  110. REQUIRE (C1(f,v) == Approx (0.0).margin( epsilon));
  111. //All cotangents sum 1.0 for those triangles
  112. REQUIRE (C1.row(f).sum() == Approx (1.0).margin( epsilon));
  113. }
  114. //Check the tiny regular tetrahedron
  115. igl::cotmatrix_entries(V_tiny,F_tet,C2);
  116. REQUIRE (C2.rows() == F_tet.rows());
  117. REQUIRE (C2.cols() == 3);
  118. for(int f = 0;f<C2.rows();f++)
  119. {
  120. //Their (half)cotangent must value 0.5 / tan(M_PI / 3.0)
  121. for(int v = 0;v<3;v++)
  122. REQUIRE (C2(f,v) == Approx (0.5 / tan(M_PI / 3.0)).margin( epsilon));
  123. }
  124. }