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/DomainAdjacency.h"
42#include "DGtal/topology/DigitalTopology.h"
43#include "DGtal/topology/Object.h"
44#include "DGtal/graph/Expander.h"
45#include "DGtal/io/boards/Board2D.h"
52#define INBLOCK_TEST(x) \
53 nbok += ( x ) ? 1 : 0; \
55 trace.info() << "(" << nbok << "/" << nb << ") " \
58#define INBLOCK_TEST2(x,y) \
59 nbok += ( x ) ? 1 : 0; \
61 trace.info() << "(" << nbok << "/" << nb << ") " \
73 unsigned int nbok = 0;
77 typedef Z2::Point
Point;
80 Point p1( -449, -449 );
82 DomainType
domain( p1, p2 );
96 typedef ObjectType::SmallSet SmallSet;
98 typedef ObjectType::Size
Size;
109 double radius = (double) (r + 1);
114 sstr <<
"Creating disk( r < " << radius <<
" ) ...";
115 trace.beginBlock ( sstr.str() );
116 for ( DomainType::ConstIterator it =
domain.begin();
120 if ( (*it - c ).norm() < radius )
122 disk.insertNew( *it );
126 trace.beginBlock (
"Testing Object instanciation and smart copy ..." );
127 ObjectType disk_object( dt48, disk );
128 nbok += disk_object.size() == 636101 ? 1 : 0;
130 trace.info() <<
"(" << nbok <<
"/" << nb <<
") "
131 <<
"Disk (r=450.0) " << disk_object << std::endl;
132 trace.info() <<
" size=" << disk_object.size() << std::endl;
133 ObjectType disk_object2( disk_object );
134 nbok += disk_object2.size() == 636101 ? 1 : 0;
136 trace.info() <<
"(" << nbok <<
"/" << nb <<
") "
137 <<
"Disk2 (r=450.0) " << disk_object2 << std::endl;
138 trace.info() <<
" size=" << disk_object2.size() << std::endl;
141 trace.beginBlock (
"Testing copy on write system ..." );
142 trace.info() <<
"Removing center point in Disk." << std::endl;
143 disk_object.pointSet().erase( c );
144 disk_object2.pointSet().insert( c );
145 nbok += disk_object.size() == 636100 ? 1 : 0;
147 trace.info() <<
"(" << nbok <<
"/" << nb <<
") "
148 <<
"Disk - c (r=450.0) " << disk_object << std::endl;
149 trace.info() <<
" size=" << disk_object.size() << std::endl;
150 nbok += disk_object2.size() == 636101 ? 1 : 0;
152 trace.info() <<
"(" << nbok <<
"/" << nb <<
") "
153 <<
"Disk2 + c (r=450.0) " << disk_object2 << std::endl;
154 trace.info() <<
" size=" << disk_object2.size() << std::endl;
157 trace.beginBlock (
"Testing neighborhoods ..." );
159 nbok += neigh.
size() == 4 ? 1 : 0;
161 trace.info() <<
"(" << nbok <<
"/" << nb <<
") "
162 <<
"N_4(Disk, c).size() = " << neigh.
size()
163 <<
" == 4" << std::endl;
165 nbok += neigh.
size() == 3 ? 1 : 0;
167 trace.info() <<
"(" << nbok <<
"/" << nb <<
") "
168 <<
"N*_4(Disk, " << l <<
").size() = " << neigh.
size()
169 <<
" == 3" << std::endl;
170 Size size = disk_object.properNeighborhoodSize( l );
171 nbok += size == 3 ? 1 : 0;
173 trace.info() <<
"(" << nbok <<
"/" << nb <<
") "
174 <<
"#N*_4(Disk, " << l <<
") = " << size
175 <<
" == 3" << std::endl;
178 nbok += neigh.
size() == 5 ? 1 : 0;
180 trace.info() <<
"(" << nbok <<
"/" << nb <<
") "
181 <<
"N_4(Disk2, c).size() = " << neigh.
size()
182 <<
" == 5" << std::endl;
185 trace.beginBlock (
"Testing set converters ..." );
187 ( neigh.
pointSet(), disk_object.pointSet() );
188 nbok += neigh.
size() == 636100 ? 1 : 0;
190 trace.info() <<
"(" << nbok <<
"/" << nb <<
") "
191 <<
"neigh = disk_object, size() = " << neigh.
size()
192 <<
" == 636100" << std::endl;
193 SmallObjectType neigh2 = disk_object2.neighborhood( c );
195 ( neigh.
pointSet(), neigh2.pointSet() );
196 nbok += neigh.
size() == 5 ? 1 : 0;
198 trace.info() <<
"(" << nbok <<
"/" << nb <<
") "
199 <<
"neigh = N_4(Disk2, c), size() = " << neigh.
size()
200 <<
" == 5" << std::endl;
203 trace.beginBlock (
"Testing border extraction ..." );
204 ObjectType bdisk = disk_object.border();
205 nbok += bdisk.size() == 3372 ? 1 : 0;
207 trace.info() <<
"(" << nbok <<
"/" << nb <<
") "
208 <<
"Border(Disk, c), size() = " << bdisk.size()
209 <<
" == 3372" << std::endl;
210 ObjectType bdisk2 = disk_object2.border();
211 nbok += bdisk2.size() == 3364 ? 1 : 0;
213 trace.info() <<
"(" << nbok <<
"/" << nb <<
") "
214 <<
"Border(Disk2, c), size() = " << bdisk2.size()
215 <<
" == 3364" << std::endl;
218 trace.beginBlock (
"Testing expansion by layers on the boundary ..." );
220 ObjectExpander expander( bdisk, *(bdisk.pointSet().begin()) );
221 while ( ! expander.finished() )
223 nbok += expander.layer().size() <= 2 ? 1 : 0;
225 trace.info() <<
"(" << nbok <<
"/" << nb <<
") "
226 <<
"expander.layer.size() <= 2 "
227 << expander << std::endl;
228 expander.nextLayer();
232 trace.beginBlock (
"Testing expansion by layers on the disk from center..." );
233 ObjectExpander expander2( disk_object2, c );
234 while ( ! expander2.finished() )
236 trace.info() << expander2 << std::endl;
237 expander2.nextLayer();
239 nbok += expander2.distance() <= sqrt(2.0) * radius ? 1 : 0;
241 trace.info() <<
"(" << nbok <<
"/" << nb <<
") "
242 <<
"expander.distance() = " << expander2.distance()
243 <<
" <= " << sqrt(2.0)*radius << std::endl;
255 unsigned int nbok = 0;
261 typedef Z3::Point
Point;
270 Point p1( -50, -50, -50 );
271 Point p2( 50, 50, 50 );
276 trace.beginBlock (
"Testing 3D Object instanciation and smart copy ..." );
277 trace.info() <<
"Creating diamond (r=45)" << endl;
280 for ( DomainConstIterator it =
domain.begin(); it !=
domain.end(); ++it )
282 if ( (*it - c ).norm1() <= 45 )
283 diamond_set.insertNew( *it );
285 ObjectType diamond( dt6_18, diamond_set );
286 trace.info() <<
"Cloning diamond" << endl;
288 ObjectType diamond_clone( diamond );
290 trace.info() <<
"Removing two points " << c <<
" and " << d << endl;
291 diamond_clone.pointSet().erase( c );
292 diamond_clone.pointSet().erase( d );
294 trace.info() <<
"Inserting into vector<Object>" << endl;
295 vector<ObjectType> objects;
296 back_insert_iterator< vector< ObjectType > > inserter( objects );
297 *inserter++ = diamond;
298 *inserter++ = diamond_clone;
300 for ( vector<ObjectType>::const_iterator it = objects.begin();
303 trace.info() <<
"- objects[" << (it - objects.begin() ) <<
"]"
304 <<
" = " << *it << endl;
306 INBLOCK_TEST( objects[ 0 ].size() == ( objects[ 1 ].size() + 2 ) );
310 trace.beginBlock (
"Testing connected component extraction ..." );
316 trace.beginBlock (
"Components of diamond.border() ..." );
317 vector<ObjectType> objects2;
318 back_insert_iterator< vector< ObjectType > > inserter2( objects2 );
319 const auto nbc0 = objects[ 0 ].border().writeComponents( inserter2 );
324 trace.beginBlock (
"Components of diamond_clone.border() ..." );
325 const auto nbc1 = objects[ 1 ].border().writeComponents( inserter2 );
328 for ( vector<ObjectType>::const_iterator it = objects2.begin();
329 it != objects2.end();
331 trace.info() <<
"- objects2[" << (it - objects2.begin() ) <<
"]"
332 <<
" = " << *it << endl;
333 INBLOCK_TEST( objects2[ 0 ].size() == objects2[ 1 ].size() );
334 INBLOCK_TEST( objects2[ 2 ].size() == objects2[ 3 ].size() );
350 unsigned int nbok = 0;
356 typedef Z3::Point
Point;
367 Point p1( -10, -10, -10 );
368 Point p2( 10, 10, 10 );
373 trace.beginBlock (
"Creating Diamond (r=4)" );
376 for ( DomainConstIterator it =
domain.begin(); it !=
domain.end(); ++it )
378 if ( (*it - c ).norm1() <= 3 )
379 diamond_set.insertNew( *it );
381 diamond_set.erase( c );
382 ObjectType diamond( dt6_18, diamond_set );
385 trace.beginBlock (
"Geodesic neighborhoods ..." );
386 SmallObjectType geoN6_3 = diamond.geodesicNeighborhood( adj6, r, 3 );
387 SmallObjectType geoN18_2 = diamond.geodesicNeighborhood( adj18, r, 2 );
388 trace.info() <<
"geoN6_3 = " << geoN6_3 << endl;
389 trace.info() <<
"geoN18_2 = " << geoN18_2 << endl;
390 SmallComplementObjectType cgeoN6_3 = diamond.geodesicNeighborhoodInComplement( adj6, r, 3 );
391 SmallComplementObjectType cgeoN18_2 = diamond.geodesicNeighborhoodInComplement( adj18, r, 2 );
392 trace.info() <<
"cgeoN6_3 = " << cgeoN6_3 << endl;
393 trace.info() <<
"cgeoN18_2 = " << cgeoN18_2 << endl;
396 trace.beginBlock (
"Simple points ..." );
398 it != diamond.pointSet().end();
400 trace.info() <<
"- " << *it
401 <<
" " << ( diamond.isSimple( *it ) ?
"Simple" :
"Not simple" )
412 unsigned int nbok = 0;
415 trace.beginBlock (
"testDraw(): testing drawing commands." );
418 typedef Z2::Point
Point;
421 Point p1( -10, -10 );
423 DomainType
domain( p1, p2 );
454 double radius = (double) (r + 1);
459 sstr <<
"Creating disk( r < " << radius <<
" ) ...";
460 trace.beginBlock ( sstr.str() );
461 for ( DomainType::ConstIterator it =
domain.begin();
465 if ( (*it - c ).norm() < radius )
467 disk.insertNew( *it );
471 trace.beginBlock (
"Testing Object instanciation and smart copy ..." );
472 ObjectType disk_object( dt48, disk );
473 ObjectType84 disk_object2( dt84, disk );
476 trace.beginBlock (
"Testing export as SVG with libboard." );
482 board << disk_object;
484 board.
saveSVG(
"disk-object.svg");
490 board2 <<
SetMode( disk_object.className(),
"DrawAdjacencies" ) << disk_object;
492 board2.
saveSVG(
"disk-object-adj.svg");
498 board3 <<
SetMode( disk_object2.className(),
"DrawAdjacencies" ) << disk_object2;
500 board3.
saveSVG(
"disk-object-adj-bis.svg");
512int main(
int argc,
char** argv )
514 trace.beginBlock (
"Testing class Object" );
515 trace.info() <<
"Args:";
516 for (
int i = 0; i < argc; ++i )
517 trace.info() <<
" " << argv[ i ];
518 trace.info() << endl;
524 trace.emphase() << ( res ?
"Passed." :
"Error." ) << endl;
Aim: This class specializes a 'Board' class so as to display DGtal objects more naturally (with <<)....
Container::const_iterator ConstIterator
Aim: Given a domain and an adjacency, limits the given adjacency to the specified domain for all adja...
Aim: This class is useful to visit an object by adjacencies, layer by layer.
Aim: Parallelepidec region of a digital space, model of a 'CDomain'.
Aim: Describes digital adjacencies in digital spaces that are defined with the 1-norm and the infinit...
Aim: An object (or digital object) represents a set in some digital space associated with a digital t...
Object< ReverseTopology, SmallSet > SmallComplementObject
const DigitalSet & pointSet() const
SmallObject properNeighborhood(const Point &p) const
SmallObject neighborhood(const Point &p) const
Object< DigitalTopology, SmallSet > SmallObject
void saveSVG(const char *filename, PageSize size=Board::BoundingBox, double margin=10.0) const
MetricAdjacency< Space, 1 > Adj4
MetricAdjacency< Space, 2 > Adj8
MetricAdjacency< Space, 2 > Adj18
MetricAdjacency< Space, 1 > Adj6
DigitalTopology< Adj6, Adj18 > DT6_18
DGtal is the top-level namespace which contains all DGtal functions and types.
static void assign(OutputDigitalSet &output, const InputDigitalSet &input)
DigitalSetByAssociativeContainer< Domain, std::unordered_set< typename Domain::Point > > Type
Modifier class in a Board2D stream. Useful to choose your own mode for a given class....
Struct representing a 2D point.
HalfEdgeDataStructure::Size Size
bool testSimplePoints3D()
Z2i::DigitalSet DigitalSet