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/graph/Expander.h"
46#include "DGtal/io/boards/Board2D.h"
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;
110 double radius = (double) (r + 1);
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;
271 Point p1( -50, -50, -50 );
272 Point p2( 50, 50, 50 );
277 trace.
beginBlock (
"Testing 3D Object instanciation and smart copy ..." );
278 trace.
info() <<
"Creating diamond (r=45)" << endl;
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 ) );
318 vector<ObjectType> objects2;
319 back_insert_iterator< vector< ObjectType > > inserter2( objects2 );
320 const auto nbc0 = objects[ 0 ].border().writeComponents( inserter2 );
326 const auto nbc1 = objects[ 1 ].border().writeComponents( inserter2 );
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() );
349bool testSimplePoints3D()
351 unsigned int nbok = 0;
357 typedef Z3::Point
Point;
368 Point p1( -10, -10, -10 );
369 Point p2( 10, 10, 10 );
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;
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 );
455 double radius = (double) (r + 1);
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 );
483 board << disk_object;
485 board.
saveSVG(
"disk-object.svg");
491 board2 <<
SetMode( disk_object.className(),
"DrawAdjacencies" ) << disk_object;
493 board2.
saveSVG(
"disk-object-adj.svg");
499 board3 <<
SetMode( disk_object2.className(),
"DrawAdjacencies" ) << disk_object2;
501 board3.
saveSVG(
"disk-object-adj-bis.svg");
513int 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;
Aim: This class specializes a 'Board' class so as to display DGtal objects more naturally (with <<)....
Aim: A wrapper class around a STL associative container for storing sets of digital points within som...
Container::const_iterator ConstIterator
ConstIterator type of the container;.
Aim: Represents a digital topology as a couple of adjacency relations.
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.
Iterator for HyperRectDomain.
Aim: Parallelepidec region of a digital space, model of a 'CDomain'.
const ConstIterator & begin() const
std::string className() const
const ConstIterator & end() const
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...
const DigitalSet & pointSet() const
SmallObject properNeighborhood(const Point &p) const
SmallObject neighborhood(const Point &p) const
void beginBlock(const std::string &keyword="")
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
HyperRectDomain< Space > Domain
Z2i::DigitalSet DigitalSet