DGtal  0.6.devel
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
testDigitalSet.cpp
1 
37 #include <cstdio>
38 #include <cmath>
39 #include <iostream>
40 #include <fstream>
41 #include <algorithm>
42 #include <string>
43 
44 #include "DGtal/base/Common.h"
45 #include "DGtal/kernel/SpaceND.h"
46 #include "DGtal/kernel/domains/HyperRectDomain.h"
47 #include "DGtal/kernel/sets/CDigitalSet.h"
48 #include "DGtal/kernel/sets/CDigitalSetArchetype.h"
49 #include "DGtal/kernel/domains/CDomain.h"
50 #include "DGtal/kernel/domains/CDomainArchetype.h"
51 #include "DGtal/kernel/sets/DigitalSetBySTLVector.h"
52 #include "DGtal/kernel/sets/DigitalSetBySTLSet.h"
53 #include "DGtal/kernel/sets/DigitalSetFromMap.h"
54 #include "DGtal/kernel/sets/DigitalSetSelector.h"
55 #include "DGtal/kernel/sets/DigitalSetDomain.h"
56 #include "DGtal/kernel/sets/DigitalSetInserter.h"
57 
58 #include "DGtal/images/ImageContainerBySTLMap.h"
59 
60 #include "DGtal/helpers/StdDefs.h"
61 
62 #include "DGtal/io/boards/Board2D.h"
63 
64 
65 using namespace DGtal;
66 using namespace std;
67 
68 
69 #define INBLOCK_TEST(x) \
70  nbok += ( x ) ? 1 : 0; \
71  nb++; \
72  trace.info() << "(" << nbok << "/" << nb << ") " \
73  << #x << std::endl;
74 
75 #define INBLOCK_TEST2(x,y) \
76  nbok += ( x ) ? 1 : 0; \
77  nb++; \
78  trace.info() << "(" << nbok << "/" << nb << ") " \
79  << y << std::endl;
80 
81 
82 
84 {
85  virtual void setStyle(Board2D & aboard) const
86  {
87  aboard.setFillColorRGBi(255, 0, 0);
88  aboard.setPenColorRGBi(0, 255, 0);
89  }
90 };
91 
92 
93 bool testDigitalSetBoardSnippet()
94 {
95  typedef SpaceND<2> Z2;
97  typedef Z2::Point Point;
98  Point p1( -10, -10 );
99  Point p2( 10, 10 );
100  Domain domain( p1, p2 );
102 
103  BOOST_CONCEPT_ASSERT(( CDigitalSet< SpecificSet > ));
104 
105  SpecificSet mySet( domain );
106 
107  Point c( 0, 0 );
108  mySet.insert( c );
109  Point d( 5, 2 );
110  mySet.insert( d );
111  Point e( 1, -3 );
112  mySet.insert( e );
113 
114  Board2D board;
116  board << mySet;
117  board.saveSVG("myset-export.svg");
118 
119  board.clear();
120 
122  board << SetMode( domain.className(), "Grid" ) << domain << mySet;
123  board.saveSVG("simpleSet-grid.svg");
124 
125  board.clear();
126 
128  board << SetMode( domain.className(), "Paving" ) << domain;
129  board << mySet;
130  board.saveSVG("simpleSet-paving.svg");
131 
132 
133  board.clear();
134 
136  board << CustomStyle( mySet.className(), new MyDomainStyleCustomRed );
137  board << mySet;
138  board.saveSVG("simpleSet-color.svg");
139 
140  return true;
141 }
142 
143 template < typename DigitalSetType >
144 bool testDigitalSet( const DigitalSetType& aSet1, const DigitalSetType& aSet2 )
145 {
146  BOOST_CONCEPT_ASSERT(( CDigitalSet< DigitalSetType > ));
147 
148  typedef typename DigitalSetType::Domain Domain;
149  typedef typename Domain::Point Point;
150  typedef typename Point::Coordinate Coordinate;
151  unsigned int nbok = 0;
152  unsigned int nb = 0;
153 
154  //copy, size/empty
155  DigitalSetType set1( aSet1 );
156  nbok += ( (set1.size() == 0)&&(set1.empty()) ) ? 1 : 0;
157  nb++;
158  trace.info() << "(" << nbok << "/" << nb << ") "
159  << "Empty set: " << set1 << std::endl;
160 
161  //insertion
162  std::set<Point> v;
163  Coordinate t [] = { 4, 3, 3 , 4};
164  Coordinate t2[] = { 2, 5, 3 , 5};
165  Coordinate t3[] = { 2, 5, 3 , 4} ;
166  Point a( t );
167  Point b( t2 );
168  Point c( t3 );
169  v.insert( a );
170  v.insert( b );
171  v.insert( c );
172 
173  set1.insert( a );
174  set1.insert( b );
175  set1.insertNew( c );
176  set1.insert( b );
177  nbok += set1.size() == 3 ? 1 : 0;
178  nb++;
179  trace.info() << "(" << nbok << "/" << nb << ") "
180  << "Insertion (3 elements): " << set1 << std::endl;
181 
182  //iterate
183  bool flag = true;
184  for (typename DigitalSetType::Iterator it = set1.begin();
185  it != set1.end(); ++it)
186  {
187  if (v.find( *it ) == v.end())
188  flag = false;
189  }
190  nbok += (flag) ? 1 : 0;
191  nb++;
192  trace.info() << "Iterate: (" << nbok << "/" << nb << ") "
193  << std::endl;
194 
195  //erasure
196  set1.erase( b );
197  nbok += ( (set1.size() == 2)
198  &&(set1.find( b ) == set1.end()) )? 1 : 0;
199  nb++;
200  trace.info() << "(" << nbok << "/" << nb << ") "
201  << "Erase one element by key (2 remain): " << set1 << std::endl;
202 
203  typename DigitalSetType::Iterator it = set1.find( c );
204  set1.erase( it );
205  nbok += ( (set1.size() == 1)
206  &&(set1.find( c ) == set1.end()) )? 1 : 0;
207  nb++;
208  trace.info() << "(" << nbok << "/" << nb << ") "
209  << "Erase one element by iterator (1 remain): " << set1 << std::endl;
210 
211  //other sets
212  DigitalSetType set2( aSet2 );
213  DigitalSetInserter<DigitalSetType> inserter(set2);
214  set1.computeComplement(inserter);
215  nbok += (set2.size() == (set2.domain().size()-1))? 1 : 0;
216  nb++;
217  trace.info() << "(" << nbok << "/" << nb << ") "
218  << "Complement: " << set2 << std::endl;
219 
220  set2 += set1;
221  nbok += (set2.size() == (set2.domain().size()))? 1 : 0;
222  nb++;
223  trace.info() << "(" << nbok << "/" << nb << ") "
224  << "Union: " << set2 << std::endl;
225 
226  //clear
227  set1.clear();
228  nbok += ( (set1.size() == 0)&&(set1.empty()) ) ? 1 : 0;
229  nb++;
230  trace.info() << "(" << nbok << "/" << nb << ") "
231  << "Cleared set: " << set1 << std::endl;
232 
233  set1.assignFromComplement(set2); //remains empty
234  nbok += ( (set1.size() == 0)&&(set1.empty()) ) ? 1 : 0;
235  nb++;
236  trace.info() << "(" << nbok << "/" << nb << ") "
237  << std::endl;
238 
239  return nbok == nb;
240 }
241 
242 template < typename DigitalDomain, int props >
243 bool testDigitalSetSelector( const DigitalDomain & domain,
244  const std::string & comment )
245 {
246  unsigned int nbok = 0;
247  unsigned int nb = 0;
248 
249  trace.beginBlock ( "Test DigitalSetSelector( " + comment + ")." );
250 
251  typedef typename DigitalSetSelector
252  < DigitalDomain, props >::Type SpecificSet;
253  SpecificSet set1( domain );
254  set1.insert( domain.lowerBound() );
255  set1.insert( domain.upperBound() );
256  nbok += set1.size() == 2 ? 1 : 0;
257  nb++;
258  trace.info() << "(" << nbok << "/" << nb << ") "
259  << comment << " (2 elements): " << set1 << std::endl;
260 
261  trace.endBlock();
262 
263 
264  return nbok == nb;
265 }
266 
267 bool testDigitalSetDraw()
268 {
269  unsigned int nbok = 0;
270  unsigned int nb = 0;
271 
272  typedef SpaceND<2> Z2;
273  typedef HyperRectDomain<Z2> Domain;
274  typedef Z2::Point Point;
275  Point p1( -10, -10 );
276  Point p2( 10, 10 );
277  Domain domain( p1, p2 );
278  typedef DigitalSetSelector
279  < Domain, BIG_DS + HIGH_ITER_DS + HIGH_BEL_DS >::Type SpecificSet;
280 
281  BOOST_CONCEPT_ASSERT(( CDigitalSet< SpecificSet > ));
282  SpecificSet disk( domain );
283  Point c( 0, 0 );
284 
285  trace.beginBlock ( "Creating disk( r=5.0 ) ..." );
286  for ( Domain::ConstIterator it = domain.begin();
287  it != domain.end();
288  ++it )
289  {
290  if ( (*it - c ).norm() < 5.0 )
291  // insertNew is very important for vector container.
292  disk.insertNew( *it );
293  }
294 
295  //Board export test
296  trace.beginBlock("SVG Export");
297  Board2D board;
298  board << SetMode( domain.className(), "Grid" ) << domain;
299  board << disk;
300 
301  board.scale(10);
302  board.saveSVG( "disk-set.svg" );
303  trace.endBlock();
304 
305  return nbok == nb;
306 }
307 
308 bool testDigitalSetDomain()
309 {
310  unsigned int nbok = 0;
311  unsigned int nb = 0;
312 
313  typedef SpaceND<2> Z2;
314  typedef HyperRectDomain<Z2> Domain;
315  typedef Z2::Point Point;
316  Point p1( -49, -49 );
317  Point p2( 49, 49 );
318  Domain domain( p1, p2 );
319  typedef DigitalSetSelector
320  < Domain, BIG_DS + HIGH_ITER_DS + HIGH_BEL_DS >::Type SpecificSet;
321  BOOST_CONCEPT_ASSERT(( CDigitalSet< SpecificSet > ));
322 
323  SpecificSet disk( domain );
324  Point c( 0, 0 );
325  Point l( 49, 0 );
326 
327  trace.beginBlock ( "Creating disk( r=50.0 ) ..." );
328  for ( Domain::ConstIterator it = domain.begin();
329  it != domain.end();
330  ++it )
331  {
332  if ( (*it - c ).norm() < 50.0 )
333  // insertNew is very important for vector container.
334  disk.insertNew( *it );
335  }
336  disk.erase( c );
337  INBLOCK_TEST( disk.size() == 7824 );
338  trace.info() << "disk.size()=" << disk.size() << std::endl;
339  trace.endBlock();
340 
341  typedef DigitalSetDomain< SpecificSet > RestrictedDomain;
342  BOOST_CONCEPT_ASSERT(( CDomain< RestrictedDomain > ));
343 
344  RestrictedDomain disk_domain( disk );
345  trace.beginBlock ( "Iterating over disk domain ..." );
346  unsigned int nb_in_domain = 0;
347  for ( RestrictedDomain::ConstIterator it = disk_domain.begin();
348  it != disk_domain.end();
349  ++it )
350  {
351  ++nb_in_domain;
352  }
353  INBLOCK_TEST( nb_in_domain == 7824 );
354  INBLOCK_TEST( disk_domain.lowerBound() == Point( -49, -49 ) );
355  INBLOCK_TEST( disk_domain.upperBound() == Point( 49, 49 ) );
356  trace.endBlock();
357 
358  return nbok == nb;
359 }
360 
361 bool testDigitalSetConcept()
362 {
363  typedef Z2i::Point Value;
364  typedef std::vector<Value>::iterator vector_iterator;
365  typedef std::set<Value>::iterator set_iterator;
366  //BOOST_CONCEPT_ASSERT(( boost::Mutable_BidirectionalIterator< vector_iterator > ));
367  //BOOST_CONCEPT_ASSERT(( boost::Mutable_BidirectionalIterator< set_iterator > ));
368  BOOST_CONCEPT_ASSERT(( CDigitalSet<Z2i::DigitalSet> ));
369  BOOST_CONCEPT_ASSERT(( CDigitalSet<Z3i::DigitalSet> ));
370 
371  typedef Z2i::Space Space;
372  BOOST_CONCEPT_ASSERT(( CDomain< CDomainArchetype< Space > > ));
373  typedef CDigitalSetArchetype<Z2i::Domain> DigitalSetArchetype;
374  BOOST_CONCEPT_ASSERT(( CDigitalSet<DigitalSetArchetype> ));
375 
376  return true;
377 }
378 
379 int main()
380 {
381  typedef SpaceND<4> Space4Type;
382  typedef HyperRectDomain<Space4Type> Domain;
383  typedef Space4Type::Point Point;
384 
385  DGtal::int32_t t[] = { 1, 2, 3 , 4};
386  Point a ( t );
387  DGtal::int32_t 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  bool okSelectorSmall = testDigitalSetSelector
416  < Domain, SMALL_DS + LOW_VAR_DS + LOW_ITER_DS + LOW_BEL_DS >
417  ( domain, "Small set" );
418 
419  bool okSelectorBig = testDigitalSetSelector
420  < Domain, BIG_DS + LOW_VAR_DS + LOW_ITER_DS + LOW_BEL_DS >
421  ( domain, "Big set" );
422 
423  bool okSelectorMediumHBel = testDigitalSetSelector
424  < Domain, MEDIUM_DS + LOW_VAR_DS + LOW_ITER_DS + HIGH_BEL_DS >
425  ( domain, "Medium set + High belonging test" );
426 
427  bool okDigitalSetDomain = testDigitalSetDomain();
428 
429  bool okDigitalSetDraw = testDigitalSetDraw();
430 
431  bool okDigitalSetDrawSnippet = testDigitalSetBoardSnippet();
432 
433  bool res = okVector && okSet && okMap
434  && okSelectorSmall && okSelectorBig && okSelectorMediumHBel
435  && okDigitalSetDomain && okDigitalSetDraw && okDigitalSetDrawSnippet;
436  trace.endBlock();
437  trace.emphase() << ( res ? "Passed." : "Error." ) << endl;
438  return res ? 0 : 1;
439 }
440