DGtal  0.9.3
testArithmeticalDSSComputer.cpp
Go to the documentation of this file.
1 
38 #include <iostream>
39 #include <iterator>
40 #include <cstdio>
41 #include <cmath>
42 #include <fstream>
43 #include <vector>
44 
45 #include "DGtal/base/Common.h"
46 #include "DGtal/base/Exceptions.h"
47 #include "DGtal/kernel/SpaceND.h"
48 #include "DGtal/kernel/domains/HyperRectDomain.h"
49 #include "DGtal/geometry/curves/ArithmeticalDSSComputer.h"
50 #include "DGtal/io/boards/Board2D.h"
51 
52 #include "DGtal/geometry/curves/CDynamicBidirectionalSegmentComputer.h"
53 #include "DGtal/io/boards/CDrawableWithBoard2D.h"
54 
55 using namespace DGtal;
56 using namespace std;
57 using namespace LibBoard;
58 
60 // Functions for testing class ArithmeticalDSSComputer.
62 
67 {
68 
69  typedef PointVector<2,int> Point;
70  typedef std::vector<Point>::iterator Iterator;
71  typedef ArithmeticalDSSComputer<Iterator,int,4> DSS4Computer;
72 
73  std::vector<Point> contour;
74  contour.push_back(Point(0,0));
75  contour.push_back(Point(1,0));
76  contour.push_back(Point(1,1));
77  contour.push_back(Point(2,1));
78  contour.push_back(Point(2,1));
79  contour.push_back(Point(3,1));
80  contour.push_back(Point(3,2));
81  contour.push_back(Point(4,2));
82  contour.push_back(Point(5,2));
83  contour.push_back(Point(6,2));
84  contour.push_back(Point(6,3));
85  contour.push_back(Point(6,4));
86 
87 
88  // Adding step
89  trace.beginBlock("Add points while it is possible and draw the result");
90 
91  DSS4Computer theDSS4Computer;
92  theDSS4Computer.init( contour.begin() );
93  trace.info() << theDSS4Computer << std::endl;
94 
95  while ( (theDSS4Computer.end() != contour.end())
96  &&(theDSS4Computer.extendFront()) ) {}
97 
98  trace.info() << theDSS4Computer << std::endl;
99 
100  DSS4Computer::Primitive theDSS4 = theDSS4Computer.primitive();
102 
103  Board2D board;
104  board.setUnit(Board::UCentimeter);
105 
106  board << SetMode(domain.className(), "Grid")
107  << domain;
108  board << SetMode("PointVector", "Grid");
109 
110  board << SetMode(theDSS4.className(), "Points")
111  << theDSS4;
112  board << SetMode(theDSS4.className(), "BoundingBox")
113  << theDSS4;
114 
115  board.saveSVG("DSS4.svg");
116 
117 
118  trace.endBlock();
119 
120  return true;
121 }
122 
128 {
129 
130  typedef PointVector<2,int> Point;
131  typedef std::vector<Point>::iterator Iterator;
132  typedef ArithmeticalDSSComputer<Iterator,int,8> DSS8Computer;
133 
134  std::vector<Point> boundary;
135  boundary.push_back(Point(0,0));
136  boundary.push_back(Point(1,1));
137  boundary.push_back(Point(2,1));
138  boundary.push_back(Point(3,2));
139  boundary.push_back(Point(4,2));
140  boundary.push_back(Point(5,2));
141  boundary.push_back(Point(6,3));
142  boundary.push_back(Point(6,4));
143 
144  // Good Initialisation
145  trace.beginBlock("Add points while it is possible and draw the result");
146  DSS8Computer theDSS8Computer;
147  theDSS8Computer.init( boundary.begin() );
148 
149  trace.info() << theDSS8Computer << std::endl;
150 
151  while ( (theDSS8Computer.end()!=boundary.end())
152  &&(theDSS8Computer.extendFront()) ) {}
153 
154  trace.info() << theDSS8Computer << std::endl;
155 
156  DSS8Computer::Primitive theDSS8 = theDSS8Computer.primitive();
158 
159  Board2D board;
160  board.setUnit(Board::UCentimeter);
161 
162  board << SetMode(domain.className(), "Paving")
163  << domain;
164  board << SetMode("PointVector", "Both");
165 
166  board << SetMode(theDSS8.className(), "Points")
167  << theDSS8;
168  board << SetMode(theDSS8.className(), "BoundingBox")
169  << theDSS8;
170 
171  board.saveSVG("DSS8.svg");
172 
173  trace.endBlock();
174 
175  return true;
176 }
177 
183 {
184 
185  typedef PointVector<2,int> Point;
186 
187  std::vector<Point> contour;
188  contour.push_back(Point(0,0));
189  contour.push_back(Point(1,0));
190  contour.push_back(Point(1,1));
191  contour.push_back(Point(2,1));
192  contour.push_back(Point(3,1));
193  contour.push_back(Point(3,2));
194  contour.push_back(Point(4,2));
195  contour.push_back(Point(5,2));
196  contour.push_back(Point(6,2));
197  contour.push_back(Point(6,3));
198 
199  typedef std::vector<Point>::const_iterator Iterator;
200  typedef std::vector<Point>::const_reverse_iterator ReverseIterator;
202  typedef ArithmeticalDSSComputer<ReverseIterator,int,4> ReverseComputer;
203  typedef Computer::Primitive Primitive;
204 
205  std::deque<Primitive> v1,v2;
206 
207  trace.beginBlock("Checking consistency between adding and removing");
208 
209  //forward scan and store each DSS
210  trace.info() << "forward scan" << std::endl;
211 
212  Computer c;
213  c.init( contour.begin() );
214  v1.push_back( c.primitive() );
215 
216  while ( (c.end() != contour.end())
217  &&(c.extendFront()) ) {
218  v1.push_back( c.primitive() );
219  }
220  ASSERT(contour.size() == v1.size());
221 
222  //backward scan
223  trace.info() << "backward scan" << std::endl;
224 
225  ReverseComputer rc;
226  rc.init( contour.rbegin() );
227 
228  while ( (rc.end() != contour.rend())
229  &&(rc.extendFront()) )
230  {
231  }
232 
233  //removing step and store each DSS for comparison
234  trace.info() << "removing" << std::endl;
235 
236  v2.push_front( rc.primitive() );
237  while (rc.retractBack()) {
238  v2.push_front( rc.primitive() );
239  }
240  ASSERT(v1.size() == v2.size());
241 
242  //comparison
243  trace.info() << "comparison" << std::endl;
244 
245  bool isOk = true;
246  for (unsigned int k = 0; k < v1.size(); k++) {
247  if (v1.at(k) != v2.at(k))
248  isOk = false;
249  trace.info() << "DSS :" << k << std::endl;
250  trace.info() << v1.at(k) << std::endl << v2.at(k) << std::endl;
251  }
252 
253  if (isOk)
254  trace.info() << "ok for the " << v1.size() << " DSS" << std::endl;
255  else
256  trace.info() << "failure" << std::endl;
257 
258  trace.endBlock();
259 
260  return isOk;
261 }
262 
263 template<typename Iterator>
264 bool testIsInsideForOneQuadrant(const Iterator& k, const Iterator& l, const Iterator& ite)
265 {
266  ASSERT(k < l);
267  ASSERT(l < ite);
268 
270  DSS4 theDSS4;
271 
272  theDSS4.init( k );
273  while ( (theDSS4.end() != l )
274  &&(theDSS4.extendFront()) ) {}
275 
276  ASSERT( theDSS4.isValid() );
277 
278  //all DSS points are in the DSS
279  bool flagIsInside = true;
280  for (Iterator i = theDSS4.begin(); i != theDSS4.end(); ++i)
281  {
282  if ( !theDSS4.isInDSS(i) )
283  flagIsInside = false;
284  }
285  //all other points are not in the DSS
286  bool flagIsOutside = true;
287  for (Iterator i = l; i != ite; ++i)
288  {
289  if ( theDSS4.isInDSS(i) )
290  flagIsOutside = false;
291  }
292  return (flagIsInside && flagIsOutside);
293 }
294 
299 {
300 
301  typedef PointVector<2,int> Point;
302  typedef std::vector<Point>::iterator Iterator;
303  typedef std::vector<Point>::reverse_iterator ReverseIterator;
304 
305  int nb = 0;
306  int nbok = 0;
307 
308  std::vector<Point> contour;
309  contour.push_back(Point(0,0));
310  contour.push_back(Point(1,1));
311  contour.push_back(Point(2,1));
312  contour.push_back(Point(3,1));
313  contour.push_back(Point(4,1));
314  contour.push_back(Point(4,2));
315  contour.push_back(Point(5,2));
316  contour.push_back(Point(6,2));
317  contour.push_back(Point(6,3));
318  contour.push_back(Point(7,3));
319 
320  std::vector<Point> contour2;
321  contour2.push_back(Point(0,0));
322  contour2.push_back(Point(1,-1));
323  contour2.push_back(Point(2,-1));
324  contour2.push_back(Point(3,-1));
325  contour2.push_back(Point(4,-1));
326  contour2.push_back(Point(4,-2));
327  contour2.push_back(Point(5,-2));
328  contour2.push_back(Point(6,-2));
329  contour2.push_back(Point(6,-3));
330  contour2.push_back(Point(7,-3));
331 
332  trace.beginBlock("isInside tests for each of the four quadrants");
333  { //Quadrant 1
334  Iterator itb = contour.begin() + 1;
335  Iterator ite = itb + 8;
336  if (testIsInsideForOneQuadrant(itb, ite, contour.end()) )
337  nbok++;
338  nb++;
339  trace.info() << nbok << " / " << nb << " quadrants" << std::endl;
340  }
341 
342  { //quadrant 2
343  ReverseIterator itb = contour2.rbegin() + 1;
344  ReverseIterator ite = itb + 8;
345  if (testIsInsideForOneQuadrant(itb, ite, contour2.rend()) )
346  nbok++;
347  nb++;
348  trace.info() << nbok << " / " << nb << " quadrants" << std::endl;
349  }
350 
351  { //quadrant 3
352  ReverseIterator itb = contour.rbegin() + 1;
353  ReverseIterator ite = itb + 8;
354  if (testIsInsideForOneQuadrant(itb, ite, contour.rend()) )
355  nbok++;
356  nb++;
357  trace.info() << nbok << " / " << nb << " quadrants" << std::endl;
358  }
359 
360  { //quadrant 4
361  Iterator itb = contour2.begin() + 1;
362  Iterator ite = itb + 8;
363  if (testIsInsideForOneQuadrant(itb, ite, contour2.end()) )
364  nbok++;
365  nb++;
366  trace.info() << nbok << " / " << nb << " quadrants" << std::endl;
367  }
368  trace.endBlock();
369 
370  return (nb == nbok);
371 }
372 
373 #ifdef WITH_BIGINTEGER
374 
378 bool testBIGINTEGER()
379 {
380  bool flag = false;
381 
382 
383  typedef DGtal::BigInteger Coordinate;
385  typedef std::vector<Point>::iterator Iterator;
387 
388 
389 
390  trace.beginBlock("Add some points of big coordinates");
391 
392  std::vector<Point> contour;
393  contour.push_back(Point(1000000000,1000000000));
394  contour.push_back(Point(1000000001,1000000000));
395  contour.push_back(Point(1000000002,1000000000));
396  contour.push_back(Point(1000000003,1000000000));
397  contour.push_back(Point(1000000003,1000000001));
398  contour.push_back(Point(1000000004,1000000001));
399  contour.push_back(Point(1000000005,1000000001));
400  contour.push_back(Point(1000000005,1000000002));
401 
402  DSS4 theDSS4;
403  theDSS4.init( contour.begin() );
404  while ( (theDSS4.end() != contour.end())
405  &&(theDSS4.extendFront()) ) {}
406 
407  trace.info() << theDSS4 << " " << theDSS4.isValid() << std::endl;
408 
409  Coordinate mu;
410  mu = "-3000000000";
411  if( (theDSS4.a() == 2)
412  &&(theDSS4.b() == 5)
413  &&(theDSS4.mu() == mu)
414  &&(theDSS4.omega() == 7) ) {
415  flag = true;
416  } else {
417  flag = false;
418  }
419 
420  trace.endBlock();
421 
422  return flag;
423 }
424 
425 #endif
426 
433 {
434 
435  typedef PointVector<2,int> Point;
436  typedef std::vector<Point>::iterator Iterator;
438 
439  std::vector<Point> boundary;
440  boundary.push_back(Point(10,10));
441  boundary.push_back(Point(10,11));
442  boundary.push_back(Point(11,11));
443 
444  trace.beginBlock("test Corner with 8-adjacency");
445 
446  DSS8 theDSS8;
447  theDSS8.init(boundary.begin());
448  std::cerr << theDSS8 << std::endl;
449  theDSS8.extendFront();
450  std::cerr << theDSS8 << std::endl;
451  bool res = ( !theDSS8.extendFront() );
452  std::cerr << theDSS8 << std::endl;
453 
454  trace.endBlock();
455 
456  return res;
457 }
458 
459 
460 
462 {
463  typedef PointVector<2,int> Point;
464  typedef std::vector<Point>::iterator Iterator;
465  typedef ArithmeticalDSSComputer<Iterator,int,8> ArithDSS;
467 }
468 
469 
470 int main(int argc, char **argv)
471 {
472 
473  trace.beginBlock ( "Testing class ArithmeticalDSSComputer" );
474  trace.info() << "Args:";
475  for ( int i = 0; i < argc; ++i )
476  trace.info() << " " << argv[ i ];
477  trace.info() << endl;
478 
479 
480  {//concept checking
482  }
483 
484  bool res = testDSS4drawing()
485  && testDSS8drawing()
487  && testCorner()
488 #ifdef WITH_BIGINTEGER
489  && testBIGINTEGER()
490 #endif
491  && testIsInside()
492  ;
493  trace.emphase() << ( res ? "Passed." : "Error." ) << endl;
494  trace.endBlock();
495 
496  return res ? 0 : 1;
497 
498 }
void beginBlock(const std::string &keyword="")
const Domain domain(Point(1, 2), Point(6, 5))
Trace trace
Definition: Common.h:137
bool testIsInsideForOneQuadrant(const Iterator &k, const Iterator &l, const Iterator &ite)
void init(const ConstIterator &it)
bool testExtendRetractFront()
This class adapts any bidirectional iterator so that operator++ calls operator-- and vice versa...
Aim: Parallelepidec region of a digital space, model of a &#39;CDomain&#39;.
STL namespace.
double endBlock()
bool testDSS8drawing()
int main(int argc, char **argv)
Aim: Implements basic operations that will be used in Point and Vector classes.
Definition: PointVector.h:141
mpz_class BigInteger
Multi-precision integer with GMP implementation.
Definition: BasicTypes.h:79
void saveSVG(const char *filename, PageSize size=Board::BoundingBox, double margin=10.0) const
Definition: Board.cpp:1012
Aim: This class is a wrapper around ArithmeticalDSS that is devoted to the dynamic recognition of dig...
std::ostream & emphase()
void testArithmeticalDSSComputerConceptChecking()
std::string className() const
DGtal is the top-level namespace which contains all DGtal functions and types.
MyPointD Point
Definition: testClone2.cpp:383
std::ostream & info()
Modifier class in a Board2D stream. Useful to choose your own mode for a given class. Realizes the concept CDrawableWithBoard2D.
Definition: Board2D.h:247
bool testDSS4drawing()
void setUnit(Unit unit)
Definition: Board.cpp:240
Aim: Defines the concept describing a dynamic and bidirectional segment computer, ie...
Aim: This class specializes a &#39;Board&#39; class so as to display DGtal objects more naturally (with <<)...
Definition: Board2D.h:70