50{
54 typedef Space::Point
Point;
55 typedef std::size_t
Index;
56
57 SECTION(
"Computing shortest paths on a 3D unit sphere digitized at gridstep 0.25" )
58 {
59
60 const double h = 0.25;
61 auto params = SH3::defaultParameters();
62 params( "polynomial", "sphere1" )( "gridstep", h );
63 params( "minAABB", -2)( "maxAABB", 2)( "offset", 1.0 )( "closed", 1 );
64 auto implicit_shape = SH3::makeImplicitShape3D ( params );
65 auto digitized_shape = SH3::makeDigitizedImplicitShape3D( implicit_shape, params );
66 auto K = SH3::getKSpace( params );
67 auto binary_image = SH3::makeBinaryImage(digitized_shape,
69 params );
71 std::vector< Point > lattice_points;
72 auto pointels = SH3::getPointelRange(
surface );
73 for (
auto p : pointels ) lattice_points.push_back(
K.uCoords( p ) );
74 REQUIRE( pointels.size() == 296 );
75
76 const Index nb = lattice_points.size();
79 for (
Index i = 1; i < nb; i++ )
80 {
81 if ( lattice_points[ i ] < lattice_points[ lowest ] ) lowest = i;
82 if ( lattice_points[ uppest ] < lattice_points[ i ] ) uppest = i;
83 }
84
87 TC.init( lattice_points.cbegin(), lattice_points.cend() );
88 auto SP = TC.makeShortestPaths( sqrt(3.0) );
89 SP.init( lowest );
90 double last_distance = 0.0;
91 _Index last = 0;
92 double prev_distance = 0.0;
93 std::set< _Index > V;
94 unsigned int nb_multiple_pops = 0;
95 unsigned int nb_decreasing_distance = 0;
96 while ( ! SP.finished() )
97 {
98 last = std::get<0>( SP.current() );
99 last_distance = std::get<2>( SP.current() );
100 if ( V.count( last ) ) nb_multiple_pops += 1;
101 V.insert( last );
102 SP.expand();
103 if ( last_distance < prev_distance ) nb_decreasing_distance += 1;
104 prev_distance = last_distance;
105 }
106
107 REQUIRE( nb_multiple_pops == 0 );
108
109 REQUIRE( nb_decreasing_distance == 0 );
110
112
113 REQUIRE( last_distance*h >= 2.8 );
114 REQUIRE( last_distance*h <= 3.14159265358979323844 );
115
116 SP = TC.makeShortestPaths( 0 );
117 SP.init( uppest );
118 double last_distance_opt = 0.0;
119 while ( ! SP.finished() )
120 {
121 last = std::get<0>( SP.current() );
122 last_distance_opt = std::get<2>( SP.current() );
123 SP.expand();
124 }
125
127
128 REQUIRE( last_distance_opt*h >= 2.8 );
129 REQUIRE( last_distance_opt*h <= 3.14159265358979323844 );
130
131 REQUIRE( last_distance_opt*h >= last_distance*h );
132 }
133
134 SECTION(
"Computing different shortest paths on a 3D unit sphere digitized at gridstep 0.125" )
135 {
136
137 const double h = 0.125;
138 auto params = SH3::defaultParameters();
139 params( "polynomial", "sphere1" )( "gridstep", h );
140 params( "minAABB", -2)( "maxAABB", 2)( "offset", 1.0 )( "closed", 1 );
141 auto implicit_shape = SH3::makeImplicitShape3D ( params );
142 auto digitized_shape = SH3::makeDigitizedImplicitShape3D( implicit_shape, params );
143 auto K = SH3::getKSpace( params );
144 auto binary_image = SH3::makeBinaryImage(digitized_shape,
146 params );
148 std::vector< Point > lattice_points;
149 auto pointels = SH3::getPointelRange(
surface );
150 for (
auto p : pointels ) lattice_points.push_back(
K.uCoords( p ) );
151
152 const Index nb = lattice_points.size();
155 for (
Index i = 1; i < nb; i++ )
156 {
157 if ( lattice_points[ i ] < lattice_points[ lowest ] ) lowest = i;
158 if ( lattice_points[ uppest ] < lattice_points[ i ] ) uppest = i;
159 }
160
162 TC.init( lattice_points.cbegin(), lattice_points.cend() );
163 auto SP = TC.makeShortestPaths( sqrt(3.0) );
164
165 const double max_discrete_distance = 5.0;
166 const int step = lattice_points.size() / 8;
167 std::size_t sum_nb_visited = 0;
168 std::size_t min_nb_visited = 100000;
169 std::size_t max_nb_visited = 0;
170 int n = 0;
171 for ( auto i = 0; i < lattice_points.size(); i += step, n += 1 )
172 {
173 SP.init( i );
174 std::vector< std::size_t > visited;
175 while ( ! SP.finished() )
176 {
177 auto last = std::get<0>( SP.current() );
178 auto last_distance = std::get<2>( SP.current() );
179 visited.push_back( last );
180 if ( last_distance >= max_discrete_distance ) break;
181 SP.expand();
182 }
183 SP.clearVisited( visited );
184 sum_nb_visited += visited.size();
185 min_nb_visited = std::min( min_nb_visited, visited.size() );
186 max_nb_visited = std::max( max_nb_visited, visited.size() );
187 }
188 double average = sum_nb_visited / (double) n;
189
190
191 REQUIRE( ( average - min_nb_visited ) / average < 0.2 );
192 REQUIRE( ( max_nb_visited - average ) / average < 0.2 );
193 }
194}