浏览代码

Euler Characteristic tests (#2250)

* test for euler characteristic

* doc
Alec Jacobson 2 年之前
父节点
当前提交
ab6229c77a
共有 2 个文件被更改,包括 63 次插入0 次删除
  1. 12 0
      include/igl/euler_characteristic.h
  2. 51 0
      tests/include/igl/euler_characteristic.cpp

+ 12 - 0
include/igl/euler_characteristic.h

@@ -17,8 +17,20 @@ namespace igl
 {
   /// Computes the Euler characteristic of a given mesh (V,F)
   ///
+  /// χ = |V| - |E| + |F|
+  ///
+  /// For example,
+  ///   - a single triangle has 3 - 3 + 1 = 1
+  ///   - a tetrahedron has 4 - 6 + 4 = 2
+  ///
   /// @param[in] F #F by dim list of mesh faces (must be triangles)
   /// @return An int containing the Euler characteristic
+  ///
+  /// \note There is [some confusion](https://github.com/libigl/libigl/issues/2249#issue-1863608449) over the standard definition of Euler
+  /// characteristic. libigl's definition agrees with
+  /// [wikipedia](https://en.wikipedia.org/wiki/Euler_characteristic) and [David
+  /// Eppstein's
+  /// proofs](https://www.ics.uci.edu/~eppstein/junkyard/euler/all.html).
   template <typename DerivedF>
   IGL_INLINE int euler_characteristic(
     const Eigen::MatrixBase<DerivedF> & F);

+ 51 - 0
tests/include/igl/euler_characteristic.cpp

@@ -0,0 +1,51 @@
+#include <test_common.h>
+#include <igl/euler_characteristic.h>
+#include <igl/read_triangle_mesh.h>
+#include <igl/triangulated_grid.h>
+#include <igl/matlab_format.h>
+#include <iostream>
+
+TEST_CASE("euler_characteristic: cube", "[igl]" )
+{
+  Eigen::MatrixXi F(12,3);
+  F <<
+    0,1,2,
+    0,2,3,
+    0,4,5,
+    0,5,1,
+    0,3,7,
+    0,7,4,
+    6,5,4,
+    6,4,7,
+    6,7,3,
+    6,3,2,
+    6,2,1,
+    6,1,5;
+  const int chi = igl::euler_characteristic(F);
+  REQUIRE(chi == 2);
+}
+
+TEST_CASE("euler_characteristic: triangle", "[igl]" )
+{
+  Eigen::MatrixXi F(1,3);
+  F << 0,1,2;
+  const int chi = igl::euler_characteristic(F);
+  REQUIRE(chi == 1);
+}
+
+TEST_CASE("euler_characteristic: square", "[igl]" )
+{
+  Eigen::MatrixXi F;
+  igl::triangulated_grid(3,3,F);
+  const int chi = igl::euler_characteristic(F);
+  REQUIRE(chi == 1);
+}
+
+TEST_CASE("euler_characteristic: torus", "[igl]" )
+{
+  Eigen::MatrixXd V;
+  Eigen::MatrixXi F;
+  igl::read_triangle_mesh(test_common::data_path("TinyTorus.obj"), V, F);
+  const int chi = igl::euler_characteristic(F);
+  REQUIRE(chi == 0);
+}