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/CorrectedNormalCurrentComputer.h"
39 #include "DGtalCatch.h"
43 using namespace DGtal;
50 SCENARIO(
"CorrectedNormalCurrentComputer interpolated curvature measures on sphere tests",
"[icnc][sphere]" )
57 SM sphere = SMH::makeSphere( 1.0,
RealPoint { 0.0, 0.0, 0.0 }, 20, 20,
58 SMH::NormalsType::VERTEX_NORMALS );
59 CNCComputer cnc_computer ( sphere,
false );
60 CNCComputer cncu_computer( sphere,
true );
61 GIVEN(
"A discretized sphere of radius 1 with 20x20x2 triangles" ) {
62 THEN(
"Its total mu0 measure is close to 4*pi (area)" ) {
63 auto mu0 = cnc_computer .computeMu0();
64 auto mu0_u = cncu_computer.computeMu0();
65 double total_area = mu0.measure();
66 double total_area_u = mu0_u.measure();
67 Approx sphere_area = Approx( 4.0 * M_PI ).epsilon(0.05);
68 REQUIRE( total_area == sphere_area );
69 REQUIRE( total_area_u == sphere_area );
71 THEN(
"Its total mu1 measure is close to 8*pi (twice mean curvature)" ) {
72 auto mu1 = cnc_computer .computeMu1();
73 auto mu1_u = cncu_computer.computeMu1();
74 double total_mu1 = mu1.measure();
75 double total_mu1_u = mu1_u.measure();
76 Approx twice_mean_c = Approx( 8.0 * M_PI ).epsilon(0.05);
77 REQUIRE( total_mu1 == twice_mean_c );
78 REQUIRE( total_mu1_u == twice_mean_c );
80 THEN(
"Its total mu2 measure is close to 4*pi (Gaussian curvature)" ) {
81 auto mu2 = cnc_computer .computeMu2();
82 auto mu2_u = cncu_computer.computeMu2();
83 double total_mu2 = mu2.measure();
84 double total_mu2_u = mu2_u.measure();
85 Approx gaussian_c = Approx( 4.0 * M_PI ).epsilon(0.05);
86 REQUIRE( total_mu2 == gaussian_c );
87 Approx exact_gaussian_c = Approx( 4.0 * M_PI ).epsilon(0.000005);
88 REQUIRE( total_mu2_u == exact_gaussian_c );
93 SCENARIO(
"CorrectedNormalCurrentComputer face-constant curvature measures on sphere tests",
"[ccnc][sphere]" )
100 SM sphere = SMH::makeSphere( 1.0,
RealPoint { 0.0, 0.0, 0.0 }, 20, 20,
101 SMH::NormalsType::FACE_NORMALS );
102 CNCComputer cnc_computer ( sphere,
false );
103 CNCComputer cncu_computer( sphere,
true );
104 GIVEN(
"A discretized sphere of radius 1 with 20x20x2 triangles" ) {
105 THEN(
"Its total mu0 measure is close to 4*pi (area)" ) {
106 auto mu0 = cnc_computer .computeMu0();
107 auto mu0_u = cncu_computer.computeMu0();
108 double total_area = mu0.measure();
109 double total_area_u = mu0_u.measure();
110 Approx sphere_area = Approx( 4.0 * M_PI ).epsilon(0.05);
111 REQUIRE( total_area == sphere_area );
112 REQUIRE( total_area_u == sphere_area );
114 THEN(
"Its total mu1 measure is close to 8*pi (twice mean curvature)" ) {
115 auto mu1 = cnc_computer .computeMu1();
116 auto mu1_u = cncu_computer.computeMu1();
117 double total_mu1 = mu1.measure();
118 double total_mu1_u = mu1_u.measure();
119 Approx twice_mean_c = Approx( 8.0 * M_PI ).epsilon(0.05);
120 REQUIRE( total_mu1 == twice_mean_c );
121 REQUIRE( total_mu1_u == twice_mean_c );
123 THEN(
"Its total mu2 measure is close to 4*pi (Gaussian curvature)" ) {
124 auto mu2 = cnc_computer .computeMu2();
125 auto mu2_u = cncu_computer.computeMu2();
126 double total_mu2 = mu2.measure();
127 double total_mu2_u = mu2_u.measure();
128 Approx gaussian_c = Approx( 4.0 * M_PI ).epsilon(0.05);
129 REQUIRE( total_mu2 == gaussian_c );
130 Approx exact_gaussian_c = Approx( 4.0 * M_PI ).epsilon(0.000005);
131 REQUIRE( total_mu2_u == exact_gaussian_c );
136 SCENARIO(
"CorrectedNormalCurrentComputer interpolated curvature measures on Schwarz lantern tests",
"[icnc][lantern]" )
143 SM lantern = SMH::makeLantern( 1.0, 1.0,
RealPoint { 0.0, 0.0, 0.0 }, 30, 12,
144 SMH::NormalsType::VERTEX_NORMALS );
145 CNCComputer cnc_computer ( lantern,
false );
146 CNCComputer cncu_computer( lantern,
true );
147 GIVEN(
"A discretized lantern of radius 1 with 30x12x2 triangles" ) {
148 THEN(
"Its total mu0 measure is close to 2*pi (area)" ) {
149 auto mu0 = cnc_computer .computeMu0();
150 auto mu0_u = cncu_computer.computeMu0();
151 double total_area = mu0.measure();
152 double total_area_u = mu0_u.measure();
153 Approx lantern_area = Approx( 2.0 * M_PI ).epsilon(0.05);
154 REQUIRE( total_area == lantern_area );
155 REQUIRE( total_area_u == lantern_area );
157 THEN(
"Its total mu1 measure is close to 2*pi (twice mean curvature)" ) {
158 auto mu1 = cnc_computer .computeMu1();
159 auto mu1_u = cncu_computer.computeMu1();
160 double total_mu1 = mu1.measure();
161 double total_mu1_u = mu1_u.measure();
162 Approx twice_mean_c = Approx( 2.0 * M_PI ).epsilon(0.05);
163 REQUIRE( total_mu1 == twice_mean_c );
164 REQUIRE( total_mu1_u == twice_mean_c );
166 THEN(
"Its total mu2 measure is close to 0 (Gaussian curvature)" ) {
167 auto mu2 = cnc_computer .computeMu2();
168 auto mu2_u = cncu_computer.computeMu2();
169 double total_mu2 = mu2.measure();
170 double total_mu2_u = mu2_u.measure();
171 Approx exact_gaussian_c = Approx( 0.0 ).epsilon(0.000005);
172 REQUIRE( total_mu2 == exact_gaussian_c );
173 REQUIRE( total_mu2_u == exact_gaussian_c );
178 SCENARIO(
"CorrectedNormalCurrentComputer face-constant curvature measures on Schwarz lantern tests",
"[ccnc][lantern]" )
185 SM lantern = SMH::makeLantern( 1.0, 1.0,
RealPoint { 0.0, 0.0, 0.0 }, 30, 12,
186 SMH::NormalsType::FACE_NORMALS );
187 CNCComputer cnc_computer ( lantern,
false );
188 CNCComputer cncu_computer( lantern,
true );
189 GIVEN(
"A discretized lantern of radius 1 with 30x12x2 triangles" ) {
190 THEN(
"Its total mu0 measure is close to 2*pi (area)" ) {
191 auto mu0 = cnc_computer .computeMu0();
192 auto mu0_u = cncu_computer.computeMu0();
193 double total_area = mu0.measure();
194 double total_area_u = mu0_u.measure();
195 Approx lantern_area = Approx( 2.0 * M_PI ).epsilon(0.05);
196 REQUIRE( total_area == lantern_area );
197 REQUIRE( total_area_u == lantern_area );
199 THEN(
"Its total mu1 measure is close to 2*pi (twice mean curvature)" ) {
200 auto mu1 = cnc_computer .computeMu1();
201 auto mu1_u = cncu_computer.computeMu1();
202 double total_mu1 = mu1.measure();
203 double total_mu1_u = mu1_u.measure();
204 Approx twice_mean_c = Approx( 2.0 * M_PI ).epsilon(0.05);
205 REQUIRE( total_mu1 == twice_mean_c );
206 REQUIRE( total_mu1_u == twice_mean_c );
208 THEN(
"Its total mu2 measure is close to 0 (Gaussian curvature)" ) {
209 auto mu2 = cnc_computer .computeMu2();
210 auto mu2_u = cncu_computer.computeMu2();
211 double total_mu2 = mu2.measure();
212 double total_mu2_u = mu2_u.measure();
213 Approx exact_gaussian_c = Approx( 0.0 ).epsilon(0.000005);
214 REQUIRE( total_mu2 == exact_gaussian_c );
215 REQUIRE( total_mu2_u == exact_gaussian_c );
221 SCENARIO(
"CorrectedNormalCurrentComputer ICNC convergence tests",
"[icnc][convergence]" )
228 GIVEN(
"A sphere of radius 1 discretized finer and finer" ) {
229 THEN(
"The total mu0 measure tends toward the sphere area" ) {
230 std::vector< double > errors_mu0;
231 for (
unsigned int n = 10; n < 50; n += 10 )
233 SM sphere = SMH::makeSphere( 1.0,
RealPoint { 0.0, 0.0, 0.0 }, n, n,
234 SMH::NormalsType::VERTEX_NORMALS );
235 CNCComputer cnc_computer ( sphere,
false );
236 auto mu0 = cnc_computer .computeMu0();
237 errors_mu0.push_back( mu0.measure() );
239 double sphere_area = 4.0 * M_PI;
240 for (
auto & v : errors_mu0 ) v = fabs( v - sphere_area ) / sphere_area;
241 for (
auto i = 0; i < (int)errors_mu0.size()-1; i++ ) {
242 REQUIRE( errors_mu0[ i+1 ] < errors_mu0[ i ] );
246 GIVEN(
"A sphere of radius 1 discretized finer and finer" ) {
247 THEN(
"The total mu1 measure tends toward twice the sphere area" ) {
248 std::vector< double > errors_mu1;
249 for (
unsigned int n = 10; n < 50; n += 10 )
251 SM sphere = SMH::makeSphere( 1.0,
RealPoint { 0.0, 0.0, 0.0 }, n, n,
252 SMH::NormalsType::VERTEX_NORMALS );
253 CNCComputer cnc_computer ( sphere,
false );
254 auto mu1 = cnc_computer .computeMu1();
255 errors_mu1.push_back( mu1.measure() );
257 double sphere_twice_mc = 8.0 * M_PI;
258 for (
auto & v : errors_mu1 ) v = fabs( v - sphere_twice_mc ) / sphere_twice_mc;
259 for (
auto i = 0; i < (int)errors_mu1.size()-1; i++ ) {
260 REQUIRE( errors_mu1[ i+1 ] < errors_mu1[ i ] );
264 GIVEN(
"A sphere of radius 1 discretized finer and finer" ) {
265 THEN(
"The total mu2 measure tends toward the sphere area" ) {
266 std::vector< double > errors_mu2;
267 for (
unsigned int n = 10; n < 50; n += 10 )
269 SM sphere = SMH::makeSphere( 1.0,
RealPoint { 0.0, 0.0, 0.0 }, n, n,
270 SMH::NormalsType::VERTEX_NORMALS );
271 CNCComputer cnc_computer ( sphere,
false );
272 auto mu2 = cnc_computer .computeMu2();
273 errors_mu2.push_back( mu2.measure() );
275 double sphere_gauss_c = 4.0 * M_PI;
276 for (
auto & v : errors_mu2 ) v = fabs( v - sphere_gauss_c ) / sphere_gauss_c;
277 for (
auto i = 0; i < (int)errors_mu2.size()-1; i++ ) {
278 REQUIRE( errors_mu2[ i+1 ] < errors_mu2[ i ] );
284 SCENARIO(
"CorrectedNormalCurrentComputer CCNC convergence tests",
"[ccnc][convergence]" )
291 GIVEN(
"A sphere of radius 1 discretized finer and finer" ) {
292 THEN(
"The total mu0 measure tends toward the sphere area" ) {
293 std::vector< double > errors_mu0;
294 for (
unsigned int n = 10; n < 50; n += 10 )
296 SM sphere = SMH::makeSphere( 1.0,
RealPoint { 0.0, 0.0, 0.0 }, n, n,
297 SMH::NormalsType::FACE_NORMALS );
298 CNCComputer cnc_computer ( sphere,
false );
299 auto mu0 = cnc_computer .computeMu0();
300 errors_mu0.push_back( mu0.measure() );
302 double sphere_area = 4.0 * M_PI;
303 for (
auto & v : errors_mu0 ) v = fabs( v - sphere_area ) / sphere_area;
304 for (
auto i = 0; i < (int)errors_mu0.size()-1; i++ ) {
305 REQUIRE( errors_mu0[ i+1 ] < errors_mu0[ i ] );
309 GIVEN(
"A sphere of radius 1 discretized finer and finer" ) {
310 THEN(
"The total mu1 measure tends toward twice the sphere area" ) {
311 std::vector< double > errors_mu1;
312 for (
unsigned int n = 10; n < 50; n += 10 )
314 SM sphere = SMH::makeSphere( 1.0,
RealPoint { 0.0, 0.0, 0.0 }, n, n,
315 SMH::NormalsType::FACE_NORMALS );
316 CNCComputer cnc_computer ( sphere,
false );
317 auto mu1 = cnc_computer .computeMu1();
318 errors_mu1.push_back( mu1.measure() );
320 double sphere_twice_mc = 8.0 * M_PI;
321 for (
auto & v : errors_mu1 ) v = fabs( v - sphere_twice_mc ) / sphere_twice_mc;
322 for (
auto i = 0; i < (int)errors_mu1.size()-1; i++ ) {
323 REQUIRE( errors_mu1[ i+1 ] < errors_mu1[ i ] );
DGtal is the top-level namespace which contains all DGtal functions and types.
Aim: Utility class to compute curvature measures induced by (1) a corrected normal current defined by...
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 ...
SCENARIO("CorrectedNormalCurrentComputer interpolated curvature measures on sphere tests", "[icnc][sphere]")
GIVEN("A cubical complex with random 3-cells")
REQUIRE(domain.isInside(aPoint))