cotmatrix_entries.cpp 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. #include <test_common.h>
  2. #include <igl/cotmatrix_entries.h>
  3. TEST(cotmatrix_entries, simple)
  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. ASSERT_EQ(F.rows(), C1.rows());
  22. ASSERT_EQ(3, C1.cols());
  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. ASSERT_EQ(0.5, C1(f,v));
  32. else
  33. ASSERT_EQ(0.0, C1(f,v));
  34. //All cotangents sum 1.0 for those triangles
  35. ASSERT_EQ(1.0, C1.row(f).sum());
  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. ASSERT_NEAR(0.5, C1(f,v), epsilon);
  41. else
  42. ASSERT_NEAR(0.0, C1(f,v), epsilon);
  43. //All cotangents sum 1.0 for those triangles
  44. ASSERT_NEAR(1.0, C1.row(f).sum(), epsilon);
  45. #endif
  46. }
  47. //Check the regular tetrahedron
  48. Eigen::MatrixXd C2;
  49. igl::cotmatrix_entries(V,F_tet,C2);
  50. ASSERT_EQ(F_tet.rows(), C2.rows());
  51. ASSERT_EQ(3, C2.cols());
  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. ASSERT_NEAR(0.5 / tan(M_PI / 3.0), C2(f,v), 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. ASSERT_EQ(F.rows(), C1.rows());
  62. ASSERT_EQ(3, C1.cols());
  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. ASSERT_EQ(0.5, C1(f,v));
  72. else
  73. ASSERT_EQ(0.0, C1(f,v));
  74. //All cotangents sum 1.0 for those triangles
  75. ASSERT_EQ(1.0, C1.row(f).sum());
  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. ASSERT_NEAR(0.5, C1(f,v), epsilon);
  81. else
  82. ASSERT_NEAR(0.0, C1(f,v), epsilon);
  83. //All cotangents sum 1.0 for those triangles
  84. ASSERT_NEAR(1.0, C1.row(f).sum(), epsilon);
  85. #endif
  86. }
  87. //Check the huge regular tetrahedron
  88. igl::cotmatrix_entries(V_huge,F_tet,C2);
  89. ASSERT_EQ(F_tet.rows(), C2.rows());
  90. ASSERT_EQ(3, C2.cols());
  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. ASSERT_NEAR(0.5 / tan(M_PI / 3.0), C2(f,v), 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. ASSERT_EQ(F.rows(), C1.rows());
  101. ASSERT_EQ(3, C1.cols());
  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. ASSERT_NEAR(0.5, C1(f,v), epsilon);
  109. else
  110. ASSERT_NEAR(0.0, C1(f,v), epsilon);
  111. //All cotangents sum 1.0 for those triangles
  112. ASSERT_NEAR(1.0, C1.row(f).sum(), epsilon);
  113. }
  114. //Check the tiny regular tetrahedron
  115. igl::cotmatrix_entries(V_tiny,F_tet,C2);
  116. ASSERT_EQ(F_tet.rows(), C2.rows());
  117. ASSERT_EQ(3, C2.cols());
  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. ASSERT_NEAR(0.5 / tan(M_PI / 3.0), C2(f,v), epsilon);
  123. }
  124. }//TEST(cotmatrix_entries, simple)