DGtal 1.3.0
Loading...
Searching...
No Matches
testNormalCycleComputer.cpp
Go to the documentation of this file.
1
31#include <iostream>
32#include <vector>
33#include <algorithm>
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"
41
42using namespace std;
43using namespace DGtal;
44
45
47// Functions for testing class NormalCycleComputer.
49
50SCENARIO( "NormalCycleComputer sphere tests", "[nc][sphere]" )
51{
52 using namespace Z3i;
56
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 );
66 }
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 );
72 }
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 );
78 }
79 }
80}
81
82SCENARIO( "NormalCycleComputer Schwarz lantern tests", "[nc][lantern]" )
83{
84 using namespace Z3i;
88
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 );
98 }
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 );
104 }
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 );
110 }
111 }
112}
113
114
115SCENARIO( "NormalCycleComputer convergence tests", "[nc][convergence]" )
116{
117 using namespace Z3i;
121
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 )
126 {
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() );
132 }
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 < errors_mu0.size()-1; i++ ) {
136 REQUIRE( errors_mu0[ i+1 ] < errors_mu0[ i ] );
137 }
138 }
139 }
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 )
144 {
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() );
150 }
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 < errors_mu1.size()-1; i++ ) {
154 REQUIRE( errors_mu1[ i+1 ] < errors_mu1[ i ] );
155 }
156 }
157 }
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 )
162 {
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() );
168 }
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 ( auto i = 0; i < errors_mu2.size(); i++ ) {
172 REQUIRE( errors_mu2[ i ] == Approx( 0.0 ).margin( 1e-8 ) );
173 }
174 }
175 }
176}
177
178// //
Aim: Implements basic operations that will be used in Point and Vector classes.
Definition: PointVector.h:593
DGtal is the top-level namespace which contains all DGtal functions and types.
STL namespace.
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 ...
Definition: SurfaceMesh.h:92
GIVEN("A cubical complex with random 3-cells")
REQUIRE(domain.isInside(aPoint))
SCENARIO("UnorderedSetByBlock< PointVector< 2, int > unit tests with 32 bits blocks", "[unorderedsetbyblock][2d]")