34 #include "DGtal/base/Common.h"
35 #include "DGtal/kernel/SpaceND.h"
36 #include "DGtal/shapes/SurfaceMesh.h"
37 #include "DGtal/shapes/SurfaceMeshHelper.h"
38 #include "DGtal/geometry/meshes/NormalCycleComputer.h"
39 #include "DGtalCatch.h"
43 using namespace DGtal;
50 SCENARIO(
"NormalCycleComputer sphere tests",
"[nc][sphere]" )
57 SM sphere = SMH::makeSphere( 1.0,
RealPoint { 0.0, 0.0, 0.0 }, 10, 10,
58 SMH::NormalsType::FACE_NORMALS );
59 NCComputer nc_computer ( sphere );
60 GIVEN(
"A discretized sphere of radius 1 with 10x10 quadrangles and triangles" ) {
61 THEN(
"Its total mu0 measure is close to 4*pi (area)" ) {
62 auto mu0 = nc_computer .computeMu0();
63 double total_area = mu0.measure();
64 Approx sphere_area = Approx( 4.0 * M_PI ).epsilon(0.05);
65 REQUIRE( total_area == sphere_area );
67 THEN(
"Its total mu1 measure is close to 8*pi (twice mean curvature)" ) {
68 auto mu1 = nc_computer .computeMu1();
69 double total_mu1 = mu1.measure();
70 Approx twice_mean_c = Approx( 8.0 * M_PI ).epsilon(0.05);
71 REQUIRE( total_mu1 == twice_mean_c );
73 THEN(
"Its total mu2 measure is close to 4*pi (Gaussian curvature)" ) {
74 auto mu2 = nc_computer .computeMu2();
75 double total_mu2 = mu2.measure();
76 Approx gaussian_c = Approx( 4.0 * M_PI ).epsilon(0.05);
77 REQUIRE( total_mu2 == gaussian_c );
82 SCENARIO(
"NormalCycleComputer Schwarz lantern tests",
"[nc][lantern]" )
89 SM lantern = SMH::makeLantern( 1.0, 1.0,
RealPoint { 0.0, 0.0, 0.0 }, 30, 12,
90 SMH::NormalsType::VERTEX_NORMALS );
91 NCComputer nc_computer ( lantern );
92 GIVEN(
"A discretized lantern of radius 1 with 30x12x2 triangles" ) {
93 THEN(
"Its total mu0 measure is close to 2*pi (area)" ) {
94 auto mu0 = nc_computer .computeMu0();
95 double total_area = mu0.measure();
96 Approx lantern_area = Approx( 2.0 * M_PI ).epsilon(0.05);
97 REQUIRE( total_area != lantern_area );
99 THEN(
"Its total mu1 measure is not close to 2*pi (twice mean curvature)" ) {
100 auto mu1 = nc_computer .computeMu1();
101 double total_mu1 = mu1.measure();
102 Approx twice_mean_c = Approx( 2.0 * M_PI ).epsilon(0.05);
103 REQUIRE( total_mu1 != twice_mean_c );
105 THEN(
"Its total mu2 measure not close to 0 (Gaussian curvature)" ) {
106 auto mu2 = nc_computer .computeMu2();
107 double total_mu2 = mu2.measure();
108 Approx gaussian_c = Approx( 0.0 ).epsilon(0.05);
109 REQUIRE( total_mu2 != gaussian_c );
115 SCENARIO(
"NormalCycleComputer convergence tests",
"[nc][convergence]" )
122 GIVEN(
"A sphere of radius 1 discretized finer and finer" ) {
123 THEN(
"The total mu0 measure tends toward the sphere area" ) {
124 std::vector< double > errors_mu0;
125 for (
unsigned int n = 10; n < 50; n += 10 )
127 SM sphere = SMH::makeSphere( 1.0,
RealPoint { 0.0, 0.0, 0.0 }, n, n,
128 SMH::NormalsType::VERTEX_NORMALS );
129 NCComputer nc_computer ( sphere );
130 auto mu0 = nc_computer .computeMu0();
131 errors_mu0.push_back( mu0.measure() );
133 double sphere_area = 4.0 * M_PI;
134 for (
auto & v : errors_mu0 ) v = fabs( v - sphere_area ) / sphere_area;
135 for (
auto i = 0; i < (int)errors_mu0.size()-1; i++ ) {
136 REQUIRE( errors_mu0[ i+1 ] < errors_mu0[ i ] );
140 GIVEN(
"A sphere of radius 1 discretized finer and finer" ) {
141 THEN(
"The total mu1 measure tends toward twice the sphere area" ) {
142 std::vector< double > errors_mu1;
143 for (
unsigned int n = 10; n < 50; n += 10 )
145 SM sphere = SMH::makeSphere( 1.0,
RealPoint { 0.0, 0.0, 0.0 }, n, n,
146 SMH::NormalsType::VERTEX_NORMALS );
147 NCComputer nc_computer ( sphere );
148 auto mu1 = nc_computer .computeMu1();
149 errors_mu1.push_back( mu1.measure() );
151 double sphere_twice_mc = 8.0 * M_PI;
152 for (
auto & v : errors_mu1 ) v = fabs( v - sphere_twice_mc ) / sphere_twice_mc;
153 for (
auto i = 0; i < (int)errors_mu1.size()-1; i++ ) {
154 REQUIRE( errors_mu1[ i+1 ] < errors_mu1[ i ] );
158 GIVEN(
"A sphere of radius 1 discretized finer and finer" ) {
159 THEN(
"The total mu2 measure is the sphere area" ) {
160 std::vector< double > errors_mu2;
161 for (
unsigned int n = 10; n < 50; n += 10 )
163 SM sphere = SMH::makeSphere( 1.0,
RealPoint { 0.0, 0.0, 0.0 }, n, n,
164 SMH::NormalsType::VERTEX_NORMALS );
165 NCComputer nc_computer ( sphere );
166 auto mu2 = nc_computer .computeMu2();
167 errors_mu2.push_back( mu2.measure() );
169 double sphere_gauss_c = 4.0 * M_PI;
170 for (
auto & v : errors_mu2 ) v = fabs( v - sphere_gauss_c ) / sphere_gauss_c;
171 for (
size_t i = 0; i < errors_mu2.size(); i++ ) {
172 REQUIRE( errors_mu2[ i ] == Approx( 0.0 ).margin( 1e-8 ) );
DGtal is the top-level namespace which contains all DGtal functions and types.
Aim: Utility class to compute curvatures measures induced by (1) the normal cycle induced by a Surfac...
Aim: An helper class for building classical meshes.
Aim: Represents an embedded mesh as faces and a list of vertices. Vertices may be shared among faces ...
GIVEN("A cubical complex with random 3-cells")
SCENARIO("NormalCycleComputer sphere tests", "[nc][sphere]")
REQUIRE(domain.isInside(aPoint))