DGtal  1.5.beta
testArithmeticalDSS.cpp
Go to the documentation of this file.
1 
31 #include <iostream>
32 #include "DGtal/base/Common.h"
33 #include "DGtal/kernel/CPointPredicate.h"
34 #include "DGtal/base/CConstBidirectionalRange.h"
35 #include "DGtal/geometry/curves/ArithmeticalDSS.h"
36 #include "DGtal/geometry/curves/ArithmeticalDSSFactory.h"
37 #include "DGtal/geometry/curves/StabbingLineComputer.h"
39 
40 using namespace std;
41 using namespace DGtal;
42 
44 // Functions for testing class ArithmeticalDSS.
46 
51 template <typename DSS>
52 bool mainTest()
53 {
54  BOOST_CONCEPT_ASSERT(( concepts::CPointPredicate<DSS> ));
55  BOOST_CONCEPT_ASSERT(( concepts::CConstBidirectionalRange<DSS> ));
56 
57  typedef typename DSS::Point Point;
58 
59  unsigned int nbok = 0;
60  unsigned int nb = 0;
61 
62  trace.beginBlock ( "Main operators..." );
63 
64  //operateur constructeur, copie, affectation
65  trace.info() << "constructor, copy, assignement, equality" << std::endl;
66 
67  DSS dss(0, 1,
68  Point(0,0), Point(1,0),
69  Point(0,0), Point(1,0),
70  Point(0,0), Point(1,0) );
71  DSS dss2 = dss;
72  DSS dss3(Point(0,0), Point(1,1), true);
73  DSS dss4 = dss3;
74  dss3 = dss2 = dss;
75 
76  //egalite, difference
77  DSS dss5(0, -1,
78  Point(1,0), Point(0,0),
79  Point(1,0), Point(0,0),
80  Point(1,0), Point(0,0) );
81 
82  if ( (dss == dss2)
83  &&(dss == dss3)
84  &&(dss != dss4)
85  &&(dss == dss5) )
86  nbok++;
87  nb++;
88  trace.info() << "(" << nbok << "/" << nb << ") "
89  << std::endl;
90 
91  //validite
92  trace.info() << "valid dss" << std::endl;
93  if ( dss.isValid() && dss3.isValid() && dss5.isValid() )
94  nbok++;
95  nb++;
96  trace.info() << "(" << nbok << "/" << nb << ") "
97  << std::endl;
98 
99  DSS dss6(0, 1,
100  Point(1,0), Point(0,0),
101  Point(1,0), Point(0,0),
102  Point(1,0), Point(0,0) );
103 
104  trace.info() << "not valid dss" << std::endl;
105  if (!dss6.isValid())
106  nbok++;
107  nb++;
108 
109  trace.info() << "(" << nbok << "/" << nb << ") "
110  << std::endl;
111 
112  //accessors
113  trace.info() << "a,b,mu,omega accessors" << std::endl;
114 
115  if ( (dss.a() == 0)&&(dss.b() == 1)&&(dss.mu() == 0)&&(dss.omega() == 1) )
116  nbok++;
117  nb++;
118 
119  trace.info() << "(" << nbok << "/" << nb << ") "
120  << std::endl;
121 
122  trace.info() << "points accessors" << std::endl;
123  if ( (dss.front() == Point(1,0))&&(dss.back() == Point(0,0)) )
124  nbok++;
125  nb++;
126  if ( (dss.Ul() == Point(1,0))&&(dss.Uf() == Point(0,0)) )
127  nbok++;
128  nb++;
129  if ( (dss.Ll() == Point(1,0))&&(dss.Lf() == Point(0,0)) )
130  nbok++;
131  nb++;
132 
133  trace.info() << "(" << nbok << "/" << nb << ") "
134  << std::endl;
135 
136  DSS dss7(Point(0,0), Point(8,5), true);
137 
138  trace.info() << "remainder, position, tests" << std::endl;
139  trace.info() << dss7 << std::endl;
140 
141  if ( (dss7.isValid())
142  && (dss7.remainder( Point(8,5) ) == 0)
143  &&(dss7.remainder( Point(16,10) ) == 0)
144  &&(dss7.remainder( Point(3,2) ) == -1)
145  &&(dss7.remainder( Point(5,3) ) == 1) )
146  nbok++;
147  nb++;
148 
149  trace.info() << "(" << nbok << "/" << nb << ") "
150  << std::endl;
151 
152  if ( (dss7.orthogonalPosition( Point(0,0) ) == 0)
153  &&(dss7.orthogonalPosition( Point(8,5) ) == 89)
154  &&(dss7.orthogonalPosition( Point(1,0) ) == 8)
155  &&(dss7.orthogonalPosition( Point(-1,0) ) == -8) )
156  nbok++;
157  nb++;
158 
159  trace.info() << "(" << nbok << "/" << nb << ") "
160  << std::endl;
161 
162  if ( (dss7.isInDSL( Point(0,0) ))
163  &&(dss7.isInDSL( Point(16,10) ))
164  &&(dss7.isInDSL( Point(5,3) ))
165  &&(!dss7.isInDSL( Point(3,2) )) )
166  nbok++;
167  nb++;
168 
169  trace.info() << "(" << nbok << "/" << nb << ") "
170  << std::endl;
171 
172  if ( (dss7( Point(0,0) ))
173  &&(!dss7( Point(16,10) ))
174  &&(dss7( Point(5,3) ))
175  &&(!dss7( Point(3,2) ))
176  &&(!dss7( Point(-1,0) )) )
177  nbok++;
178  nb++;
179 
180  trace.info() << "(" << nbok << "/" << nb << ") "
181  << std::endl;
182 
183  trace.info() << "shift" << std::endl;
184  if (dss.remainder(dss.shift()) == dss.omega())
185  nbok++;
186  nb++;
187  trace.info() << "(" << nbok << "/" << nb << ") "
188  << std::endl;
189 
190  trace.endBlock();
191 
192  return nbok == nb;
193 }
194 
195 
197 
203 template <typename DSS>
204 bool rangeTest(const DSS& dss)
205 {
206  unsigned int nbok = 0;
207  unsigned int nb = 0;
208 
209  trace.beginBlock ( "Range/Iterator services..." );
210  trace.info() << dss << std::endl;
211 
212  if (dss.isValid())
213  nbok++;
214  nb++;
215 
216  trace.info() << "(" << nbok << "/" << nb << ") "
217  << std::endl;
218 
219  {//forward pass
220  typedef typename DSS::ConstIterator I;
221  BOOST_CONCEPT_ASSERT(( boost_concepts::ReadableIteratorConcept<I> ));
222  BOOST_CONCEPT_ASSERT(( boost_concepts::BidirectionalTraversalConcept<I> ));
223  bool res = true;
224  int c = 0;
225  for (I it = dss.begin(), itEnd = dss.end();
226  ( (it != itEnd)&&(res)&&(c<100) );
227  ++it, ++c)
228  {
229  trace.info() << *it << " ";
230  if ( !dss(*it) )
231  res = false;
232  }
233  trace.info() << " : " << c << " points " << std::endl;
234  trace.info() << std::endl;
235 
236  if ( (res)&&(c == (dss.omega()+1))
237  &&(*dss.begin() == dss.back())
238  &&(*--dss.end() == dss.front()) )
239  nbok++;
240  nb++;
241 
242  trace.info() << "(" << nbok << "/" << nb << ") "
243  << std::endl;
244  }
245 
246  {//backward pass
247  typedef typename DSS::ConstReverseIterator I;
248  bool res = true;
249  int c = 0;
250  for (I it = dss.rbegin(), itEnd = dss.rend();
251  ( (it != itEnd)&&(res)&&(c<100) );
252  ++it, ++c)
253  {
254  trace.info() << *it << " ";
255  if ( !dss(*it) )
256  res = false;
257  }
258  trace.info() << " : " << c << " points " << std::endl;
259  trace.info() << std::endl;
260 
261  if ( (res)&&(c == (dss.omega()+1))
262  &&(*dss.rbegin() == dss.front())
263  &&(*--dss.rend() == dss.back()) )
264  nbok++;
265  nb++;
266 
267  trace.info() << "(" << nbok << "/" << nb << ") "
268  << std::endl;
269  }
270 
271  trace.endBlock();
272 
273  return nbok == nb;
274 }
275 
277 
288 template <typename DSS>
289 void extensionTest(const DSS& dss,
290  typename DSS::Point newPointToFront,
291  typename DSS::Point newPointToBack,
292  unsigned int& nbok, unsigned int& nb,
293  const unsigned short int& code = 0)
294 {
295  trace.info() << dss << std::endl;
296  if (dss.isValid())
297  nbok++;
298  nb++;
299  trace.info() << "(" << nbok << "/" << nb << ") " << std::endl;
300 
301  trace.info() << "to front " << newPointToFront << std::endl;
302  if (dss.isExtendableFront( newPointToFront ) == code)
303  nbok++;
304  nb++;
305  trace.info() << "(" << nbok << "/" << nb << ") " << std::endl;
306 
307  DSS mdss = dss; //local and modifiable copy
308  if (code == 0)
309  {
310  if ( (!mdss.extendFront(newPointToFront)) )
311  nbok++;
312  nb++;
313  }
314  else
315  {
316  if ( (mdss.extendFront(newPointToFront))&&(mdss.isValid()) )
317  nbok++;
318  nb++;
319  std::cerr << mdss.isValid() << std::endl;
320  }
321  trace.info() << mdss << std::endl;
322  trace.info() << "(" << nbok << "/" << nb << ") " << std::endl;
323 
324  trace.info() << "to back " << newPointToBack << std::endl;
325  if (dss.isExtendableBack( newPointToBack ) == code)
326  nbok++;
327  nb++;
328  trace.info() << "(" << nbok << "/" << nb << ") " << std::endl;
329 
330  mdss = dss; //local and modifiable copy
331  if (code == 0)
332  {
333  if ( (!mdss.extendBack(newPointToBack)) )
334  nbok++;
335  nb++;
336  }
337  else
338  {
339  if ( (mdss.extendBack(newPointToBack))&&(mdss.isValid()) )
340  nbok++;
341  nb++;
342  std::cerr << mdss.isValid() << std::endl;
343  }
344  trace.info() << mdss << std::endl;
345  trace.info() << "(" << nbok << "/" << nb << ") " << std::endl;
346 }
347 
349 
359 template <typename DSS>
360 void retractionTest(const DSS& dss,
361  unsigned int& nbok,
362  unsigned int& nb,
363  bool res = true)
364 {
365  typedef typename DSS::Point Point;
366 
367  trace.info() << dss << std::endl;
368  if (dss.isValid())
369  nbok++;
370  nb++;
371  trace.info() << "(" << nbok << "/" << nb << ") " << std::endl;
372 
373  //local and modifiable copy
374  DSS mdss = dss;
375 
376  //forward test
377  Point first = mdss.back();
378  trace.info() << "remove " << first << std::endl;
379  if ( ( (mdss.retractBack())
380  && (mdss.isValid())
381  && (mdss(first) == false) ) == res )
382  nbok++;
383  nb++;
384  trace.info() << "(" << nbok << "/" << nb << ") " << std::endl;
385 
386  if (res)
387  {
388  if ( (mdss.extendBack(first))
389  && (mdss.isValid()) && (mdss == dss) )
390  nbok++;
391  nb++;
392  trace.info() << "(" << nbok << "/" << nb << ") " << std::endl;
393  }
394 
395  //backward test
396  Point last = mdss.front();
397  trace.info() << "remove " << last << std::endl;
398  if ( ( (mdss.retractFront())
399  && (mdss.isValid())
400  && (mdss(last) == false) ) == res )
401  nbok++;
402  nb++;
403  trace.info() << mdss << std::endl;
404  trace.info() << "(" << nbok << "/" << nb << ") " << std::endl;
405 
406  if (res)
407  {
408  if ( (mdss.extendFront(last))
409  && (mdss.isValid()) && (mdss == dss) )
410  nbok++;
411  nb++;
412  trace.info() << "(" << nbok << "/" << nb << ") " << std::endl;
413  }
414 
415 }
416 
422 template <typename DSS>
424 {
425  typedef typename DSS::Point Point;
426  typedef typename DSS::Vector Vector;
427 
428  unsigned int nbok = 0;
429  unsigned int nb = 0;
430 
431  trace.beginBlock ( "Extension services..." );
432 
433  if (nbok == nb)
434  {
435  trace.info() << "not connected point" << std::endl;
436  DSS dss(Point(0,0), Point(8,5), true);
437  extensionTest( dss, Point(9,7), Point(-2,1), nbok, nb );
438  }
439 
440  if (nbok == nb)
441  {
442  trace.info() << "not compatible second step" << std::endl;
443  DSS dss(Point(0,0), Point(1,1), true);
444  extensionTest( dss, Point(0,2), Point(-1,1), nbok, nb );
445  }
446 
447  if (nbok == nb)
448  {
449  trace.info() << "a third step" << std::endl;
450  DSS dss(Point(0,0), Point(2,1), true);
451  extensionTest( dss, Point(2,2), Point(0,1), nbok, nb );
452  }
453 
454  if (nbok == nb)
455  {
456  trace.info() << "strongly exterior" << std::endl;
457  DSS dss(Point(0,0), Point(8,5), true);
458  extensionTest( dss, Point(9,6), Point(-1,0), nbok, nb );
459  }
460 
461  if (nbok == nb)
462  {
463  trace.info() << "confounded points" << std::endl;
464  DSS dss(Point(0,0), Point(8,5), true);
465  extensionTest( dss, Point(8,5), Point(0,0), nbok, nb, 9 );
466  }
467 
468  if (nbok == nb)
469  {
470  trace.info() << "strongly interior points" << std::endl;
471  DSS dss0(Point(0,0), Point(8,5), true);
472  DSS dss(5, 8, Point(-2,-2), Point(8,5),
473  dss0.Uf(), dss0.Ul(),
474  dss0.Lf(), dss0.Ll() );
475  extensionTest( dss, Point(9,5), Point(-3,-2), nbok, nb, 9 );
476  }
477 
478  if (nbok == nb)
479  {
480  trace.info() << "weakly interior points on the left" << std::endl;
481  DSS dss0(Point(0,0), Point(8,5), true);
482  Point newPointToBack = dss0.Lf()-Vector(8,5);
483  Point newPointToFront = dss0.Ul()+Vector(8,5);
484  DSS dss(5, 8,
485  newPointToBack+dss0.steps().second,
486  newPointToFront-dss0.steps().second,
487  dss0.Uf(), dss0.Ul(),
488  dss0.Lf(), dss0.Ll()+Vector(8,5) );
489  extensionTest( dss, newPointToFront, newPointToBack, nbok, nb, 5 );
490  }
491 
492  if (nbok == nb)
493  {
494  trace.info() << "weakly exterior points on the left" << std::endl;
495  DSS dss0(Point(0,0), Point(8,5), true);
496  Point newPointToBack = dss0.Uf()+dss0.shift()-Vector(8,5);
497  Point newPointToFront = dss0.Ll()-dss0.shift()+Vector(8,5);
498  DSS dss(5, 8,
499  newPointToBack+dss0.steps().second,
500  newPointToFront-dss0.steps().second,
501  dss0.Uf(), dss0.Ul(),
502  dss0.Lf()-Vector(8,5), dss0.Ll() );
503  extensionTest( dss, newPointToFront, newPointToBack, nbok, nb, 7 );
504  }
505 
506  if (nbok == nb)
507  {
508  trace.info() << "weakly interior points on the right" << std::endl;
509  DSS dss0(Point(0,0), Point(8,5), true);
510  Point newPointToBack = dss0.Uf()-Vector(8,5);
511  Point newPointToFront = dss0.Ll()+Vector(8,5);
512  DSS dss(5, 8,
513  newPointToBack+dss0.steps().first,
514  newPointToFront-dss0.steps().first,
515  dss0.Uf(), dss0.Ul(),
516  dss0.Lf()-Vector(8,5), dss0.Ll() );
517  extensionTest( dss, newPointToFront, newPointToBack, nbok, nb, 6 );
518  }
519 
520  if (nbok == nb)
521  {
522  trace.info() << "weakly exterior points on the right" << std::endl;
523  DSS dss0(Point(0,0), Point(8,5), true);
524  Point newPointToBack = dss0.Lf()-Vector(8,5)-dss0.shift();
525  Point newPointToFront = dss0.Ul()+Vector(8,5)+dss0.shift();
526  DSS dss(5, 8,
527  newPointToBack+dss0.steps().first,
528  newPointToFront-dss0.steps().first,
529  dss0.Uf(), dss0.Ul(),
530  dss0.Lf(), dss0.Ll()+Vector(8,5) );
531  extensionTest( dss, newPointToFront, newPointToBack, nbok, nb, 8 );
532  }
533 
534  if (nbok == nb)
535  {
536  trace.info() << "first step" << std::endl;
537  DSS dss( Point(0,0), Point(0,0) );
538  extensionTest( dss, Point(1,0), Point(-1,0), nbok, nb, 1 );
539  }
540 
541  if (nbok == nb)
542  {
543  trace.info() << "first step repetition" << std::endl;
544  DSS dss(Point(0,0), Point(1,0), true);
545  extensionTest( dss, Point(2,0), Point(-1,0), nbok, nb, 2 );
546  }
547 
548  if (nbok == nb)
549  {
550  trace.info() << "second step (above)" << std::endl;
551  DSS dss0(Point(0,0), Point(2,1), true);
552  DSS dss(Point(0,0), Point(2,1) - dss0.steps().second);
553  Point newPointToBack = Point(0,0) - dss0.steps().second;
554  extensionTest( dss, Point(2,1), newPointToBack, nbok, nb, 3 );
555  }
556 
557  if (nbok == nb)
558  {
559  trace.info() << "second step (below)" << std::endl;
560  DSS dss0a(Point(0,0), Point(2,-1), true);
561  DSS dss0b(Point(0,0), Point(2,1), true);
562  DSS dss(Point(0,0), Point(2,-1) - dss0a.steps().first);
563  Point newPointToBack = Point(0,0) - dss0a.steps().first;
564  extensionTest( dss, Point(2,-1), newPointToBack, nbok, nb, 4 );
565  }
566 
567  trace.endBlock();
568 
569  if (nbok == nb)
570  {
571  trace.beginBlock ( "Retraction services..." );
572 
573  {
574  trace.info() << "upper leaning points" << std::endl;
575  DSS dss(Point(0,0), Point(8,5), true);
576  retractionTest( dss, nbok, nb );
577  }
578 
579  if (nbok == nb)
580  {
581  trace.info() << "lower leaning points" << std::endl;
582  DSS dss0(Point(0,0), Point(8,5), true);
583  Point first = dss0.Lf();
584  Point last = dss0.Lf() + Vector(8,5);
585  DSS dss(5, 8, first, last,
586  Point(8,5), Point(8,5),
587  first, last );
588  retractionTest( dss, nbok, nb );
589  }
590 
591  if (nbok == nb)
592  {
593  trace.info() << "upper leaning points (repetitions)" << std::endl;
594  DSS dss(Point(0,0), Point(16,10), true);
595  retractionTest( dss, nbok, nb );
596  }
597 
598  if (nbok == nb)
599  {
600  trace.info() << "lower leaning points (repetitions)" << std::endl;
601  DSS dss0(Point(0,0), Point(16,10), true);
602  Point first = dss0.Lf();
603  Point last = dss0.Lf() + Vector(16,10);
604  DSS dss(5, 8, first, last,
605  Point(8,5), Point(16,10),
606  first, last );
607  retractionTest( dss, nbok, nb );
608  }
609 
610  if (nbok == nb)
611  {
612  trace.info() << "no change" << std::endl;
613  DSS dss0(Point(0,0), Point(21,13), true);
614  typename DSS::ConstIterator itb = dss0.begin();
615  --itb; --itb; --itb;
616  typename DSS::ConstIterator ite = dss0.end();
617  ++ite; ++ite; ++ite;
618  DSS dss(dss0.a(), dss0.b(), *itb, *ite,
619  dss0.Uf(), dss0.Ul(), dss0.Lf(), dss0.Ll() );
620  retractionTest( dss, nbok, nb );
621  }
622 
623  if (nbok == nb)
624  {
625  trace.info() << "one point" << std::endl;
626  DSS dss(Point(0,0), Point(0,0), true);
627  retractionTest( dss, nbok, nb, false );
628  }
629 
630  if (nbok == nb)
631  {
632  trace.info() << "two points" << std::endl;
633  DSS dss(Point(0,0), Point(1,0), true);
634  retractionTest( dss, nbok, nb );
635  }
636 
637  if (nbok == nb)
638  {
639  trace.info() << "from two steps to one step" << std::endl;
640  DSS dss(Point(0,0), Point(1,1), true);
641  retractionTest( dss, nbok, nb );
642  }
643 
644 
645  trace.endBlock();
646  }
647 
648  return nbok == nb;
649 }
650 
658 template <typename DSS>
659 bool compatibleStepsTest(const DSS& dss)
660 {
661  unsigned int nbok = 0;
662  unsigned int nb = 0;
663 
664  trace.beginBlock ( "directional Position..." );
665 
666  trace.info() << "shift: " << dss.shift()
667  << ", front pos: " << dss.position( dss.front() )
668  << ", back pos: " << dss.position( dss.back() ) << std::endl;
669  if ( dss.position( dss.front() )
670  > dss.position( dss.back() ) )
671  nbok++;
672  nb++;
673 
674  trace.info() << "(" << nbok << "/" << nb << ") "
675  << std::endl;
676 
677  trace.endBlock();
678 
679  trace.beginBlock ( "Compatible steps..." );
680 
682  DSS mdss = dss;
683  if ( mdss.extendFront(mdss.front()-dss.shift()+dss.steps().first) )
684  nbok++;
685  nb++;
686 
687  trace.info() << "(" << nbok << "/" << nb << ") "
688  << std::endl;
689  mdss = dss;
690  if ( !mdss.extendFront(mdss.front()-dss.shift()) )
691  nbok++;
692  nb++;
693 
694  trace.info() << "(" << nbok << "/" << nb << ") "
695  << std::endl;
696 
697  mdss = dss;
698  if ( !mdss.extendFront(mdss.front()-dss.shift()-dss.steps().first) )
699  nbok++;
700  nb++;
701 
702  trace.info() << "(" << nbok << "/" << nb << ") "
703  << std::endl;
704 
706  mdss = dss;
707  if ( mdss.extendBack(mdss.back()+dss.shift()-dss.steps().first) )
708  nbok++;
709  nb++;
710 
711  trace.info() << "(" << nbok << "/" << nb << ") "
712  << std::endl;
713  mdss = dss;
714  if ( !mdss.extendBack(mdss.back()+dss.shift()) )
715  nbok++;
716  nb++;
717 
718  trace.info() << "(" << nbok << "/" << nb << ") "
719  << std::endl;
720 
721  mdss = dss;
722  if ( !mdss.extendBack(mdss.back()+dss.shift()+dss.steps().first) )
723  nbok++;
724  nb++;
725 
726  trace.info() << "(" << nbok << "/" << nb << ") "
727  << std::endl;
728 
729  trace.endBlock();
730 
731  return nbok == nb;
732 }
733 
739 template <typename DSS>
741 {
742  BOOST_CONCEPT_ASSERT(( concepts::CPointPredicate<DSS> ));
743  BOOST_CONCEPT_ASSERT(( concepts::CConstBidirectionalRange<DSS> ));
744 
745  typedef typename DSS::Point Point;
746 
747  unsigned int nbok = 0;
748  unsigned int nb = 0;
749 
750  trace.beginBlock ( "constructors..." );
751 
752  {
753  //pattern
754  DSS dss0( Point(0,0), Point(8,5) );
755  trace.info() << dss0 << std::endl;
756 
757  //construction by points range
758  DSS dss( dss0.begin(), dss0.end() );
759  trace.info() << dss << std::endl;
760 
761  if ( (dss0.isValid())
762  &&(dss.isValid())
763  && (dss0 == dss)
764  && (dss.Lf() == dss.Ll())
765  && (dss.Uf() == dss.back())
766  && (dss.Ul() == dss.front())
767  && (dss.back() != dss.front()) )
768  nbok++;
769  nb++;
770  trace.info() << "(" << nbok << "/" << nb << ") "
771  << std::endl;
772 
773  //reversed pattern
774  DSS rdss0( Point(0,0), Point(8,5), false );
775  trace.info() << rdss0 << std::endl;
776 
777  //construction by points range
778  DSS rdss( rdss0.begin(), rdss0.end() );
779  trace.info() << rdss << std::endl;
780 
781  if ( (rdss0.isValid())
782  &&(rdss.isValid())
783  && (rdss0 == rdss)
784  && (rdss.Uf() == rdss.Ul())
785  && (rdss.Lf() == rdss.back())
786  && (rdss.Ll() == rdss.front())
787  && (rdss.back() != rdss.front())
788  && (rdss != dss) )
789  nbok++;
790  nb++;
791  trace.info() << "(" << nbok << "/" << nb << ") "
792  << std::endl;
793 
794  }
795 
796  trace.endBlock();
797 
798  return nbok == nb;
799 }
800 
811 template <typename DSS>
812 bool comparisonSubsegment(const DSS& aDSS,
813  typename DSS::Position x, typename DSS::Position y)
814 {
815  typename DSS::DSL dsl = aDSS.dsl();
816  DSS dss0( dsl.begin(dsl.getPoint(x)), dsl.end(dsl.getPoint(y)) ); //classical (linear-time)
817  DSS dss1( dsl, dsl.getPoint(x), dsl.getPoint(y) ); //smartCH (log)
818  DSS dss2( aDSS, dsl.getPoint(x), dsl.getPoint(y) ); //reversedSmartCH (log)
819  return ( (dss0 == dss1)&&(dss0 == dss2) );
820 }
821 
832 template <typename DSL>
833 bool comparisonSubsegment(typename DSL::Coordinate a, typename DSL::Coordinate b)
834 {
835  unsigned int nbok = 0;
836  unsigned int nb = 0;
837 
838  trace.beginBlock ( "Subsegment comparison ..." );
839 
840  DSL aDSL(a, b, 0);
841  for (typename DSL::Integer mu = 0; ( (mu-1 >= -aDSL.omega())&&(nbok == nb) ); --mu)
842  {
843  //trace.info() << "mu=" << mu << std::endl;
844 
845  typedef typename DSL::Point Point;
846  typedef typename DSL::Coordinate Coordinate;
847  typedef typename DSL::Integer Integer;
849 
850  Point startingPoint = aDSL.getPoint(0);
851  ASSERT( aDSL(startingPoint) );
852  Point endingPoint = aDSL.getPoint(2*aDSL.patternLength()+1);
853  ASSERT( aDSL(endingPoint) );
854 
855  DSS dss = DSS(aDSL.begin(startingPoint), aDSL.end(endingPoint));
856 
857  for (typename DSL::Position l = 0; ( (l <= 2*aDSL.patternLength())&&(nbok == nb) ); ++l)
858  {
859  //trace.info() << "l=" << l << std::endl;
860 
861  for (typename DSL::Position k = 0; ( (k <= l)&&(nbok == nb) ); ++k)
862  {
863  //trace.info() << "k=" << k << std::endl;
864 
865  if (comparisonSubsegment(dss, k, l))
866  nbok++;
867  nb++;
868 
869  }
870  }
871 
872  }
873 
874  trace.endBlock();
875 
876  return (nb == nbok);
877 }
878 
879 //---------------------------------------------------------------------------
880 bool unionTest()
881 {
882  unsigned int nb = 0;
883  unsigned int nbok = 0;
884 
886  typedef DSS::Point Point;
887 
888  trace.beginBlock("Testing union of two DSSs");
889 
890  // Different tests to cover all possible configurations
891 
892  //-------------------------------------------------
893  //---------- Union is part of a DSL----------------
894 
895  // DSS1 included in DSS2
896 
897  trace.beginBlock("Simplest inclusion: DSS1 in DSS2");
898  // octant 0
899  trace.info() << "octant 0\n";
900  DSS DSS1(1,2,Point(2,2),Point(6,4),Point(2,2),Point(6,4),Point(3,2),Point(5,3));
901  DSS DSS2(3,5,Point(-2,-1),Point(9,6),Point(2,2),Point(7,5),Point(0,0),Point(5,3));
902  DSS res=DSS1.computeUnion(DSS2);
903  nb++;
904  nbok +=(res==DSS2)?1:0;
905 
906  // octant 1
907  trace.info() << "octant 1\n";
908  DSS1 = DSS(2,1,Point(2,2),Point(4,6),Point(2,3),Point(3,5),Point(2,2),Point(4,6));
909  assert(DSS1.isValid());
910  DSS2 = DSS(5,3,Point(-1,-2),Point(6,9),Point(0,0),Point(3,5),Point(2,2),Point(5,7));
911  assert(DSS2.isValid());
912  res = DSS1.computeUnion(DSS2);
913  nb++;
914  nbok +=(res==DSS2)?1:0;
915 
916  // octant 2
917  trace.info() << "octant 2\n";
918  DSS1 = DSS(2,-1,Point(-2,2),Point(-4,6),Point(-2,2),Point(-4,6),Point(-2,3),Point(-3,5));
919  assert(DSS1.isValid());
920  DSS2 = DSS(5,-3,Point(1,-2),Point(-6,9),Point(-2,2),Point(-5,7),Point(0,0),Point(-3,5));
921  assert(DSS2.isValid());
922  res = DSS1.computeUnion(DSS2);
923  nb++;
924  nbok +=(res==DSS2)?1:0;
925 
926  // octant 3
927  trace.info() << "octant 3\n";
928  DSS1 = DSS(1,-2,Point(-2,2),Point(-6,4),Point(-3,2),Point(-5,3),Point(-2,2),Point(-6,4));
929  assert(DSS1.isValid());
930  DSS2 = DSS(3,-5,Point(2,-1),Point(-9,6),Point(0,0),Point(-5,3),Point(-2,2),Point(-7,5));
931  assert(DSS2.isValid());
932  res = DSS1.computeUnion(DSS2);
933  nb++;
934  nbok +=(res==DSS2)?1:0;
935 
936  // octant 4
937  trace.info() << "octant 4\n";
938  DSS1 = DSS(-1,-2,Point(-2,-2),Point(-6,-4),Point(-2,-2),Point(-6,-4),Point(-3,-2),Point(-5,-3));
939  assert(DSS1.isValid());
940  DSS2 = DSS(-3,-5,Point(2,1),Point(-9,-6),Point(-2,-2),Point(-7,-5),Point(0,0),Point(-5,-3));
941  assert(DSS2.isValid());
942  res = DSS1.computeUnion(DSS2);
943  nb++;
944  nbok +=(res==DSS2)?1:0;
945 
946  // octant 5 - take octant3 - DSS(a,b...) -> DSS(-a,b...) + Point(x,y) -> Point(x,-y) + inverse lower and upper leaning points
947 
948  trace.endBlock();
949 
950  // DSS2 included in DSS1 + see unionComparisonTest below
951  trace.beginBlock("Simplest inclusion: DSS2 in DSS1");
952  // octant 0
953  trace.info() << "octant 0\n";
954  DSS1 = DSS(3,5,Point(-2,-1),Point(9,6),Point(2,2),Point(7,5),Point(0,0),Point(5,3));
955  DSS2 = DSS(1,2,Point(2,2),Point(6,4),Point(2,2),Point(6,4),Point(3,2),Point(5,3));
956  res = DSS1.computeUnion(DSS2);
957  nb++;
958  nbok +=(res==DSS1)?1:0;
959 
960  trace.endBlock();
961 
962  // DSS2 belongs to DSS1's supporting DSL
963 
964  trace.beginBlock("DSS2 belongs to DSS1's supporting DSL");
965  // octant 0
966  trace.info() << "octant 0 - no new leaning points\n";
967  DSS1 = DSS(3,7,Point(1,3),Point(12,7),Point(3,4),Point(10,7),Point(5,4),Point(12,7));
968  DSS2 = DSS(1,2,Point(14,8),Point(16,9),Point(15,9),Point(15,9),Point(14,8),Point(16,9));
969  res = DSS1.computeUnion(DSS2);
970  nb++;
971  nbok +=(res==DSS(3,7,Point(1,3),Point(16,9),Point(3,4),Point(10,7),Point(5,4),Point(12,7)))?1:0;
972  trace.info() << "(" << nbok << "/" << nb << ") "
973  << std::endl;
974 
975  trace.info() << "octant 0 - new leaning points in DSS2\n";
976  DSS1 = DSS(3,7,Point(1,3),Point(10,7),Point(3,4),Point(10,7),Point(5,4),Point(5,4));
977  DSS2 = DSS(1,2,Point(12,7),Point(17,10),Point(13,8),Point(17,10),Point(12,7),Point(16,9));
978  res = DSS1.computeUnion(DSS2);
979  nb++;
980  nbok +=(res==DSS(3,7,Point(1,3),Point(17,10),Point(3,4),Point(17,10),Point(5,4),Point(12,7)))?1:0;
981  trace.info() << "(" << nbok << "/" << nb << ") "
982  << std::endl;
983 
984  trace.info() << "octant 0 - new leaning points between DSS1 and DSS2\n";
985  DSS1 = DSS(3,7,Point(1,3),Point(10,7),Point(3,4),Point(10,7),Point(5,4),Point(5,4));
986  DSS2 = DSS(1,2,Point(13,8),Point(15,9),Point(13,8),Point(15,9),Point(14,8),Point(14,8));
987  res = DSS1.computeUnion(DSS2);
988  nb++;
989  nbok +=(res==DSS(3,7,Point(1,3),Point(15,9),Point(3,4),Point(10,7),Point(5,4),Point(12,7)))?1:0;
990  trace.info() << "(" << nbok << "/" << nb << ") "
991  << std::endl;
992 
993  trace.endBlock();
994 
995  // DSS1 belongs to DSS2 supporting DSL
996 
997  // DSS1 and DSS2 connected and union is part of a DSL -> see
998  // unionComparisonTest below
999 
1000  // DSS1 and DSS2 not connected but easy case and union is part of a
1001  // DSL -> see unionComparisonTest below
1002 
1003  trace.beginBlock("Not connected but easy case");
1004 
1005  trace.info() << "octant 2";
1006  DSS1 = DSS(1,5,Point(0,1),Point(5,2),Point(1,2),Point(1,2),Point(0,1),Point(5,2));
1007  DSS2 = DSS(1,4,Point(9,2),Point(14,3),Point(11,3),Point(11,3),Point(10,2),Point(14,3));
1008  res = DSS1.computeUnion(DSS2);
1009  nb++;
1010  nbok +=(res==DSS(1,10,Point(0,1),Point(14,3),Point(1,2),Point(11,3),Point(0,1),Point(10,2)))?1:0;
1011  trace.info() << "(" << nbok << "/" << nb << ") "
1012  << std::endl;
1013 
1014  trace.endBlock();
1015 
1016  // DSS1 and DSS2 not connected and union is part of a DSL
1017 
1018  trace.beginBlock("Not connected case");
1019 
1020  trace.info() << "octant 0\n";
1021  DSS1 = DSS(1,5,Point(0,1),Point(5,2),Point(1,2),Point(1,2),Point(0,1),Point(5,2));
1022  DSS2 = DSS(1,4,Point(9,2),Point(14,3),Point(11,3),Point(11,3),Point(10,2),Point(14,3));
1023  res = DSS1.computeUnion(DSS2);
1024  nb++;
1025  nbok +=(res==DSS(1,10,Point(0,1),Point(14,3),Point(1,2),Point(11,3),Point(0,1),Point(10,2)))?1:0;
1026  trace.info() << "(" << nbok << "/" << nb << ") "
1027  << std::endl;
1028 
1029  DSS1 = DSS(1,6,Point(0,1),Point(6,2),Point(1,2),Point(1,2),Point(0,1),Point(6,2));
1030  DSS2 = DSS(0,1,Point(13,3),Point(18,3),Point(13,3),Point(18,3),Point(13,3),Point(18,3));
1031  res = DSS1.computeUnion(DSS2);
1032  nb++;
1033  nbok +=(res==DSS(1,9,Point(0,1),Point(18,3),Point(1,2),Point(10,3),Point(0,1),Point(18,3)))?1:0;
1034  trace.info() << "(" << nbok << "/" << nb << ") "
1035  << std::endl;
1036 
1037  trace.info() << "octant 2\n";
1038 
1039  DSS1 = DSS(6,-1,Point(-1,0),Point(-2,6),Point(-2,1),Point(-2,1),Point(-1,0),Point(-2,6));
1040  DSS2 = DSS(1,0,Point(-3,13),Point(-3,18),Point(-3,13),Point(-3,18),Point(-3,13),Point(-3,18));
1041  res = DSS1.computeUnion(DSS2);
1042  nb++;
1043  nbok +=(res==DSS(9,-1,Point(-1,0),Point(-3,18),Point(-2,1),Point(-3,10),Point(-1,0),Point(-3,18)))?1:0;
1044  trace.info() << "(" << nbok << "/" << nb << ") "
1045  << std::endl;
1046 
1047 
1048 
1049  trace.endBlock();
1050 
1051  //-------------------------------------------------
1052  //---------- Union is not part of a DSL -----------
1053 
1054  trace.beginBlock("Union is not part of a DSL");
1055 
1056  // DSS1 and DSS2 not in the same octant
1057  trace.info() << "DSS1 and DSS2 are not in the same octant\n";
1058 
1059  DSS1 = DSS(1,3,Point(0,0),Point(3,1),Point(0,0),Point(3,1),Point(2,0),Point(2,0));
1060  DSS2 = DSS(1,-3,Point(6,2),Point(9,1),Point(6,2),Point(9,1),Point(8,2),Point(8,2));
1061  res = DSS1.computeUnion(DSS2);
1062  nb++;
1063  nbok +=(res==DSS(Point(0,0)))?1:0;
1064  trace.info() << "(" << nbok << "/" << nb << ") "
1065  << std::endl;
1066 
1067  // DSS1 and DSS2 connected and union is not part of a DSL
1068  trace.info() << "DSS1 and DSS2 are in the same octant and connected\n";
1069 
1070  DSS1 = DSS(1,3,Point(0,0),Point(4,2),Point(1,1),Point(4,2),Point(0,0),Point(3,1));
1071  DSS2 = DSS(1,5,Point(4,2),Point(9,3),Point(4,2),Point(9,3),Point(8,2),Point(8,2));
1072  res = DSS1.computeUnion(DSS2);
1073  nb++;
1074  nbok +=(res==DSS(Point(0,0)))?1:0;
1075  trace.info() << "(" << nbok << "/" << nb << ") "
1076  << std::endl;
1077 
1078 
1079  // DSS1 and DSS2 not connected but easy case and union is not part of a DSL
1080  trace.info() << "DSS1 and DSS1 are in the same octant, not connected but easy case anyway\n";
1081 
1082  DSS1 = DSS(-3,-1,Point(0,0),Point(-2,-5),Point(0,0),Point(-1,-3),Point(-1,-1),Point(-2,-4));
1083  DSS2 = DSS(-3,-1,Point(-2,-8),Point(-3,-11),Point(-2,-10),Point(-2,-10),Point(-2,-8),Point(-3,-11));
1084  res = DSS1.computeUnion(DSS2);
1085  nb++;
1086  nbok +=(res==DSS(Point(0,0)))?1:0;
1087  trace.info() << "(" << nbok << "/" << nb << ") "
1088  << std::endl;
1089 
1090  // DSS1 and DSS2 not connected and union is not part of a DSL
1091  trace.info() << "DSS1 and DSS2 are in the same octant but not connected\n";
1092 
1093  DSS1 = DSS(-3,-1,Point(0,0),Point(-2,-5),Point(0,0),Point(-1,-3),Point(-1,-1),Point(-2,-4));
1094  DSS2 = DSS(-3,-1,Point(-5,-8),Point(-6,-11),Point(-5,-10),Point(-5,-10),Point(-5,-8),Point(-6,-11));
1095  res = DSS1.computeUnion(DSS2);
1096  nb++;
1097  nbok +=(res==DSS(Point(0,0)))?1:0;
1098  trace.info() << "(" << nbok << "/" << nb << ") "
1099  << std::endl;
1100 
1101 
1102  trace.endBlock();
1103 
1104  return (nb==nbok);
1105 
1106 }
1107 
1108 int max(int a, int b)
1109 {
1110  return ((a>b)?a:b);
1111 }
1112 
1113 // General random test of the union of two DSSs
1114 // - compare the result with ArithmeticalDSS recognition algorithm for easy cases (connected or first point of
1115 // DSS2 and last point of DSS1 have the same ordinate) and inclusion cases
1116 // - otherwise, check DSS result validity + check that computed leaning points belong to the DSL when they should (when they are between A and B or between C and D)
1117 template <typename TCoordinate,typename TInteger, unsigned short adjacency>
1118 //template <typename DSS>
1119 bool unionComparisonTest(int modb, int modx, unsigned int nbtries)
1120 {
1122  typedef typename DSS::DSL DSL;
1123  typedef typename DSS::Point Point;
1124  typedef typename DSS::Integer Integer;
1125  typedef typename DSS::Vector Vector;
1126 
1127  unsigned int nb = 0;
1128  unsigned int nbok = 0;
1129  unsigned int nbEasy = 0;
1130 
1132 
1133  trace.beginBlock("General random test results");
1134  trace.emphase() << "Adjacency: " << adjacency << std::endl;
1135 
1136  for ( unsigned int i = 0; i < nbtries; ++i )
1137  {
1138  // Pick up a random DSL slope
1139  Integer b( rand() % modb + 1 );
1140  Integer a( rand() % b +1);
1141  while(ic.gcd(a,b) !=1)
1142  a =rand()%b +1; // |a| < |b|
1143 
1144  // Pick-up random signs for a and b
1145  a = a*((rand()%2==0)?1:-1);
1146  b = b*((rand()%2==0)?1:-1);
1147 
1148  if ( ic.gcd( a, b ) == 1 )
1149  {
1150 
1151  for ( unsigned int j = 0; j < 5; ++j )
1152  {
1153  // Pick up the DSL intercept
1154  Integer mu = rand() % (2*modb);
1155  DSL baseDSL(a,b,-mu);
1156 
1157  for (Integer x = 0; x < 10; ++x )
1158  {
1159  Integer elemMove = (b>0)?1:-1;
1160 
1161  // modx modulates the length of the subsegments
1162  // Pick up the beginning of the first subsegment
1163  Integer x1 = rand() % modx;
1164  // Pick up the end of the first subsegment
1165  Integer x2 = x1 + (modx + (rand() % modx))*elemMove;
1166 
1167  /************************************************/
1168 
1169  // Connected DSSs: The beginning of the second
1170  //subsegment is randomly set between x1 and x2 or just
1171  //after x2.
1172  //Integer x3 = x1 + (rand() % (x2-x1+1))*elemMove;
1173 
1174  // Disonnected DSSs: The beginning of the second subsegment is randomly set after x2.
1175  //Integer x3 = x2 + (rand() % (modb))*elemMove;
1176 
1177  // General Case
1178  Integer x3 = x1 + (rand() % (2*modb))*elemMove;
1179 
1180  // The length of the second segment is set to modx
1181  Integer x4 = x3 + modx*elemMove;
1182 
1183  Integer y1,y2,y3,y4;
1184  if(baseDSL.shift()[1] < 0)
1185  {
1186  y1 = ic.floorDiv(a*x1+mu,b); y2 = ic.floorDiv(a*x2+mu,b);
1187  y3 = ic.floorDiv(a*x3+mu,b); y4 = ic.floorDiv(a*x4+mu,b);
1188  }
1189  else
1190  {
1191  y1 = ic.ceilDiv(a*x1+mu,b); y2 = ic.ceilDiv(a*x2+mu,b);
1192  y3 = ic.ceilDiv(a*x3+mu,b); y4 = ic.ceilDiv(a*x4+mu,b);
1193  }
1194 
1195  Point A,B,C,D;
1196  DSL aDSL(baseDSL);
1197  //Randomly switch a and b to cover cases where |a| > |b|
1198  if(rand()%2)
1199  {
1200  aDSL = DSL(b,-a,-mu);
1201  A = Point(-y1,x1); B = Point(-y2,x2);
1202  C = Point(-y3,x3); D = Point(-y4,x4);
1203  }
1204  else
1205  {
1206  A = Point(x1,y1); B = Point(x2,y2);
1207  C = Point(x3,y3); D = Point(x4,y4);
1208  }
1209 
1210  // Computation of the parameters of the two segments
1211  // using the subsegment algorithm of [Roussillon,
1212  // 2014]
1213 
1214  DSS DSS1(aDSL,A,B);
1215  DSS DSS2(aDSL,C,D);
1216 
1217  nb++;
1218  // Computation of DSS1 \cup DSS2 using the union algorithm [Sivignon, 2014]
1219  DSS DSSres = DSS1.computeUnion(DSS2);
1220 
1221 
1222  // Compare the result with Arithmetical DSS recognition algorithm for easy cases
1223  Vector dir;
1224  if(abs(aDSL.a())<=abs(aDSL.b()))
1225  dir = Vector(0,1);
1226  else
1227  dir = Vector(1,0);
1228 
1229  if(aDSL.beforeOrEqual(C,B) || ic.dotProduct(C-B,dir)==0 || DGtal::ArithmeticalDSLKernel<TCoordinate,adjacency>::norm((C-B)[0], (C-B)[1])<=1 )
1230  {
1231  nbEasy++;
1232  // Computation of DSS1 \cup DSS2 using the
1233  // Arithmetical DSS algorithm: add points from B++
1234  // until D
1235  DSS DSSGroundTruth(DSS1);
1236  if(aDSL.before(B,D)) // otherwise [CD] is included
1237  // in [AB]
1238  {
1239  typename DSS::ConstIterator itbegin = aDSL.begin(B);
1240  typename DSS::ConstIterator itend = aDSL.end(D);
1241  typename DSS::ConstIterator it = itbegin++;
1242  while(it != itend)
1243  {
1244  DSSGroundTruth.extendFront(*it);
1245  it++;
1246  }
1247  }
1248 
1249  if(DSSres != DSSGroundTruth)
1250  {
1251 
1252  trace.info() << "DSS1 " << DSS1 << "\n" << "DSS2 " << DSS2 << std::endl;
1253  trace.info() << DSSres << std::endl;
1254  trace.info() << DSSGroundTruth << std::endl;
1255  trace.info() << "------------------\n";
1256  }
1257  nbok+=(DSSres == DSSGroundTruth)?1:0;
1258 
1259  }
1260  else
1261  { // for disconnected cases, check that all the leaning points of DSSres that are between A anb B or between C and D are in the DSL
1262 
1263  bool error = false;
1264  if((aDSL.beforeOrEqual(DSSres.Uf(),B) && !aDSL.isInDSL(DSSres.Uf())) || (!aDSL.before(DSSres.Uf(),C) && !aDSL.isInDSL(DSSres.Uf())))
1265  error = true;
1266  if((aDSL.beforeOrEqual(DSSres.Ul(),B) && !aDSL.isInDSL(DSSres.Ul())) || (!aDSL.before(DSSres.Ul(),C) && !aDSL.isInDSL(DSSres.Ul())))
1267  error = true;
1268  if((aDSL.beforeOrEqual(DSSres.Lf(),B) && !aDSL.isInDSL(DSSres.Lf())) || (!aDSL.before(DSSres.Lf(),C) && !aDSL.isInDSL(DSSres.Lf())))
1269  error = true;
1270  if((aDSL.beforeOrEqual(DSSres.Ll(),B) && !aDSL.isInDSL(DSSres.Ll())) || (!aDSL.before(DSSres.Ll(),C) && !aDSL.isInDSL(DSSres.Ll())))
1271  error = true;
1272 
1273  if(error || !DSSres.isValid() || DSSres==DSS(Point(0,0)))
1274  {
1275  trace.info() << "disconnected\n";
1276  trace.info() << "DSS1 " << DSS1 << "\n" << "DSS2 " << DSS2 << std::endl;
1277  trace.info() << DSSres << std::endl;
1278  trace.info() << "--------------------------------\n";
1279  }
1280  else
1281  nbok++;
1282 
1283  }
1284 
1285 
1286  }
1287  }
1288 
1289  }
1290  }
1291 
1292 
1293  trace.info() << "(" << nbok << "/" << nb << ") "
1294  << nbEasy << " easy cases." << std::endl;
1295  trace.endBlock();
1296  return (nb==nbok);
1297 }
1298 
1299 
1300 
1301 //---------------------------------------------------------------------------
1303 {
1304  unsigned int nb = 0;
1305  unsigned int nbok = 0;
1306 
1307  trace.beginBlock("Testing creation of a DSS from direction vector, two endpoints and one upper leaning point");
1308 
1310  typedef DSS8::Point Point;
1312  nb++;
1313  nbok += (Factory::createDSS(3,5,Point(-6,-4),Point(14,8),Point(5,3)) == DSS8(3,5,Point(-6,-4),Point(14,8),Point(-5,-3),Point(10,6),Point(-2,-2),Point(13,7)))?1:0;
1314 
1315  nb++;
1316  nbok += (Factory::createDSS(3,5,Point(0,0),Point(14,8),Point(3,2)) == DSS8(3,5,Point(0,0),Point(14,8),Point(3,2),Point(13,8),Point(1,0),Point(11,6)))?1:0;
1317 
1318  nb++;
1319  nbok += (Factory::createDSS(3,5,Point(-3,-2),Point(14,8),Point(3,2)) == DSS8(3,5,Point(-3,-2),Point(14,8),Point(-2,-1),Point(13,8),Point(1,0),Point(11,6)))?1:0;
1320 
1321  nb++;
1322  nbok += (Factory::createDSS(3,5,Point(0,0),Point(14,8),Point(3,2)) == DSS8(3,5,Point(0,0),Point(14,8),Point(3,2),Point(13,8),Point(1,0),Point(11,6)))?1:0;
1323 
1324  nb++;
1325  nbok += (Factory::createDSS(3,5,Point(0,0),Point(14,8),Point(3,2)) == DSS8(3,5,Point(0,0),Point(14,8),Point(3,2),Point(13,8),Point(1,0),Point(11,6)))?1:0;
1326 
1327  trace.endBlock();
1328 
1329  return (nb==nbok);
1330 }
1331 
1332 
1334 {
1335  unsigned int nbok = 0;
1336  unsigned int nb = 0;
1337 
1338  trace.beginBlock("Test patch bezoutVector/CreatePattern");
1339 
1342  typedef DSS8::Point Point;
1343  DSS8 dss = Factory::createPattern(DSS8::Point(0,0), DSS8::Point(-1,-3));
1344  nb++;
1345  nbok += (dss == DSS8(-3,-1,Point(0,0), Point(-1,-3), Point(0,0), Point(-1,-3), Point(-1,-1), Point(-1,-1)));
1346 
1347  dss = Factory::createPattern(DSS8::Point(0,0), DSS8::Point(10,-1));
1348  nb++;
1349  nbok += (dss == DSS8(-1,10, Point(0,0), Point(10,-1), Point(0,0), Point(10,-1), Point(1,-1), Point(1,-1)));
1350 
1351  trace.endBlock();
1352 
1353  return (nb == nbok);
1354 
1355 }
1356 
1357 
1359 int main( int argc, char** argv )
1360 {
1361  trace.beginBlock ( "Testing class ArithmeticalDSS" );
1362  trace.info() << "Args:";
1363  for ( int i = 0; i < argc; ++i )
1364  trace.info() << " " << argv[ i ];
1365  trace.info() << endl;
1366 
1367  //main operators
1368  bool res = mainTest<DGtal::ArithmeticalDSS<DGtal::int32_t> >()
1369 #ifdef WITH_BIGINTEGER
1371 #endif
1372  && mainTest<DGtal::NaiveDSS8<DGtal::int32_t> >()
1374  ;
1375 
1376  { //range services for 8 adjacency
1379  typedef DSS8::Point Point;
1380 
1381  res = res
1382  && rangeTest( Factory::createPattern(Point(0,0), Point(8,5)) )
1383  && rangeTest( Factory::createPattern(Point(0,0), Point(5,8)) )
1384  && rangeTest( Factory::createPattern(Point(0,0), Point(-5,8)) )
1385  && rangeTest( Factory::createPattern(Point(0,0), Point(-8,5)) )
1386  && rangeTest( Factory::createPattern(Point(0,0), Point(-8,-5)) )
1387  && rangeTest( Factory::createPattern(Point(0,0), Point(-5,-8)) )
1388  && rangeTest( Factory::createPattern(Point(0,0), Point(5,-8)) )
1389  && rangeTest( Factory::createPattern(Point(0,0), Point(8,-5)) )
1390  && rangeTest( Factory::createPattern(Point(0,0), Point(1,0)) )
1391  && rangeTest( Factory::createPattern(Point(0,0), Point(-1,0)) )
1392  && rangeTest( Factory::createPattern(Point(0,0), Point(0,1)) )
1393  && rangeTest( Factory::createPattern(Point(0,0), Point(0,-1)) )
1394  && rangeTest( Factory::createPattern(Point(0,0), Point(1,1)) )
1395  && rangeTest( Factory::createPattern(Point(0,0), Point(-1,1)) )
1396  && rangeTest( Factory::createPattern(Point(0,0), Point(1,-1)) )
1397  && rangeTest( Factory::createPattern(Point(0,0), Point(-1,-1)) )
1398  && rangeTest( Factory::createReversedPattern(Point(0,0), Point(8,5)) )
1399  && rangeTest( Factory::createReversedPattern(Point(0,0), Point(5,8)) )
1400  ;
1401  }
1402 
1403 
1404  { //range services for 4 adjacency
1407  typedef DSS4::Point Point;
1408 
1409  res = res
1410  && rangeTest( Factory::createPattern(Point(0,0), Point(8,5)) )
1411  && rangeTest( Factory::createPattern(Point(0,0), Point(5,8)) )
1412  && rangeTest( Factory::createPattern(Point(0,0), Point(-8,-5)) )
1413  && rangeTest( Factory::createPattern(Point(0,0), Point(-5,-8)) )
1414  && rangeTest( Factory::createPattern(Point(0,0), Point(5,-8)) )
1415  && rangeTest( Factory::createPattern(Point(0,0), Point(8,-5)) )
1416  && rangeTest( Factory::createPattern(Point(0,0), Point(1,0)) )
1417  && rangeTest( Factory::createPattern(Point(0,0), Point(-1,0)) )
1418  && rangeTest( Factory::createPattern(Point(0,0), Point(0,1)) )
1419  && rangeTest( Factory::createPattern(Point(0,0), Point(0,-1)) )
1420  && rangeTest( Factory::createReversedPattern(Point(0,0), Point(8,5)) )
1421  ;
1422  }
1423 
1424  {
1427  typedef DSS8::Point Point;
1428  res = res
1429  && compatibleStepsTest( Factory::createPattern(Point(0,0), Point(5,0)) )
1430  && compatibleStepsTest( Factory::createPattern(Point(0,0), Point(-5,0)) )
1431  && compatibleStepsTest( Factory::createPattern(Point(0,0), Point(0,5)) )
1432  && compatibleStepsTest( Factory::createPattern(Point(0,0), Point(0,-5)) )
1433  && compatibleStepsTest( Factory::createPattern(Point(0,0), Point(5,5)) )
1434  && compatibleStepsTest( Factory::createPattern(Point(0,0), Point(5,-5)) )
1435  && compatibleStepsTest( Factory::createPattern(Point(0,0), Point(-5,5)) )
1436  && compatibleStepsTest( Factory::createPattern(Point(0,0), Point(-5,-5)) )
1437  ;
1438  }
1439 
1440  {
1443  typedef DSS4::Point Point;
1444  res = res
1445  && compatibleStepsTest( Factory::createPattern(Point(0,0), Point(5,0)) )
1446  && compatibleStepsTest( Factory::createPattern(Point(0,0), Point(-5,0)) )
1447  && compatibleStepsTest( Factory::createPattern(Point(0,0), Point(0,5)) )
1448  && compatibleStepsTest( Factory::createPattern(Point(0,0), Point(0,-5)) )
1449  ;
1450  }
1451 
1452  res = res
1453  && updateTest<DGtal::ArithmeticalDSS<DGtal::int32_t> >()
1454 #ifdef WITH_BIGINTEGER
1456 #endif
1457  ;
1458 
1459  res = res
1460  && constructorsTest<DGtal::ArithmeticalDSS<DGtal::int32_t> >()
1461 #ifdef WITH_BIGINTEGER
1463 #endif
1464  && constructorsTest<DGtal::NaiveDSS8<DGtal::int32_t> >()
1466  ;
1467 
1468  { //subsegment
1469  res = res
1470  && comparisonSubsegment<NaiveDSL<DGtal::int32_t> >(5,8)
1472  && comparisonSubsegment<NaiveDSL<DGtal::int32_t> >(12,29)
1474  && comparisonSubsegment<NaiveDSL<DGtal::int32_t> >(-5,8)
1476  && comparisonSubsegment<NaiveDSL<DGtal::int32_t> >(5,-8)
1478  && comparisonSubsegment<NaiveDSL<DGtal::int32_t> >(-5,-8)
1480 
1481  && comparisonSubsegment<StandardDSL<DGtal::int32_t> >(5,8)
1483  && comparisonSubsegment<StandardDSL<DGtal::int32_t> >(-5,8)
1485  && comparisonSubsegment<StandardDSL<DGtal::int32_t> >(5,-8)
1487  && comparisonSubsegment<StandardDSL<DGtal::int32_t> >(-5,-8)
1489 #ifdef WITH_BIGINTEGER
1490  && comparisonSubsegment<StandardDSL<DGtal::int32_t, DGtal::BigInteger> >(5,8)
1491 #endif
1492  ;
1493  }
1494 
1495  { // createDSS
1496  res = res && createDSSTest();
1497  }
1498 
1499  { // Patch BezoutVector / CreatePattern
1500  res = res && testPatchCreatePattern();
1501  }
1502 
1503  { // union of two DSSs
1504  res = res && unionTest();
1505  res = res && unionComparisonTest<DGtal::int64_t,DGtal::int64_t,8>(43577,1276,200);
1506  res = res && unionComparisonTest<DGtal::int64_t, DGtal::int64_t, 4>(86731,6648,200);
1507  }
1508 
1509 
1510  trace.emphase() << ( res ? "Passed." : "Error." ) << endl;
1511  trace.endBlock();
1512  return res ? 0 : 1;
1513 }
1514 // //
Aim: Set of static methods that create digital straight segments (DSS) from some input parameters,...
Aim: This class represents a naive (resp. standard) digital straight segment (DSS),...
Integer ceilDiv(IntegerParamType na, IntegerParamType nb) const
Integer dotProduct(const Vector2I &u, const Vector2I &v) const
Integer gcd(IntegerParamType a, IntegerParamType b) const
Integer floorDiv(IntegerParamType na, IntegerParamType nb) const
Aim: This class is an alias of ArithmeticalDSS for naive DSL. It represents a naive digital straight ...
Aim: This class is an alias of ArithmeticalDSS for standard DSL. It represents a standard digital str...
Aim: This class represents a standard digital straight segment (DSS), ie. the sequence of simply 4-co...
void beginBlock(const std::string &keyword="")
std::ostream & emphase()
std::ostream & info()
double endBlock()
DigitalPlane::Point Vector
MyDigitalSurface::ConstIterator ConstIterator
DGtal is the top-level namespace which contains all DGtal functions and types.
Trace trace
Definition: Common.h:153
Aim: Small class that contains the code that depends on the arithmetical thickness (either naive or s...
Aim: Defines the concept describing a bidirectional const range.
Aim: Defines a predicate on a point.
Go to http://www.boost.org/doc/libs/1_52_0/libs/iterator/doc/BidirectionalTraversal....
Go to http://www.boost.org/doc/libs/1_52_0/libs/iterator/doc/ReadableIterator.html.
bool unionComparisonTest(int modb, int modx, unsigned int nbtries)
bool rangeTest(const DSS &dss)
bool updateTest()
int main(int argc, char **argv)
void retractionTest(const DSS &dss, unsigned int &nbok, unsigned int &nb, bool res=true)
bool unionTest()
void extensionTest(const DSS &dss, typename DSS::Point newPointToFront, typename DSS::Point newPointToBack, unsigned int &nbok, unsigned int &nb, const unsigned short int &code=0)
bool mainTest()
bool createDSSTest()
bool compatibleStepsTest(const DSS &dss)
bool comparisonSubsegment(const DSS &aDSS, typename DSS::Position x, typename DSS::Position y)
bool constructorsTest()
bool testPatchCreatePattern()
int max(int a, int b)
MyPointD Point
Definition: testClone2.cpp:383