DGtal  0.6.devel
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
testVoronoiMap.cpp
1 
30 
31 #include <iostream>
32 #include "DGtal/base/Common.h"
33 #include "DGtal/helpers/StdDefs.h"
34 #include "DGtal/geometry/volumes/distance/VoronoiMap.h"
35 #include "DGtal/geometry/volumes/distance/DistanceTransformation.h"
36 #include "DGtal/kernel/BasicPointPredicates.h"
37 #include "DGtal/io/boards/Board2D.h"
38 #include "DGtal/io/colormaps/HueShadeColorMap.h"
40 
41 using namespace std;
42 using namespace DGtal;
44 // Functions for testing class VoronoiMap.
46 
47 
48 template<typename Point>
49 double mynorm(const Point &point, const double p)
50 {
51  double res=0.0;
52  for(unsigned int i=0; i< Point::dimension; i++)
53  res += std::pow ( (double)abs(point[i]) , p);
54 
55  // x^p = exp(p*log(x))
56  return exp( 1.0/p*log(res));
57 }
58 
59 template <typename VoroMap>
60 void saveVoroMap(const std::string &filename,const VoroMap &output,const double p)
61 {
62  typedef HueShadeColorMap<double,2> Hue;
63  double maxdt=0.0;
64 
65  for ( typename VoroMap::Domain::ConstIterator it = output.domain().begin(), itend = output.domain().end();
66  it != itend; ++it)
67  {
68  typename VoroMap::Value point = output(*it);
69  if ( mynorm(point-(*it),p) > maxdt)
70  maxdt = mynorm(point-(*it),p);
71  }
72  trace.error() << "MaxDT="<<maxdt<<std::endl;
73 
74  Board2D board;
75  Hue hue(0,maxdt);
76 
77  for(typename VoroMap::Domain::ConstIterator it = output.domain().begin(),
78  itend = output.domain().end();
79  it != itend; ++it)
80  {
81  typename VoroMap::Value point = output(*it);
82 
83  board << CustomStyle( (*it).className(), new CustomColors( hue(mynorm(point- (*it),p)),
84  hue(mynorm(point- (*it),p))))
85  << (*it);
86  }
87 
88  board.saveSVG(filename.c_str());
89 }
90 
91 
92 /* Is Validate the VoronoiMap
93  */
94 template < typename Set, typename Image>
95 bool checkVoronoiL2(const Set &aSet, const Image & voro)
96 {
97  typedef typename Image::Point Point;
98 
99  for(typename Image::Domain::ConstIterator it = voro.domain().begin(), itend = voro.domain().end();
100  it != itend; ++it)
101  {
102  Point psite = voro(*it);
103  Point p = (*it);
104  DGtal::int64_t d=0;
105  for(DGtal::Dimension i=0; i<Point::dimension;++i)
106  d+= (p[i]-psite[i])*(p[i]-psite[i]);
107 
108  for(typename Set::ConstIterator itset = aSet.begin(), itendSet = aSet.end();
109  itset != itendSet;
110  ++itset)
111  {
112  DGtal::int64_t dbis=0;
113  for(DGtal::Dimension i=0; i<Point::dimension;++i)
114  dbis+= (p[i]-(*itset)[i])*(p[i]-(*itset)[i]);
115  if ( dbis < d)
116  {
117  trace.error() << "DT Error at "<<p<<" Voro:"<<psite<<" ("<<d<<") from set:"
118  << (*itset) << "("<<dbis<<")"<<std::endl;
119  return false;
120  }
121  }
122  }
123  return true;
124 }
125 
130 bool testVoronoiMap()
131 {
132  unsigned int nbok = 0;
133  unsigned int nb = 0;
134 
135  trace.beginBlock ( "Testing VoronoiMap2D ..." );
136 
137  Z2i::Point a(-10,-10);
138  Z2i::Point b(10,10);
139  Z2i::Domain domain(a,b);
140 
141  Z2i::DigitalSet mySet(domain);
142 
143  for(Z2i::Domain::ConstIterator it = domain.begin(), itend = domain.end();
144  it != itend;
145  ++it)
146  mySet.insertNew( *it );
147 
148 
149  Z2i::DigitalSet sites(domain);
150 
151  sites.insertNew( Z2i::Point(0,-6));
152  sites.insertNew( Z2i::Point(6,0));
153  sites.insertNew( Z2i::Point(-6,0));
154 
155  for(Z2i::DigitalSet::ConstIterator it = sites.begin(), itend = sites.end();
156  it != itend; ++it)
157  mySet.erase (*it);
158 
159 
160 
161  typedef SetPredicate<Z2i::DigitalSet> Predicate;
162  Predicate myPredicate(mySet);
163 
164  //typedef NotPointPredicate<Predicate> NegPredicate;
165  //NegPredicate myNegPredicate( myPredicate );
166 
168 
169  Voro2 voro(domain, myPredicate);
170 
171  Voro2::OutputImage output = voro.compute();
172 
173  for(int j=-10; j <= 10; j++)
174  {
175  for(int i=-10; i<=10; i++)
176  trace.info() << "("<<output( Z2i::Point(i,j))[0]<<","<< output( Z2i::Point(i,j))[1]<<") ";
177  trace.info()<<std::endl;
178  }
179 
180 
181  Board2D board;
182  for(Voro2::OutputImage::Domain::ConstIterator it = output.domain().begin(), itend = output.domain().end();
183  it != itend; ++it)
184  {
185  Z2i::Point p = output(*it);
186  unsigned char c = (p[1]*13 + p[0] * 7) % 256;
187  board << CustomStyle( (*it).className(), new CustomColors(Color(c,c,c),Color(c,c,c)))
188  << (*it);
189  }
190 
191  board.saveSVG("Voromap.svg");
192 
193  nbok += checkVoronoiL2(sites,output) ? 1 : 0;
194  nb++;
195  trace.info() << "(" << nbok << "/" << nb << ") "
196  << "Voronoi diagram is valid !" << std::endl;
197  trace.endBlock();
198 
199 
200 
201 
202  return nbok == nb;
203 }
204 
205 
206 
211 template<typename Set>
212 bool testVoronoiMapFromSites2D(const Set &aSet, const std::string &name)
213 {
214  unsigned int nbok = 0;
215  unsigned int nb = 0;
216 
217  Set mySet(aSet.domain());
218 
219  for(typename Set::Domain::ConstIterator it = aSet.domain().begin(), itend = aSet.domain().end();
220  it != itend;
221  ++it)
222  mySet.insertNew( *it );
223 
224 
225  for(typename Set::ConstIterator it = aSet.begin(), itend = aSet.end();
226  it != itend; ++it)
227  mySet.erase (*it);
228 
229 
230  typedef SetPredicate<Set> Predicate;
231  Predicate myPredicate(mySet);
232 
233  trace.beginBlock(" Voro computation");
235  Voro2 voro(aSet.domain(), myPredicate);
236  typename Voro2::OutputImage output = voro.compute();
237  trace.endBlock();
238 
239 
240  // trace.beginBlock(" Voro computation (l_1)");
241  // typedef VoronoiMap<typename Set::Space, Predicate, 1> Voro1;
242  // Voro1 voro1(aSet.domain(), myPredicate);
243  // typename Voro1::OutputImage output1 = voro1.compute();
244  // trace.endBlock();
245 
246  trace.beginBlock(" Voronoi computation l_3");
248  Voro6 voro6(aSet.domain(), myPredicate);
249  typename Voro6::OutputImage output6 = voro6.compute();
250  trace.endBlock();
251 
252 
253 
254  trace.beginBlock(" DT computation");
256  DT dt(aSet.domain(), myPredicate);
257  typename DT::OutputImage output2 = dt.compute();
258  trace.endBlock();
259 
260 
261  if ( (aSet.domain().upperBound()[1] - aSet.domain().lowerBound()[1]) <20)
262  {
263  for(int j= aSet.domain().lowerBound()[1]; j <= aSet.domain().upperBound()[1]; j++)
264  {
265  for(int i=aSet.domain().lowerBound()[0]; i<=aSet.domain().upperBound()[0]; i++)
266  if ( aSet.find( Z2i::Point(i,j) ) != aSet.end() )
267  std::cout <<"X ";
268  else
269  std::cout<<"0 ";
270  trace.info()<<std::endl;
271  }
272 
273  trace.info() << std::endl;
274 
275  for(int j= aSet.domain().lowerBound()[1]; j <= aSet.domain().upperBound()[1]; j++)
276  {
277  for(int i=aSet.domain().lowerBound()[0]; i<=aSet.domain().upperBound()[0]; i++)
278  trace.info() << "("<<output( Z2i::Point(i,j))[0]<<","<< output( Z2i::Point(i,j))[1]<<") ";
279  trace.info()<<std::endl;
280  }
281  }
282 
283  Board2D board;
284  for(typename Voro2::OutputImage::Domain::ConstIterator it = output.domain().begin(), itend = output.domain().end();
285  it != itend; ++it)
286  {
287  Z2i::Point p = output(*it);
288  unsigned char c = (p[1]*13 + p[0] * 7) % 256;
289  board << CustomStyle( (*it).className(), new CustomColors(Color(c,c,c),Color(c,c,c)))
290  << (*it);;
291  }
292 
293  std::string filename= "Voromap-"+name+".svg";
294  board.saveSVG(filename.c_str());
295  filename= "Voromap-hue"+name+".svg";
296  saveVoroMap(filename.c_str(),output,2);
297 
298 
299  board.clear();
300  for(typename Voro2::OutputImage::Domain::ConstIterator it = output.domain().begin(), itend = output.domain().end();
301  it != itend; ++it)
302  {
303  Z2i::Point p = output(*it);
304  if (p != (*it))
305  Display2DFactory::draw( board, p - (*it), (*it));
306  }
307 
308  filename= "Voromap-diag-"+name+".svg";
309  board.saveSVG(filename.c_str());
310 
311  board.clear();
312  for(typename Voro6::OutputImage::Domain::ConstIterator it = output6.domain().begin(),
313  itend = output6.domain().end();
314  it != itend; ++it)
315  {
316  Z2i::Point p = output6(*it);
317  if (p != (*it))
318  Display2DFactory::draw( board, p - (*it), (*it));
319  }
320 
321  filename= "Voromap-diag-l6-"+name+".svg";
322  board.saveSVG(filename.c_str());
323 
324  board.clear();
325  for(typename Voro6::OutputImage::Domain::ConstIterator it = output6.domain().begin(), itend = output6.domain().end();
326  it != itend; ++it)
327  {
328  Z2i::Point p = output6(*it);
329  unsigned char c = (p[1]*13 + p[0] * 7) % 256;
330  board << CustomStyle( (*it).className(), new CustomColors(Color(c,c,c),Color(c,c,c)))
331  << (*it);;
332  }
333 
334  filename= "Voromap-l6"+name+".svg";
335  board.saveSVG(filename.c_str());
336  filename= "Voromap-hue-l6-"+name+".svg";
337  saveVoroMap(filename.c_str(),output6,3);
338 
339 
340 
341 
342  // board.clear();
343 
344  // for(typename Voro1::OutputImage::Domain::ConstIterator it = output.domain().begin(), itend = output.domain().end();
345  // it != itend; ++it)
346  // {
347  // Z2i::Point p = output(*it);
348  // unsigned char c = (p[1]*13 + p[0] * 7) % 256;
349  // board << CustomStyle( (*it).className(), new CustomColors(Color(c,c,c),Color(c,c,c)))
350  // << (*it);;
351  // }
352 
353  // filename= "Voromap-l1-"+name+".svg";
354  // board.saveSVG(filename.c_str());
355 
356 
357 
358  nbok += checkVoronoiL2(aSet,output) ? 1 : 0;
359  nb++;
360  trace.info() << "(" << nbok << "/" << nb << ") "
361  << "Voronoi diagram is valid !" << std::endl;
362 
363  return nbok == nb;
364 }
365 
370 template<typename Set>
371 bool testVoronoiMapFromSites(const Set &aSet)
372 {
373  unsigned int nbok = 0;
374  unsigned int nb = 0;
375 
376  Set mySet(aSet.domain());
377 
378  for(typename Set::Domain::ConstIterator it = aSet.domain().begin(),
379  itend = aSet.domain().end();
380  it != itend;
381  ++it)
382  mySet.insertNew( *it );
383 
384 
385  for(typename Set::ConstIterator it = aSet.begin(), itend = aSet.end();
386  it != itend; ++it)
387  mySet.erase (*it);
388 
389 
390  typedef SetPredicate<Set> Predicate;
391  Predicate myPredicate(mySet);
392 
393  //typedef NotPointPredicate<Predicate> NegPredicate;
394  //NegPredicate myNegPredicate( myPredicate );
395 
396  trace.beginBlock(" Voronoi computation");
398  Voro2 voro(aSet.domain(), myPredicate);
399  typename Voro2::OutputImage output = voro.compute();
400  trace.endBlock();
401 
402 
403  trace.beginBlock(" Voronoi computation l_3");
405  Voro3 voro3(aSet.domain(), myPredicate);
406  typename Voro3::OutputImage output3 = voro3.compute();
407  trace.endBlock();
408 
409 
410  trace.beginBlock(" DT computation");
412  DT dt(aSet.domain(), myPredicate);
413  typename DT::OutputImage output2 = dt.compute();
414  trace.endBlock();
415 
416 
417  trace.beginBlock("Validating the Voronoi Map");
418  nbok += (checkVoronoiL2(aSet,output) )? 1 : 0;
419  trace.endBlock();
420  nb++;
421  trace.info() << "(" << nbok << "/" << nb << ") "
422  << "Voronoi diagram is valid !" << std::endl;
423 
424  return nbok == nb;
425 }
426 
427 
428 bool testSimple2D()
429 {
430 
431  Z2i::Point a(-10,-10);
432  Z2i::Point b(10,10);
433  Z2i::Domain domain(a,b);
434 
435  Z2i::DigitalSet sites(domain);
436  bool ok;
437 
438  trace.beginBlock("Simple2D");
439  sites.insertNew( Z2i::Point(0,-6));
440  sites.insertNew( Z2i::Point(6,0));
441  sites.insertNew( Z2i::Point(-6,0));
442 
443  ok = testVoronoiMapFromSites2D<Z2i::DigitalSet>(sites,"simple");
444  trace.endBlock();
445 
446  return ok;
447 
448 }
449 
450 bool testSimpleRandom2D()
451 {
452 
453  Z2i::Point a(0,0);
454  Z2i::Point b(64,64);
455  Z2i::Domain domain(a,b);
456 
457  Z2i::DigitalSet sites(domain);
458  bool ok;
459 
460  trace.beginBlock("Random 2D");
461  for(unsigned int i = 0 ; i < 64; ++i)
462  {
463  Z2i::Point p( rand() % (b[0]) - a[0], rand() % (b[1]) + a[1] );
464  sites.insert( p );
465  }
466  ok = testVoronoiMapFromSites2D<Z2i::DigitalSet>(sites,"random");
467  trace.endBlock();
468 
469  trace.beginBlock("Random 2D (dense)");
470  for(unsigned int i = 0 ; i < 64*64-64; ++i)
471  {
472  Z2i::Point p( rand() % (b[0]) - a[0], rand() % (b[1]) + a[1] );
473  sites.insert( p );
474  }
475  ok = testVoronoiMapFromSites2D<Z2i::DigitalSet>(sites,"random-dense");
476  trace.endBlock();
477 
478  return ok;
479 
480 }
481 
482 
483 bool testSimple3D()
484 {
485 
486  Z3i::Point a(-10,-10,-10);
487  Z3i::Point b(10,10,10);
488  Z3i::Domain domain(a,b);
489 
490  Z3i::DigitalSet sites(domain);
491  bool ok;
492 
493  trace.beginBlock("Simple3D");
494  sites.insertNew( Z3i::Point(0,0,-6));
495  sites.insertNew( Z3i::Point(6,0,0));
496  sites.insertNew( Z3i::Point(-6,0,3));
497 
498  ok = testVoronoiMapFromSites<Z3i::DigitalSet>(sites);
499  trace.endBlock();
500 
501  return ok;
502 
503 }
504 
505 bool testSimpleRandom3D()
506 {
507 
508  Z3i::Point a(0,0,0);
509  Z3i::Point b(64,64,64);
510  Z3i::Domain domain(a,b);
511 
512  Z3i::DigitalSet sites(domain);
513  bool ok;
514 
515  trace.beginBlock("Random 3D");
516  for(unsigned int i = 0 ; i < 64; ++i)
517  {
518  Z3i::Point p( rand() % (b[0]) - a[0],
519  rand() % (b[1]) + a[1],
520  rand() % (b[2]) + a[2] );
521  sites.insert( p );
522  }
523  ok = testVoronoiMapFromSites<Z3i::DigitalSet>(sites);
524  trace.endBlock();
525 
526  return ok;
527 
528 }
529 
530 
531 
532 bool testSimple4D()
533 {
534 
535  typedef SpaceND<4> Space4;
536  Space4::Point a(0,0,0,0);
537  Space4::Point b(5,5,5,5);
538  HyperRectDomain<Space4> domain(a,b);
539 
541  bool ok;
542 
543  trace.beginBlock("Simple4D");
544  sites.insertNew( Space4::Point(1,4,1,1));
545  sites.insertNew( Space4::Point(3,1,3,1));
546  sites.insertNew( Space4::Point(0,0,0,0));
547 
548  ok = testVoronoiMapFromSites< DigitalSetBySTLSet< HyperRectDomain<Space4> > >(sites);
549  trace.endBlock();
550 
551  return ok;
552 
553 }
554 
555 
557 // Standard services - public :
558 
559 int main( int argc, char** argv )
560 {
561  trace.beginBlock ( "Testing class VoronoiMap" );
562  trace.info() << "Args:";
563  for ( int i = 0; i < argc; ++i )
564  trace.info() << " " << argv[ i ];
565  trace.info() << endl;
566 
567  bool res = testVoronoiMap()
568  && testSimple2D()
569  && testSimpleRandom2D()
570  && testSimple3D()
571  && testSimpleRandom3D()
572  && testSimple4D(); // && ... other tests
573  trace.emphase() << ( res ? "Passed." : "Error." ) << endl;
574  trace.endBlock();
575  return res ? 0 : 1;
576 }
577 // //