DGtal  1.5.beta
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  // 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 );
222  DigitalSetInserter<DigitalSetType> inserter(set2);
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 
251 template < typename DigitalDomain, int props >
252 bool 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;
282  typedef HyperRectDomain<Z2> Domain;
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 ) ..." );
295  for ( Domain::ConstIterator it = domain.begin();
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;
323  typedef HyperRectDomain<Z2> Domain;
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 ) ..." );
337  for ( Domain::ConstIterator it = domain.begin();
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 
383 int 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" );
402  bool okVector = testDigitalSet< DigitalSetBySTLVector<Domain> >
404  trace.endBlock();
405 
406  trace.beginBlock( "DigitalSetBySTLSet" );
407  bool okSet = testDigitalSet< DigitalSetBySTLSet<Domain> >
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;
421  bool okAssoctestSet = testDigitalSet< DigitalSetByAssociativeContainer<Domain,Container> >
423  trace.endBlock();
424 
425  trace.beginBlock( "DigitalSetByUnorderedSet" );
426  typedef std::unordered_set<Point> ContainerU;
427  bool okUnorderedSet = testDigitalSet< DigitalSetByAssociativeContainer<Domain,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....
Iterator for HyperRectDomain.
Aim: Parallelepidec region of a digital space, model of a 'CDomain'.
const ConstIterator & end() const
const ConstIterator & begin() const
const Point & lowerBound() const
const Point & upperBound() const
std::string className() 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
MyDigitalSurface::ConstIterator ConstIterator
DGtal is the top-level namespace which contains all DGtal functions and types.
Trace trace
Definition: Common.h:153
Aim: Automatically defines an adequate digital set type according to the hints given by the user.
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...
Definition: CDigitalSet.h:141
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
Definition: testClone2.cpp:383
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