DGtal  0.9.2
testArithmeticalDSL.cpp
1 
30 #include <iostream>
32 #include <boost/iterator/iterator_concepts.hpp>
33 #include "DGtal/base/Common.h"
34 #include "DGtal/kernel/CPointPredicate.h"
35 #include "DGtal/geometry/curves/ArithmeticalDSL.h"
37 
38 using namespace std;
39 using namespace DGtal;
40 
42 // Functions for testing class ArithmeticalDSL.
44 
49 template <typename DSL>
50 bool mainTest()
51 {
52  BOOST_CONCEPT_ASSERT(( concepts::CPointPredicate<DSL> ));
53 
54  typedef typename DSL::Point Point;
55 
56  unsigned int nbok = 0;
57  unsigned int nb = 0;
58 
59  trace.beginBlock ( "Main operators..." );
60 
61  //operateur constructeur, copie, affectation
62  trace.info() << "constructor, copy, assignement, equality" << std::endl;
63 
64  DSL dsl(0, 1, 0);
65  DSL dsl2 = dsl;
66  DSL dsl3(1, 1, 0);
67  DSL dsl4 = dsl3;
68  dsl3 = dsl2 = dsl;
69 
70  //egalite, difference
71  DSL dsl5(0, -1, 0);
72 
73  if ( (dsl == dsl2)
74  &&(dsl == dsl3)
75  &&(dsl != dsl4)
76  &&(dsl == dsl5) )
77  nbok++;
78  nb++;
79  trace.info() << "(" << nbok << "/" << nb << ") "
80  << std::endl;
81 
82  //validite
83  trace.info() << "valid dsl" << std::endl;
84  if ( dsl.isValid() && dsl3.isValid() && dsl5.isValid() )
85  nbok++;
86  nb++;
87  trace.info() << "(" << nbok << "/" << nb << ") "
88  << std::endl;
89 
90  DSL dsl6(0, 0, 1);
91 
92  trace.info() << "not valid dsl" << std::endl;
93  if (!dsl6.isValid())
94  nbok++;
95  nb++;
96 
97  trace.info() << "(" << nbok << "/" << nb << ") "
98  << std::endl;
99 
100  //accessors
101  trace.info() << "a,b,mu,omega accessors" << std::endl;
102 
103  if ( (dsl.a() == 0)&&(dsl.b() == 1)&&(dsl.mu() == 0)&&(dsl.omega() == 1) )
104  nbok++;
105  nb++;
106 
107  trace.info() << "(" << nbok << "/" << nb << ") "
108  << std::endl;
109 
110 
111  DSL dsl7(5, 8, 0);
112 
113  trace.info() << "remainder, position, tests" << std::endl;
114  trace.info() << dsl7 << std::endl;
115 
116  if ( (dsl7.isValid())
117  && (dsl7.remainder( Point(8,5) ) == 0)
118  &&(dsl7.remainder( Point(16,10) ) == 0)
119  &&(dsl7.remainder( Point(3,2) ) == -1)
120  &&(dsl7.remainder( Point(5,3) ) == 1) )
121  nbok++;
122  nb++;
123 
124  trace.info() << "(" << nbok << "/" << nb << ") "
125  << std::endl;
126 
127  if ( (dsl7.orthogonalPosition( Point(0,0) ) == 0)
128  &&(dsl7.orthogonalPosition( Point(8,5) ) == 89)
129  &&(dsl7.orthogonalPosition( Point(1,0) ) == 8)
130  &&(dsl7.orthogonalPosition( Point(-1,0) ) == -8) )
131  nbok++;
132  nb++;
133 
134  if ( ( dsl7.before( Point(0,0), Point(8,5) ) )
135  &&(!dsl7.before( Point(8,5), Point(0,0) ) )
136  &&( dsl7.beforeOrEqual( Point(0,0), Point(8,5) ) )
137  &&(!dsl7.beforeOrEqual( Point(8,5), Point(0,0) ) )
138  &&( dsl7.before( Point(-1,0), Point(1,0) ) )
139  &&( !dsl7.before( Point(1,0), Point(-1,0) ) )
140  &&( !dsl7.before( Point(8,5), Point(8,5) ) )
141  &&( dsl7.beforeOrEqual( Point(8,5), Point(8,5) ) )
142  )
143  nbok++;
144  nb++;
145 
146  trace.info() << "(" << nbok << "/" << nb << ") "
147  << std::endl;
148 
149  if ( (dsl7.isInDSL( Point(0,0) ))
150  &&(dsl7.isInDSL( Point(16,10) ))
151  &&(dsl7.isInDSL( Point(5,3) ))
152  &&(!dsl7.isInDSL( Point(3,2) )) )
153  nbok++;
154  nb++;
155 
156  trace.info() << "(" << nbok << "/" << nb << ") "
157  << std::endl;
158 
159  if ( (dsl7( Point(0,0) ))
160  &&(dsl7( Point(16,10) ))
161  &&(dsl7( Point(5,3) ))
162  &&(!dsl7( Point(3,2) ))
163  &&(!dsl7( Point(-1,0) ))
164  &&(dsl7( Point(-1,-1) )) )
165  nbok++;
166  nb++;
167 
168  trace.info() << "(" << nbok << "/" << nb << ") "
169  << std::endl;
170 
171  trace.info() << "shift" << std::endl;
172  if ( (dsl.remainder(dsl.shift()) == dsl.omega())
173  && (DSL::toCoordinate(dsl.omega()) == dsl.patternLength()) )
174  nbok++;
175  nb++;
176  trace.info() << "(" << nbok << "/" << nb << ") "
177  << std::endl;
178 
179  if ( (dsl7.getPoint() == Point(0,0))
180  &&(DSL(5,8,dsl7.omega()-1).getPoint() == Point(0,0)+dsl.shift())
181  &&(DSL(5,8,dsl7.omega()).getPoint() == Point(0,0)+dsl.shift())
182  &&(DSL(5,8,dsl7.omega()+1).getPoint() == Point(0,0)+2*dsl.shift())
183  &&(DSL(5,8,-dsl7.omega()+1).getPoint() == Point(0,0))
184  &&(DSL(5,8,-dsl7.omega()).getPoint() == Point(0,0)-dsl.shift())
185  &&(DSL(5,8,-dsl7.omega()-1).getPoint() == Point(0,0)-dsl.shift())
186  )
187  nbok++;
188  nb++;
189 
190  trace.info() << "(" << nbok << "/" << nb << ") "
191  << std::endl;
192 
193 
194  trace.endBlock();
195 
196  return nbok == nb;
197 }
198 
199 
201 
208 template <typename DSL>
209 bool rangeTest(const DSL& dsl)
210 {
211  typedef typename DSL::Point Point;
212 
213  unsigned int nbok = 0;
214  unsigned int nb = 0;
215 
216  trace.beginBlock ( "Range/Iterator services..." );
217  trace.info() << dsl << std::endl;
218 
219  Point origin = dsl.getPoint();
220  Point first = Point(origin[0]-dsl.b(), origin[1]-dsl.a());
221  Point last = Point(first[0]+dsl.b(), first[1]+dsl.a());
222  trace.info() << "from " << first << " to " << last << std::endl;
223 
224  if (dsl.isValid())
225  nbok++;
226  nb++;
227 
228  trace.info() << "(" << nbok << "/" << nb << ") "
229  << std::endl;
230 
231  {//forward pass
232  typedef typename DSL::ConstIterator I;
233  BOOST_CONCEPT_ASSERT(( boost_concepts::ReadableIteratorConcept<I> ));
234  BOOST_CONCEPT_ASSERT(( boost_concepts::RandomAccessTraversalConcept<I> ));
235  bool res = true;
236  int c = 0;
237  for (I it = dsl.begin(first), itEnd = dsl.end(last);
238  ( (it != itEnd)&&(res)&&(c<100) );
239  ++it, ++c)
240  {
241  trace.info() << "(" << it->operator[](0) << "," << it->operator[](1) << ") ";
242  if ( !dsl(*it) )
243  res = false;
244  }
245  trace.info() << " : " << c << " points " << std::endl;
246  trace.info() << std::endl;
247 
248  if ( (res)&&(c == (dsl.omega()+1)) )
249  nbok++;
250  nb++;
251 
252  trace.info() << "(" << nbok << "/" << nb << ") "
253  << std::endl;
254  }
255 
256  {//backward pass
257  typedef typename DSL::ConstReverseIterator I;
258  BOOST_CONCEPT_ASSERT(( boost_concepts::ReadableIteratorConcept<I> ));
259  BOOST_CONCEPT_ASSERT(( boost_concepts::RandomAccessTraversalConcept<I> ));
260  bool res = true;
261  int c = 0;
262  for (I it = dsl.rbegin(last), itEnd = dsl.rend(first);
263  ( (it != itEnd)&&(res)&&(c<100) );
264  ++it, ++c)
265  {
266  trace.info() << "(" << it->operator[](0) << "," << it->operator[](1) << ") ";
267  if ( !dsl(*it) )
268  res = false;
269  }
270  trace.info() << " : " << c << " points " << std::endl;
271  trace.info() << std::endl;
272 
273  if ( (res)&&(c == (dsl.omega()+1)) )
274  nbok++;
275  nb++;
276 
277  trace.info() << "(" << nbok << "/" << nb << ") "
278  << std::endl;
279  }
280 
281  {//random access services
282  typedef typename DSL::ConstIterator I;
283  BOOST_CONCEPT_ASSERT(( boost_concepts::ReadableIteratorConcept<I> ));
284  BOOST_CONCEPT_ASSERT(( boost_concepts::RandomAccessTraversalConcept<I> ));
285  bool res = true;
286  int c = 0;
287  I itBegin = dsl.begin(first);
288  for (I it = itBegin, itEnd = dsl.end(last);
289  ( (it != itEnd)&&(res)&&(c<100) );
290  ++it, ++c)
291  {
292  trace.info() << "(" << it->operator[](0) << "," << it->operator[](1) << ") " << it.remainder() << ", ";
293  I it2 = ( itBegin + c );
294  if ( (it != it2) || ((it2 - itBegin) != c) )
295  res = false;
296  }
297  int n = c;
298  trace.info() << " : " << c << " points " << std::endl;
299  trace.info() << std::endl;
300 
301  if (res)
302  nbok++;
303  nb++;
304 
305  trace.info() << "(" << nbok << "/" << nb << ") "
306  << std::endl;
307 
308  --n;
309  c = 0;
310  for (I it = (itBegin+n), itEnd = itBegin;
311  ( (it!=itEnd)&&(res)&&(c < 100) );
312  --it, ++c )
313  {
314  trace.info() << "(" << it->operator[](0) << "," << it->operator[](1) << ") " << it.remainder() << ", ";
315  I it2 = ( (itBegin+n) - c );
316  if ( (it != it2) || (((itBegin+n) - it2) != c) )
317  res = false;
318  }
319 
320  if (res)
321  nbok++;
322  nb++;
323 
324  trace.info() << "(" << nbok << "/" << nb << ") "
325  << std::endl;
326  }
327 
328 
329  trace.endBlock();
330 
331  return nbok == nb;
332 }
333 
334 
335 
336 template <typename DSL>
337 bool sameOctantTest(const DSL& dsl1, const DSL& dsl2)
338 {
339  trace.beginBlock ( "Test same octant" );
340  trace.info() << dsl1 << " " << dsl2 << std::endl;
341 
342  typename DSL::Octant::first_type oc;
343 
344  return dsl1.sameOctant(dsl2,&oc);
345 
346  trace.endBlock();
347 
348 
349 }
350 
351 
352 template <typename DSL>
353 typename DSL::Octant testOctant(const typename DSL::Coordinate & a, const typename DSL::Coordinate & b)
354 {
355 
356  DSL aDSL(a,b,0);
357  trace.info() << aDSL << std::endl;
358 
359  return aDSL.octant();
360 
361 }
362 
363 
364 
366 int main( int argc, char** argv )
367 {
368  trace.beginBlock ( "Testing class ArithmeticalDSL" );
369  trace.info() << "Args:";
370  for ( int i = 0; i < argc; ++i )
371  trace.info() << " " << argv[ i ];
372  trace.info() << endl;
373 
374  //main operators
375  bool res = mainTest<DGtal::ArithmeticalDSL<DGtal::int32_t> >()
376 #ifdef WITH_BIGINTEGER
378 #endif
379  && mainTest<DGtal::NaiveDSL<DGtal::int32_t> >()
380  && mainTest<DGtal::StandardDSL<DGtal::int32_t> >()
381  ;
382 
383  { //range services for 8 adjacency
385 
386  res = res
387  && rangeTest( DSL(5, 8, 16) )
388  && rangeTest( DSL(8, 5, 14) )
389  && rangeTest( DSL(5, -8, 14) )
390  && rangeTest( DSL(8, -5, 14) )
391  && rangeTest( DSL(-5, 8, 14) )
392  && rangeTest( DSL(-8, 5, 14) )
393  && rangeTest( DSL(-5, -8, 14) )
394  && rangeTest( DSL(-8, -5, 14) )
395  && rangeTest( DSL(1, 0, 14) )
396  && rangeTest( DSL(0, -1, 14) )
397  && rangeTest( DSL(0, 1, 14) )
398  && rangeTest( DSL(-1, 0, 14) )
399  && rangeTest( DSL(1, 1, 14) )
400  && rangeTest( DSL(1, -1, 14) )
401  && rangeTest( DSL(-1, 1, 14) )
402  && rangeTest( DSL(-1, -1, 14) )
403  ;
404  }
405 
406 
407  { //range services for 4 adjacency
409 
410  res = res
411  && rangeTest( DSL(5, 8, -16) )
412  && rangeTest( DSL(8, 5, -17) )
413  && rangeTest( DSL(5, -8, -17) )
414  && rangeTest( DSL(8, -5, -17) )
415  && rangeTest( DSL(-5, 8, -17) )
416  && rangeTest( DSL(-8, 5, -17) )
417  && rangeTest( DSL(-5, -8, -17) )
418  && rangeTest( DSL(-8, -5, -17) )
419  && rangeTest( DSL(1, 0, -17) )
420  && rangeTest( DSL(0, -1, -17) )
421  && rangeTest( DSL(0, 1, -17) )
422  && rangeTest( DSL(-1, 0, -17) )
423  ;
424  }
425 
426 
427  { // same octant test
429 
430  res = res
431  && sameOctantTest(DSL(5,8,16),DSL(1,2,3))==true
432  && sameOctantTest(DSL(5,8,16),DSL(2,1,3))==false
433  && sameOctantTest(DSL(2,2,16),DSL(6,3,3))==true
434  && sameOctantTest(DSL(2,2,16),DSL(3,3,3))==true
435  && sameOctantTest(DSL(5,-8,16),DSL(0,-2,3))==true
436  && sameOctantTest(DSL(5,8,16),DSL(-2,1,3))==false
437  ;
438  }
439 
440  // ---------------- octant tests -------------------------
441 
442  {
444  typedef DSL::Octant Octant;
445 
446  trace.beginBlock("Test octant computation");
447 
448  res = res
449  && testOctant<DSL>(0,0) == Octant(-1,-1)
450  && testOctant<DSL>(0,5) == Octant(0,7)
451  && testOctant<DSL>(0,-5) == Octant(3,4)
452  && testOctant<DSL>(5,0) == Octant(1,2)
453  && testOctant<DSL>(-5,0) == Octant(5,6)
454  && testOctant<DSL>(1,1) == Octant(0,1)
455  && testOctant<DSL>(1,-1) == Octant(2,3)
456  && testOctant<DSL>(-1,1) == Octant(6,7)
457  && testOctant<DSL>(-1,-1) == Octant(4,5)
458  ;
459 
460  }
461 
462 #ifdef WITH_BIGINTEGER
463  {
465  res = res && rangeTest( DSL(5, 8, -26) ) && rangeTest( DSL(5, 8, 13) )
466  && rangeTest( DSL(5, 8, -17) ) && rangeTest( DSL(5, 8, 11313) );
467  }
468  // Warning: BOOST_CONCEPT_ASSERT(( boost_concepts::RandomAccessTraversalConcept<I> ));
469  // does not accept DGtal::BigInteger as a difference type for random access iterators
470  // because it uses methods is_signed and is_integer of std::numeric_limits
471  // { //does not compile
472  // typedef DGtal::ArithmeticalDSL<DGtal::BigInteger, DGtal::BigInteger, 4> DSL;
473  // res = res && rangeTest( DSL(5, 8, 123654) );
474  // }
475 #endif
476 
477  trace.emphase() << ( res ? "Passed." : "Error." ) << endl;
478  trace.endBlock();
479  return res ? 0 : 1;
480 }
481 // //
void beginBlock(const std::string &keyword="")
Go to http://www.boost.org/doc/libs/1_52_0/libs/iterator/doc/RandomAccessTraversal.html.
Trace trace
Definition: Common.h:130
STL namespace.
double endBlock()
Aim: Defines a predicate on a point.
std::ostream & emphase()
Aim: This class is an alias of ArithmeticalDSS for standard DSL. It represents a standard digital str...
DGtal is the top-level namespace which contains all DGtal functions and types.
std::ostream & info()
Aim: This class represents a naive (resp. standard) digital straight line (DSL), ie. the set of digital points such that with , and (resp. ). Note that any DSL such that (resp. ) is simply 8-connected (resp. 4-connected).
Go to http://www.boost.org/doc/libs/1_52_0/libs/iterator/doc/ReadableIterator.html.