DGtal 1.4.0
Loading...
Searching...
No Matches
testDigitalSet.cpp
Go to the documentation of this file.
1
37#include <cstdio>
38#include <cmath>
39#include <iostream>
40#include <fstream>
41#include <algorithm>
42#include <string>
43#include <unordered_set>
44
45#include "DGtal/base/Common.h"
46#include "DGtal/kernel/SpaceND.h"
47#include "DGtal/kernel/domains/HyperRectDomain.h"
48#include "DGtal/kernel/sets/CDigitalSet.h"
49#include "DGtal/kernel/sets/CDigitalSetArchetype.h"
50#include "DGtal/kernel/domains/CDomain.h"
51#include "DGtal/kernel/domains/CDomainArchetype.h"
52#include "DGtal/kernel/sets/DigitalSetBySTLVector.h"
53#include "DGtal/kernel/sets/DigitalSetBySTLSet.h"
54#include "DGtal/kernel/sets/DigitalSetByAssociativeContainer.h"
55#include "DGtal/kernel/sets/DigitalSetFromMap.h"
56#include "DGtal/kernel/sets/DigitalSetSelector.h"
57#include "DGtal/kernel/sets/DigitalSetDomain.h"
58#include "DGtal/kernel/sets/DigitalSetInserter.h"
59
60#include "DGtal/images/ImageContainerBySTLMap.h"
61
62#include "DGtal/helpers/StdDefs.h"
63
64#include "DGtal/io/boards/Board2D.h"
65
66#include "DGtal/kernel/PointHashFunctions.h"
67
68
69
70using namespace DGtal;
71using namespace std;
72
73
74#define INBLOCK_TEST(x) \
75 nbok += ( x ) ? 1 : 0; \
76 nb++; \
77 trace.info() << "(" << nbok << "/" << nb << ") " \
78 << #x << std::endl;
79
80#define INBLOCK_TEST2(x,y) \
81 nbok += ( x ) ? 1 : 0; \
82 nb++; \
83 trace.info() << "(" << nbok << "/" << nb << ") " \
84 << y << std::endl;
85
86
87
88struct MyDomainStyleCustomRed : public DrawableWithBoard2D
89{
90 virtual void setStyle(Board2D & aboard) const
91 {
92 aboard.setFillColorRGBi(255, 0, 0);
93 aboard.setPenColorRGBi(0, 255, 0);
94 }
95};
96
97
99{
100 typedef SpaceND<2> Z2;
102 typedef Z2::Point Point;
103 Point p1( -10, -10 );
104 Point p2( 10, 10 );
105 Domain domain( p1, p2 );
107
108 BOOST_CONCEPT_ASSERT(( concepts::CDigitalSet< SpecificSet > ));
109
110 SpecificSet mySet( domain );
111
112 Point c( 0, 0 );
113 mySet.insert( c );
114 Point d( 5, 2 );
115 mySet.insert( d );
116 Point e( 1, -3 );
117 mySet.insert( e );
118
119 Board2D board;
121 board << mySet;
122 board.saveSVG("myset-export.svg");
123
124 board.clear();
125
127 board << SetMode( domain.className(), "Grid" ) << domain << mySet;
128 board.saveSVG("simpleSet-grid.svg");
129
130 board.clear();
131
133 board << SetMode( domain.className(), "Paving" ) << domain;
134 board << mySet;
135 board.saveSVG("simpleSet-paving.svg");
136
137
138 board.clear();
139
141 board << CustomStyle( mySet.className(), new MyDomainStyleCustomRed );
142 board << mySet;
143 board.saveSVG("simpleSet-color.svg");
144
145 return true;
146}
147
148template < typename DigitalSetType >
149bool testDigitalSet( const DigitalSetType& aSet1, const DigitalSetType& aSet2 )
150{
151 BOOST_CONCEPT_ASSERT(( concepts::CDigitalSet< DigitalSetType > ));
152
153 typedef typename DigitalSetType::Domain Domain;
154 typedef typename Domain::Point Point;
155 typedef typename Point::Coordinate Coordinate;
156 unsigned int nbok = 0;
157 unsigned int nb = 0;
158
159 //copy, size/empty
160 DigitalSetType set1( aSet1 );
161 nbok += ( (set1.size() == 0)&&(set1.empty()) ) ? 1 : 0;
162 nb++;
163 trace.info() << "(" << nbok << "/" << nb << ") "
164 << "Empty set: " << set1 << std::endl;
165
166 //insertion
167 std::set<Point> v;
168 Coordinate t [] = { 4, 3, 3 , 4};
169 Coordinate t2[] = { 2, 5, 3 , 5};
170 Coordinate t3[] = { 2, 5, 3 , 4} ;
171 Point a( t );
172 Point b( t2 );
173 Point c( t3 );
174 v.insert( a );
175 v.insert( b );
176 v.insert( c );
177
178 set1.insert( a );
179 set1.insert( b );
180 set1.insertNew( c );
181 set1.insert( b );
182 nbok += set1.size() == 3 ? 1 : 0;
183 nb++;
184 trace.info() << "(" << nbok << "/" << nb << ") "
185 << "Insertion (3 elements): " << set1 << std::endl;
186
187 //iterate
188 bool flag = true;
189 for (typename DigitalSetType::Iterator it = set1.begin();
190 it != set1.end(); ++it)
191 {
192 if (v.find( *it ) == v.end())
193 flag = false;
194 }
195 nbok += (flag) ? 1 : 0;
196 nb++;
197 trace.info() << "Iterate: (" << nbok << "/" << nb << ") "
198 << std::endl;
199
200 // access to underlying container
201 auto & container = set1.container();
202 (void)container; // remove unused warning
203
204 //erasure
205 set1.erase( b );
206 nbok += ( (set1.size() == 2)
207 &&(set1.find( b ) == set1.end()) )? 1 : 0;
208 nb++;
209 trace.info() << "(" << nbok << "/" << nb << ") "
210 << "Erase one element by key (2 remain): " << set1 << std::endl;
211
212 typename DigitalSetType::Iterator it = set1.find( c );
213 set1.erase( it );
214 nbok += ( (set1.size() == 1)
215 &&(set1.find( c ) == set1.end()) )? 1 : 0;
216 nb++;
217 trace.info() << "(" << nbok << "/" << nb << ") "
218 << "Erase one element by iterator (1 remain): " << set1 << std::endl;
219
220 //other sets
221 DigitalSetType set2( aSet2 );
223 set1.computeComplement(inserter);
224 nbok += (set2.size() == (set2.domain().size()-1))? 1 : 0;
225 nb++;
226 trace.info() << "(" << nbok << "/" << nb << ") "
227 << "Complement: " << set2 << std::endl;
228
229 set2 += set1;
230 nbok += (set2.size() == (set2.domain().size()))? 1 : 0;
231 nb++;
232 trace.info() << "(" << nbok << "/" << nb << ") "
233 << "Union: " << set2 << std::endl;
234
235 //clear
236 set1.clear();
237 nbok += ( (set1.size() == 0)&&(set1.empty()) ) ? 1 : 0;
238 nb++;
239 trace.info() << "(" << nbok << "/" << nb << ") "
240 << "Cleared set: " << set1 << std::endl;
241
242 set1.assignFromComplement(set2); //remains empty
243 nbok += ( (set1.size() == 0)&&(set1.empty()) ) ? 1 : 0;
244 nb++;
245 trace.info() << "(" << nbok << "/" << nb << ") "
246 << std::endl;
247
248 return nbok == nb;
249}
250
251template < typename DigitalDomain, int props >
252bool testDigitalSetSelector( const DigitalDomain & domain,
253 const std::string & comment )
254{
255 unsigned int nbok = 0;
256 unsigned int nb = 0;
257
258 trace.beginBlock ( "Test DigitalSetSelector( " + comment + ")." );
259
260 typedef typename DigitalSetSelector
261 < DigitalDomain, props >::Type SpecificSet;
262 SpecificSet set1( domain );
263 set1.insert( domain.lowerBound() );
264 set1.insert( domain.upperBound() );
265 nbok += set1.size() == 2 ? 1 : 0;
266 nb++;
267 trace.info() << "(" << nbok << "/" << nb << ") "
268 << comment << " (2 elements): " << set1 << std::endl;
269
270 trace.endBlock();
271
272
273 return nbok == nb;
274}
275
277{
278 unsigned int nbok = 0;
279 unsigned int nb = 0;
280
281 typedef SpaceND<2> Z2;
283 typedef Z2::Point Point;
284 Point p1( -10, -10 );
285 Point p2( 10, 10 );
286 Domain domain( p1, p2 );
287 typedef DigitalSetSelector
288 < Domain, BIG_DS + HIGH_ITER_DS + HIGH_BEL_DS >::Type SpecificSet;
289
290 BOOST_CONCEPT_ASSERT(( concepts::CDigitalSet< SpecificSet > ));
291 SpecificSet disk( domain );
292 Point c( 0, 0 );
293
294 trace.beginBlock ( "Creating disk( r=5.0 ) ..." );
296 it != domain.end();
297 ++it )
298 {
299 if ( (*it - c ).norm() < 5.0 )
300 // insertNew is very important for vector container.
301 disk.insertNew( *it );
302 }
303
304 //Board export test
305 trace.beginBlock("SVG Export");
306 Board2D board;
307 board << SetMode( domain.className(), "Grid" ) << domain;
308 board << disk;
309
310 board.scale(10);
311 board.saveSVG( "disk-set.svg" );
312 trace.endBlock();
313
314 return nbok == nb;
315}
316
318{
319 unsigned int nbok = 0;
320 unsigned int nb = 0;
321
322 typedef SpaceND<2> Z2;
324 typedef Z2::Point Point;
325 Point p1( -49, -49 );
326 Point p2( 49, 49 );
327 Domain domain( p1, p2 );
328 typedef DigitalSetSelector
329 < Domain, BIG_DS + HIGH_ITER_DS + HIGH_BEL_DS >::Type SpecificSet;
330 BOOST_CONCEPT_ASSERT(( concepts::CDigitalSet< SpecificSet > ));
331
332 SpecificSet disk( domain );
333 Point c( 0, 0 );
334 Point l( 49, 0 );
335
336 trace.beginBlock ( "Creating disk( r=50.0 ) ..." );
338 it != domain.end();
339 ++it )
340 {
341 if ( (*it - c ).norm() < 50.0 )
342 // insertNew is very important for vector container.
343 disk.insertNew( *it );
344 }
345 disk.erase( c );
346 INBLOCK_TEST( disk.size() == 7824 );
347 trace.info() << "disk.size()=" << disk.size() << std::endl;
348 trace.endBlock();
349
350 typedef DigitalSetDomain< SpecificSet > RestrictedDomain;
351 BOOST_CONCEPT_ASSERT(( concepts::CDomain< RestrictedDomain > ));
352
353 RestrictedDomain disk_domain( disk );
354 trace.beginBlock ( "Iterating over disk domain ..." );
355 unsigned int nb_in_domain = 0;
356 for ( RestrictedDomain::ConstIterator it = disk_domain.begin();
357 it != disk_domain.end();
358 ++it )
359 {
360 ++nb_in_domain;
361 }
362 INBLOCK_TEST( nb_in_domain == 7824 );
363 INBLOCK_TEST( disk_domain.lowerBound() == Point( -49, -49 ) );
364 INBLOCK_TEST( disk_domain.upperBound() == Point( 49, 49 ) );
365 trace.endBlock();
366
367 return nbok == nb;
368}
369
371{
372 BOOST_CONCEPT_ASSERT(( concepts::CDigitalSet<Z2i::DigitalSet> ));
373 BOOST_CONCEPT_ASSERT(( concepts::CDigitalSet<Z3i::DigitalSet> ));
374
375 typedef Z2i::Space Space;
376 BOOST_CONCEPT_ASSERT(( concepts::CDomain< concepts::CDomainArchetype< Space > > ));
377 typedef concepts::CDigitalSetArchetype<Z2i::Domain> DigitalSetArchetype;
378 BOOST_CONCEPT_ASSERT(( concepts::CDigitalSet<DigitalSetArchetype> ));
379
380 return true;
381}
382
383int main()
384{
385 typedef SpaceND<4> Space4Type;
387 typedef Space4Type::Point Point;
388
389 Space4Type::Integer t[] = { 1, 2, 3 , 4};
390 Point a ( t );
391 Space4Type::Integer t2[] = { 5, 5, 3 , 5};
392 Point b ( t2);
393 trace.beginBlock ( "HyperRectDomain init" );
394
396 Domain domain ( a, b );
397 trace.info() << domain << std::endl;
398 trace.info() << "Domain size= " << domain.size() << std::endl;
399 trace.endBlock();
400
401 trace.beginBlock( "DigitalSetBySTLVector" );
404 trace.endBlock();
405
406 trace.beginBlock( "DigitalSetBySTLSet" );
409 trace.endBlock();
410
411 trace.beginBlock( "DigitalSetFromMap" );
413 Map map(domain); Map map2(domain); //maps
414 DigitalSetFromMap<Map> setFromMap(map); //sets from these maps
415 DigitalSetFromMap<Map> setFromMap2(map2);
416 bool okMap = testDigitalSet< DigitalSetFromMap<Map> >( setFromMap, setFromMap2 );
417 trace.endBlock();
418
419 trace.beginBlock( "DigitalSetByAssociativeContainer" );
420 typedef std::set<Point> Container;
423 trace.endBlock();
424
425 trace.beginBlock( "DigitalSetByUnorderedSet" );
426 typedef std::unordered_set<Point> ContainerU;
429 trace.endBlock();
430
431 bool okSelectorSmall = testDigitalSetSelector
433 ( domain, "Small set" );
434
435 bool okSelectorBig = testDigitalSetSelector
437 ( domain, "Big set" );
438
439 bool okSelectorMediumHBel = testDigitalSetSelector
441 ( domain, "Medium set + High belonging test" );
442
443 bool okDigitalSetDomain = testDigitalSetDomain();
444
445 bool okDigitalSetDraw = testDigitalSetDraw();
446
447 bool okDigitalSetDrawSnippet = testDigitalSetBoardSnippet();
448
449 bool res = okVector && okSet && okMap
450 && okSelectorSmall && okSelectorBig && okSelectorMediumHBel
451 && okDigitalSetDomain && okDigitalSetDraw && okDigitalSetDrawSnippet
452 && okUnorderedSet && okAssoctestSet;
453 trace.endBlock();
454 trace.emphase() << ( res ? "Passed." : "Error." ) << endl;
455 return res ? 0 : 1;
456}
457
Aim: This class specializes a 'Board' class so as to display DGtal objects more naturally (with <<)....
Definition Board2D.h:71
Aim: A wrapper class around a STL associative container for storing sets of digital points within som...
Aim: A container class for storing sets of digital points within some given domain.
Aim: Realizes the concept CDigitalSet by using the STL container std::vector.
Aim: Constructs a domain limited to the given digital set.
Aim: An adapter for viewing an associative image container like ImageContainerBySTLMap as a simple di...
Aim: this output iterator class is designed to allow algorithms to insert points in the digital set....
Aim: Parallelepidec region of a digital space, model of a 'CDomain'.
const ConstIterator & begin() const
const Point & lowerBound() const
const Point & upperBound() const
std::string className() const
const ConstIterator & end() const
void beginBlock(const std::string &keyword="")
std::ostream & emphase()
std::ostream & info()
double endBlock()
Aim: The archetype of a container class for storing sets of digital points within some given domain.
Aim: The archetype of a class that represents a digital domain, i.e. a non mutable subset of points o...
Board & setPenColorRGBi(unsigned char red, unsigned char green, unsigned char blue, unsigned char alpha=255)
Definition Board.cpp:277
void clear(const DGtal::Color &color=DGtal::Color::None)
Definition Board.cpp:151
Board & setFillColorRGBi(unsigned char red, unsigned char green, unsigned char blue, unsigned char alpha=255)
Definition Board.cpp:304
void saveSVG(const char *filename, PageSize size=Board::BoundingBox, double margin=10.0) const
Definition Board.cpp:1011
void setUnit(Unit unit)
Definition Board.cpp:239
Shape & scale(double sx, double sy)
Definition Board.cpp:183
DGtal is the top-level namespace which contains all DGtal functions and types.
Trace trace
Definition Common.h:153
STL namespace.
Aim: Automatically defines an adequate digital set type according to the hints given by the user.
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....
Definition Board2D.h:247
Aim: Represents a set of points within the given domain. This set of points is modifiable by the user...
Aim: This concept represents a digital domain, i.e. a non mutable subset of points of the given digit...
Definition CDomain.h:130
MyPointD Point
std::unordered_map< Cell, CubicalCellData > Map
bool testDigitalSetDomain()
bool testDigitalSetConcept()
bool testDigitalSet(const DigitalSetType &aSet1, const DigitalSetType &aSet2)
bool testDigitalSetDraw()
#define INBLOCK_TEST(x)
int main()
bool testDigitalSetBoardSnippet()
bool testDigitalSetSelector(const DigitalDomain &domain, const std::string &comment)
Domain domain
HyperRectDomain< Space > Domain