34 #include "DGtal/base/Common.h"
35 #include "DGtal/kernel/SpaceND.h"
36 #include "DGtal/kernel/domains/DomainPredicate.h"
37 #include "DGtal/kernel/domains/HyperRectDomain.h"
38 #include "DGtal/kernel/sets/DigitalSetSelector.h"
39 #include "DGtal/kernel/sets/DigitalSetConverter.h"
40 #include "DGtal/topology/MetricAdjacency.h"
41 #include "DGtal/topology/DomainMetricAdjacency.h"
42 #include "DGtal/topology/DomainAdjacency.h"
43 #include "DGtal/topology/DigitalTopology.h"
44 #include "DGtal/topology/Object.h"
45 #include "DGtal/topology/Expander.h"
46 #include "DGtal/io/boards/Board2D.h"
50 using namespace DGtal;
51 using namespace LibBoard;
53 #define INBLOCK_TEST(x) \
54 nbok += ( x ) ? 1 : 0; \
56 trace.info() << "(" << nbok << "/" << nb << ") " \
59 #define INBLOCK_TEST2(x,y) \
60 nbok += ( x ) ? 1 : 0; \
62 trace.info() << "(" << nbok << "/" << nb << ") " \
74 unsigned int nbok = 0;
78 typedef Z2::Point
Point;
79 typedef Point::Coordinate Coordinate;
81 Point p1( -449, -449 );
83 DomainType domain( p1, p2 );
97 typedef ObjectType::SmallSet SmallSet;
99 typedef ObjectType::Size Size;
105 Adj4 adj4( domain, madj4 );
106 Adj8 adj8( domain, madj8 );
107 DT48 dt48( adj4, adj8, JORDAN_DT );
110 double radius = (double) (r + 1);
113 MediumSet disk( domain );
115 sstr <<
"Creating disk( r < " << radius <<
" ) ...";
117 for ( DomainType::ConstIterator it = domain.begin();
121 if ( (*it - c ).norm() < radius )
123 disk.insertNew( *it );
127 trace.
beginBlock (
"Testing Object instanciation and smart copy ..." );
128 ObjectType disk_object( dt48, disk );
129 nbok += disk_object.size() == 636101 ? 1 : 0;
131 trace.
info() <<
"(" << nbok <<
"/" << nb <<
") "
132 <<
"Disk (r=450.0) " << disk_object << std::endl;
133 trace.
info() <<
" size=" << disk_object.size() << std::endl;
134 ObjectType disk_object2( disk_object );
135 nbok += disk_object2.size() == 636101 ? 1 : 0;
137 trace.
info() <<
"(" << nbok <<
"/" << nb <<
") "
138 <<
"Disk2 (r=450.0) " << disk_object2 << std::endl;
139 trace.
info() <<
" size=" << disk_object2.size() << std::endl;
143 trace.
info() <<
"Removing center point in Disk." << std::endl;
144 disk_object.pointSet().erase( c );
145 disk_object2.pointSet().insert( c );
146 nbok += disk_object.size() == 636100 ? 1 : 0;
148 trace.
info() <<
"(" << nbok <<
"/" << nb <<
") "
149 <<
"Disk - c (r=450.0) " << disk_object << std::endl;
150 trace.
info() <<
" size=" << disk_object.size() << std::endl;
151 nbok += disk_object2.size() == 636101 ? 1 : 0;
153 trace.
info() <<
"(" << nbok <<
"/" << nb <<
") "
154 <<
"Disk2 + c (r=450.0) " << disk_object2 << std::endl;
155 trace.
info() <<
" size=" << disk_object2.size() << std::endl;
160 nbok += neigh.
size() == 4 ? 1 : 0;
162 trace.
info() <<
"(" << nbok <<
"/" << nb <<
") "
163 <<
"N_4(Disk, c).size() = " << neigh.
size()
164 <<
" == 4" << std::endl;
166 nbok += neigh.
size() == 3 ? 1 : 0;
168 trace.
info() <<
"(" << nbok <<
"/" << nb <<
") "
169 <<
"N*_4(Disk, " << l <<
").size() = " << neigh.
size()
170 <<
" == 3" << std::endl;
171 Size size = disk_object.properNeighborhoodSize( l );
172 nbok += size == 3 ? 1 : 0;
174 trace.
info() <<
"(" << nbok <<
"/" << nb <<
") "
175 <<
"#N*_4(Disk, " << l <<
") = " << size
176 <<
" == 3" << std::endl;
179 nbok += neigh.
size() == 5 ? 1 : 0;
181 trace.
info() <<
"(" << nbok <<
"/" << nb <<
") "
182 <<
"N_4(Disk2, c).size() = " << neigh.
size()
183 <<
" == 5" << std::endl;
188 ( neigh.
pointSet(), disk_object.pointSet() );
189 nbok += neigh.
size() == 636100 ? 1 : 0;
191 trace.
info() <<
"(" << nbok <<
"/" << nb <<
") "
192 <<
"neigh = disk_object, size() = " << neigh.
size()
193 <<
" == 636100" << std::endl;
194 SmallObjectType neigh2 = disk_object2.neighborhood( c );
196 ( neigh.
pointSet(), neigh2.pointSet() );
197 nbok += neigh.
size() == 5 ? 1 : 0;
199 trace.
info() <<
"(" << nbok <<
"/" << nb <<
") "
200 <<
"neigh = N_4(Disk2, c), size() = " << neigh.
size()
201 <<
" == 5" << std::endl;
205 ObjectType bdisk = disk_object.border();
206 nbok += bdisk.size() == 3372 ? 1 : 0;
208 trace.
info() <<
"(" << nbok <<
"/" << nb <<
") "
209 <<
"Border(Disk, c), size() = " << bdisk.size()
210 <<
" == 3372" << std::endl;
211 ObjectType bdisk2 = disk_object2.border();
212 nbok += bdisk2.size() == 3364 ? 1 : 0;
214 trace.
info() <<
"(" << nbok <<
"/" << nb <<
") "
215 <<
"Border(Disk2, c), size() = " << bdisk2.size()
216 <<
" == 3364" << std::endl;
219 trace.
beginBlock (
"Testing expansion by layers on the boundary ..." );
221 ObjectExpander expander( bdisk, *(bdisk.pointSet().begin()) );
222 while ( ! expander.finished() )
224 nbok += expander.layer().size() <= 2 ? 1 : 0;
226 trace.
info() <<
"(" << nbok <<
"/" << nb <<
") "
227 <<
"expander.layer.size() <= 2 "
228 << expander << std::endl;
229 expander.nextLayer();
233 trace.
beginBlock (
"Testing expansion by layers on the disk from center..." );
234 ObjectExpander expander2( disk_object2, c );
235 while ( ! expander2.finished() )
238 expander2.nextLayer();
240 nbok += expander2.distance() <= sqrt(2.0) * radius ? 1 : 0;
242 trace.
info() <<
"(" << nbok <<
"/" << nb <<
") "
243 <<
"expander.distance() = " << expander2.distance()
244 <<
" <= " << sqrt(2.0)*radius << std::endl;
256 unsigned int nbok = 0;
262 typedef Z3::Point Point;
264 typedef Domain::ConstIterator DomainConstIterator;
269 DT6_18 dt6_18( adj6, adj18, JORDAN_DT );
271 Point p1( -50, -50, -50 );
272 Point p2( 50, 50, 50 );
273 Domain domain( p1, p2 );
277 trace.
beginBlock (
"Testing 3D Object instanciation and smart copy ..." );
278 trace.
info() <<
"Creating diamond (r=45)" << endl;
280 DigitalSet diamond_set( domain );
281 for ( DomainConstIterator it = domain.begin(); it != domain.end(); ++it )
283 if ( (*it - c ).norm1() <= 45 )
284 diamond_set.insertNew( *it );
286 ObjectType diamond( dt6_18, diamond_set );
287 trace.
info() <<
"Cloning diamond" << endl;
289 ObjectType diamond_clone( diamond );
291 trace.
info() <<
"Removing two points " << c <<
" and " << d << endl;
292 diamond_clone.pointSet().erase( c );
293 diamond_clone.pointSet().erase( d );
295 trace.
info() <<
"Inserting into vector<Object>" << endl;
296 vector<ObjectType> objects;
297 back_insert_iterator< vector< ObjectType > > inserter( objects );
298 *inserter++ = diamond;
299 *inserter++ = diamond_clone;
301 for ( vector<ObjectType>::const_iterator it = objects.begin();
304 trace.
info() <<
"- objects[" << (it - objects.begin() ) <<
"]"
305 <<
" = " << *it << endl;
307 INBLOCK_TEST( objects[ 0 ].size() == ( objects[ 1 ].size() + 2 ) );
308 INBLOCK_TEST( objects[ 0 ].size() == 125671 );
318 vector<ObjectType> objects2;
319 back_insert_iterator< vector< ObjectType > > inserter2( objects2 );
320 unsigned int nbc0 = objects[ 0 ].border().writeComponents( inserter2 );
321 INBLOCK_TEST( nbc0 == 1 );
322 INBLOCK_TEST( objects[ 0 ].computeConnectedness() == CONNECTED );
326 unsigned int nbc1 = objects[ 1 ].border().writeComponents( inserter2 );
327 INBLOCK_TEST( nbc1 == 3 );
329 for ( vector<ObjectType>::const_iterator it = objects2.begin();
330 it != objects2.end();
332 trace.
info() <<
"- objects2[" << (it - objects2.begin() ) <<
"]"
333 <<
" = " << *it << endl;
334 INBLOCK_TEST( objects2[ 0 ].size() == objects2[ 1 ].size() );
335 INBLOCK_TEST( objects2[ 2 ].size() == objects2[ 3 ].size() );
336 INBLOCK_TEST( objects2[ 0 ].size() == 15848 );
337 INBLOCK_TEST( objects2[ 2 ].size() == 18 );
349 bool testSimplePoints3D()
351 unsigned int nbok = 0;
357 typedef Z3::Point Point;
359 typedef Domain::ConstIterator DomainConstIterator;
366 DT6_18 dt6_18( adj6, adj18, JORDAN_DT );
368 Point p1( -10, -10, -10 );
369 Point p2( 10, 10, 10 );
370 Domain domain( p1, p2 );
376 DigitalSet diamond_set( domain );
377 for ( DomainConstIterator it = domain.begin(); it != domain.end(); ++it )
379 if ( (*it - c ).norm1() <= 3 )
380 diamond_set.insertNew( *it );
382 diamond_set.erase( c );
383 ObjectType diamond( dt6_18, diamond_set );
387 SmallObjectType geoN6_3 = diamond.geodesicNeighborhood( adj6, r, 3 );
388 SmallObjectType geoN18_2 = diamond.geodesicNeighborhood( adj18, r, 2 );
389 trace.
info() <<
"geoN6_3 = " << geoN6_3 << endl;
390 trace.
info() <<
"geoN18_2 = " << geoN18_2 << endl;
391 SmallComplementObjectType cgeoN6_3 = diamond.geodesicNeighborhoodInComplement( adj6, r, 3 );
392 SmallComplementObjectType cgeoN18_2 = diamond.geodesicNeighborhoodInComplement( adj18, r, 2 );
393 trace.
info() <<
"cgeoN6_3 = " << cgeoN6_3 << endl;
394 trace.
info() <<
"cgeoN18_2 = " << cgeoN18_2 << endl;
398 for ( DigitalSet::ConstIterator it = diamond.pointSet().begin();
399 it != diamond.pointSet().end();
402 <<
" " << ( diamond.isSimple( *it ) ?
"Simple" :
"Not simple" )
413 unsigned int nbok = 0;
419 typedef Z2::Point Point;
420 typedef Point::Coordinate Coordinate;
422 Point p1( -10, -10 );
424 DomainType domain( p1, p2 );
441 typedef ObjectType::SmallSet SmallSet;
443 typedef ObjectType::Size Size;
449 Adj4 adj4( domain, madj4 );
450 Adj8 adj8( domain, madj8 );
451 DT48 dt48( adj4, adj8, JORDAN_DT );
452 DT84 dt84( adj8, adj4, JORDAN_DT );
455 double radius = (double) (r + 1);
458 MediumSet disk( domain );
460 sstr <<
"Creating disk( r < " << radius <<
" ) ...";
462 for ( DomainType::ConstIterator it = domain.begin();
466 if ( (*it - c ).norm() < radius )
468 disk.insertNew( *it );
472 trace.
beginBlock (
"Testing Object instanciation and smart copy ..." );
473 ObjectType disk_object( dt48, disk );
474 ObjectType84 disk_object2( dt84, disk );
480 board.
setUnit(Board::UCentimeter);
482 board <<
SetMode( domain.className(),
"Grid" ) << domain;
483 board << disk_object;
485 board.
saveSVG(
"disk-object.svg");
488 board2.
setUnit(Board::UCentimeter);
490 board2 <<
SetMode( domain.className(),
"Grid" ) << domain;
491 board2 <<
SetMode( disk_object.className(),
"DrawAdjacencies" ) << disk_object;
493 board2.
saveSVG(
"disk-object-adj.svg");
496 board3.
setUnit( Board::UCentimeter );
498 board3 <<
SetMode( domain.className(),
"Grid" ) << domain;
499 board3 <<
SetMode( disk_object2.className(),
"DrawAdjacencies" ) << disk_object2;
501 board3.
saveSVG(
"disk-object-adj-bis.svg");
513 int main(
int argc,
char** argv )
517 for (
int i = 0; i < argc; ++i )
521 bool res = testObject() &&
522 testObject3D() && testDraw()
523 && testSimplePoints3D();
525 trace.
emphase() << ( res ?
"Passed." :
"Error." ) << endl;