DGtal  0.9.3
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 
70 using namespace DGtal;
71 using 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 
88 struct 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;
101  typedef HyperRectDomain<Z2> Domain;
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 
148 template < typename DigitalSetType >
149 bool 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  //erasure
201  set1.erase( b );
202  nbok += ( (set1.size() == 2)
203  &&(set1.find( b ) == set1.end()) )? 1 : 0;
204  nb++;
205  trace.info() << "(" << nbok << "/" << nb << ") "
206  << "Erase one element by key (2 remain): " << set1 << std::endl;
207 
208  typename DigitalSetType::Iterator it = set1.find( c );
209  set1.erase( it );
210  nbok += ( (set1.size() == 1)
211  &&(set1.find( c ) == set1.end()) )? 1 : 0;
212  nb++;
213  trace.info() << "(" << nbok << "/" << nb << ") "
214  << "Erase one element by iterator (1 remain): " << set1 << std::endl;
215 
216  //other sets
217  DigitalSetType set2( aSet2 );
218  DigitalSetInserter<DigitalSetType> inserter(set2);
219  set1.computeComplement(inserter);
220  nbok += (set2.size() == (set2.domain().size()-1))? 1 : 0;
221  nb++;
222  trace.info() << "(" << nbok << "/" << nb << ") "
223  << "Complement: " << set2 << std::endl;
224 
225  set2 += set1;
226  nbok += (set2.size() == (set2.domain().size()))? 1 : 0;
227  nb++;
228  trace.info() << "(" << nbok << "/" << nb << ") "
229  << "Union: " << set2 << std::endl;
230 
231  //clear
232  set1.clear();
233  nbok += ( (set1.size() == 0)&&(set1.empty()) ) ? 1 : 0;
234  nb++;
235  trace.info() << "(" << nbok << "/" << nb << ") "
236  << "Cleared set: " << set1 << std::endl;
237 
238  set1.assignFromComplement(set2); //remains empty
239  nbok += ( (set1.size() == 0)&&(set1.empty()) ) ? 1 : 0;
240  nb++;
241  trace.info() << "(" << nbok << "/" << nb << ") "
242  << std::endl;
243 
244  return nbok == nb;
245 }
246 
247 template < typename DigitalDomain, int props >
248 bool testDigitalSetSelector( const DigitalDomain & domain,
249  const std::string & comment )
250 {
251  unsigned int nbok = 0;
252  unsigned int nb = 0;
253 
254  trace.beginBlock ( "Test DigitalSetSelector( " + comment + ")." );
255 
256  typedef typename DigitalSetSelector
257  < DigitalDomain, props >::Type SpecificSet;
258  SpecificSet set1( domain );
259  set1.insert( domain.lowerBound() );
260  set1.insert( domain.upperBound() );
261  nbok += set1.size() == 2 ? 1 : 0;
262  nb++;
263  trace.info() << "(" << nbok << "/" << nb << ") "
264  << comment << " (2 elements): " << set1 << std::endl;
265 
266  trace.endBlock();
267 
268 
269  return nbok == nb;
270 }
271 
273 {
274  unsigned int nbok = 0;
275  unsigned int nb = 0;
276 
277  typedef SpaceND<2> Z2;
278  typedef HyperRectDomain<Z2> Domain;
279  typedef Z2::Point Point;
280  Point p1( -10, -10 );
281  Point p2( 10, 10 );
282  Domain domain( p1, p2 );
283  typedef DigitalSetSelector
284  < Domain, BIG_DS + HIGH_ITER_DS + HIGH_BEL_DS >::Type SpecificSet;
285 
286  BOOST_CONCEPT_ASSERT(( concepts::CDigitalSet< SpecificSet > ));
287  SpecificSet disk( domain );
288  Point c( 0, 0 );
289 
290  trace.beginBlock ( "Creating disk( r=5.0 ) ..." );
291  for ( Domain::ConstIterator it = domain.begin();
292  it != domain.end();
293  ++it )
294  {
295  if ( (*it - c ).norm() < 5.0 )
296  // insertNew is very important for vector container.
297  disk.insertNew( *it );
298  }
299 
300  //Board export test
301  trace.beginBlock("SVG Export");
302  Board2D board;
303  board << SetMode( domain.className(), "Grid" ) << domain;
304  board << disk;
305 
306  board.scale(10);
307  board.saveSVG( "disk-set.svg" );
308  trace.endBlock();
309 
310  return nbok == nb;
311 }
312 
314 {
315  unsigned int nbok = 0;
316  unsigned int nb = 0;
317 
318  typedef SpaceND<2> Z2;
319  typedef HyperRectDomain<Z2> Domain;
320  typedef Z2::Point Point;
321  Point p1( -49, -49 );
322  Point p2( 49, 49 );
323  Domain domain( p1, p2 );
324  typedef DigitalSetSelector
325  < Domain, BIG_DS + HIGH_ITER_DS + HIGH_BEL_DS >::Type SpecificSet;
326  BOOST_CONCEPT_ASSERT(( concepts::CDigitalSet< SpecificSet > ));
327 
328  SpecificSet disk( domain );
329  Point c( 0, 0 );
330  Point l( 49, 0 );
331 
332  trace.beginBlock ( "Creating disk( r=50.0 ) ..." );
333  for ( Domain::ConstIterator it = domain.begin();
334  it != domain.end();
335  ++it )
336  {
337  if ( (*it - c ).norm() < 50.0 )
338  // insertNew is very important for vector container.
339  disk.insertNew( *it );
340  }
341  disk.erase( c );
342  INBLOCK_TEST( disk.size() == 7824 );
343  trace.info() << "disk.size()=" << disk.size() << std::endl;
344  trace.endBlock();
345 
346  typedef DigitalSetDomain< SpecificSet > RestrictedDomain;
347  BOOST_CONCEPT_ASSERT(( concepts::CDomain< RestrictedDomain > ));
348 
349  RestrictedDomain disk_domain( disk );
350  trace.beginBlock ( "Iterating over disk domain ..." );
351  unsigned int nb_in_domain = 0;
352  for ( RestrictedDomain::ConstIterator it = disk_domain.begin();
353  it != disk_domain.end();
354  ++it )
355  {
356  ++nb_in_domain;
357  }
358  INBLOCK_TEST( nb_in_domain == 7824 );
359  INBLOCK_TEST( disk_domain.lowerBound() == Point( -49, -49 ) );
360  INBLOCK_TEST( disk_domain.upperBound() == Point( 49, 49 ) );
361  trace.endBlock();
362 
363  return nbok == nb;
364 }
365 
367 {
368  BOOST_CONCEPT_ASSERT(( concepts::CDigitalSet<Z2i::DigitalSet> ));
369  BOOST_CONCEPT_ASSERT(( concepts::CDigitalSet<Z3i::DigitalSet> ));
370 
371  typedef Z2i::Space Space;
372  BOOST_CONCEPT_ASSERT(( concepts::CDomain< concepts::CDomainArchetype< Space > > ));
373  typedef concepts::CDigitalSetArchetype<Z2i::Domain> DigitalSetArchetype;
374  BOOST_CONCEPT_ASSERT(( concepts::CDigitalSet<DigitalSetArchetype> ));
375 
376  return true;
377 }
378 
379 int main()
380 {
381  typedef SpaceND<4> Space4Type;
383  typedef Space4Type::Point Point;
384 
385  Space4Type::Integer t[] = { 1, 2, 3 , 4};
386  Point a ( t );
387  Space4Type::Integer t2[] = { 5, 5, 3 , 5};
388  Point b ( t2);
389  trace.beginBlock ( "HyperRectDomain init" );
390 
392  Domain domain ( a, b );
393  trace.info() << domain << std::endl;
394  trace.info() << "Domain size= " << domain.size() << std::endl;
395  trace.endBlock();
396 
397  trace.beginBlock( "DigitalSetBySTLVector" );
398  bool okVector = testDigitalSet< DigitalSetBySTLVector<Domain> >
400  trace.endBlock();
401 
402  trace.beginBlock( "DigitalSetBySTLSet" );
403  bool okSet = testDigitalSet< DigitalSetBySTLSet<Domain> >
405  trace.endBlock();
406 
407  trace.beginBlock( "DigitalSetFromMap" );
409  Map map(domain); Map map2(domain); //maps
410  DigitalSetFromMap<Map> setFromMap(map); //sets from these maps
411  DigitalSetFromMap<Map> setFromMap2(map2);
412  bool okMap = testDigitalSet< DigitalSetFromMap<Map> >( setFromMap, setFromMap2 );
413  trace.endBlock();
414 
415  trace.beginBlock( "DigitalSetByAssociativeContainer" );
416  typedef std::set<Point> Container;
417  bool okAssoctestSet = testDigitalSet< DigitalSetByAssociativeContainer<Domain,Container> >
419  trace.endBlock();
420 
421  trace.beginBlock( "DigitalSetByUnorderedSet" );
422  typedef std::unordered_set<Point> ContainerU;
423  bool okUnorderedSet = testDigitalSet< DigitalSetByAssociativeContainer<Domain,ContainerU> >
425  trace.endBlock();
426 
427  bool okSelectorSmall = testDigitalSetSelector
429  ( domain, "Small set" );
430 
431  bool okSelectorBig = testDigitalSetSelector
433  ( domain, "Big set" );
434 
435  bool okSelectorMediumHBel = testDigitalSetSelector
437  ( domain, "Medium set + High belonging test" );
438 
439  bool okDigitalSetDomain = testDigitalSetDomain();
440 
441  bool okDigitalSetDraw = testDigitalSetDraw();
442 
443  bool okDigitalSetDrawSnippet = testDigitalSetBoardSnippet();
444 
445  bool res = okVector && okSet && okMap
446  && okSelectorSmall && okSelectorBig && okSelectorMediumHBel
447  && okDigitalSetDomain && okDigitalSetDraw && okDigitalSetDrawSnippet
448  && okUnorderedSet && okAssoctestSet;
449  trace.endBlock();
450  trace.emphase() << ( res ? "Passed." : "Error." ) << endl;
451  return res ? 0 : 1;
452 }
453 
void beginBlock(const std::string &keyword="")
const ConstIterator & end() const
bool testDigitalSet(const DigitalSetType &aSet1, const DigitalSetType &aSet2)
std::unordered_map< Cell, CubicalCellData > Map
HyperRectDomain< Space > Domain
Aim: An adapter for viewing an associative image container like ImageContainerBySTLMap as a simple di...
Board & setFillColorRGBi(unsigned char red, unsigned char green, unsigned char blue, unsigned char alpha=255)
Definition: Board.cpp:305
const Domain domain(Point(1, 2), Point(6, 5))
MyDigitalSurface::ConstIterator ConstIterator
Trace trace
Definition: Common.h:137
Aim: SpaceND is a utility class that defines the fundamental structure of a Digital Space in ND...
Definition: SpaceND.h:95
Shape & scale(double sx, double sy)
Definition: Board.cpp:184
Aim: The archetype of a class that represents a digital domain, i.e. a non mutable subset of points o...
Aim: Parallelepidec region of a digital space, model of a &#39;CDomain&#39;.
STL namespace.
double endBlock()
bool testDigitalSetBoardSnippet()
void saveSVG(const char *filename, PageSize size=Board::BoundingBox, double margin=10.0) const
Definition: Board.cpp:1012
bool testDigitalSetSelector(const DigitalDomain &domain, const std::string &comment)
bool testDigitalSetDomain()
Aim: This concept represents a digital domain, i.e. a non mutable subset of points of the given digit...
Definition: CDomain.h:129
bool testDigitalSetConcept()
std::ostream & emphase()
Aim: The archetype of a container class for storing sets of digital points within some given domain...
void clear(const DGtal::Color &color=DGtal::Color::None)
Definition: Board.cpp:152
const ConstIterator & begin() const
Aim: Constructs a domain limited to the given digital set.
std::string className() const
DGtal is the top-level namespace which contains all DGtal functions and types.
MyPointD Point
Definition: testClone2.cpp:383
Aim: A wrapper class around a STL associative container for storing sets of digital points within som...
std::ostream & info()
Aim: Automatically defines an adequate digital set type according to the hints given by the user...
Aim: Realizes the concept CDigitalSet by using the STL container std::vector.
Modifier class in a Board2D stream. Useful to choose your own mode for a given class. Realizes the concept CDrawableWithBoard2D.
Definition: Board2D.h:247
Board & setPenColorRGBi(unsigned char red, unsigned char green, unsigned char blue, unsigned char alpha=255)
Definition: Board.cpp:278
Aim: Represents a set of points within the given domain. This set of points is modifiable by the user...
Definition: CDigitalSet.h:138
bool testDigitalSetDraw()
void setUnit(Unit unit)
Definition: Board.cpp:240
Aim: this output iterator class is designed to allow algorithms to insert points in the digital set...
#define INBLOCK_TEST(x)
Aim: A container class for storing sets of digital points within some given domain.
Aim: This class specializes a &#39;Board&#39; class so as to display DGtal objects more naturally (with <<)...
Definition: Board2D.h:70
int main()