DGtal  0.9.3
testLatticePolytope2D.cpp
Go to the documentation of this file.
1 
30 #include <iostream>
32 
33 //#define DEBUG_LatticePolytope2D
34 
35 #include "DGtal/base/Common.h"
36 #include "DGtal/arithmetic/LatticePolytope2D.h"
37 #include "DGtal/shapes/Shapes.h"
38 #include "DGtal/io/boards/Board2D.h"
39 
41 
42 using namespace std;
43 using namespace DGtal;
44 
46 // Functions for testing class LatticePolytope2D.
48 
49 template <typename LatticePolytope2D>
50 bool
52  typename LatticePolytope2D::HalfSpace hs )
53 {
54  trace.beginBlock ( "Check cut, see <cip.eps> and <cip2.eps>" );
55  typedef typename LatticePolytope2D::Domain Domain;
58 
59  Domain d = cip.boundingBoxDomain();
60 #ifdef DEBUG_LatticePolytope2D
61  Board2D board;
62  board << SetMode( d.className(), "Grid" ) << d;
63  DigitalSet aSet( d );
65  Color col1( 100, 100, 255 );
66  Color col2( 180, 180, 255 );
67  board << CustomStyle( aSet.className(), new CustomColors( col1, col2 ) )
68  << aSet;
69  board << SetMode( cip.className(), "Transparent" ) << cip;
70  board.saveEPS( "cip.eps" );
71  board.clear();
72 #endif
73 
74  DigitalSet cipSet( d );
75  DigitalSet cipSet2( d );
76  cip.getIncludedDigitalPoints( cipSet );
77  cip.cut( hs );
78  cip.getIncludedDigitalPoints( cipSet2 );
79 #ifdef DEBUG_LatticePolytope2D
80  board << SetMode( d.className(), "Grid" ) << d;
81  board << CustomStyle( aSet.className(), new CustomColors( col1, col2 ) )
82  << cipSet;
83  board << CustomStyle( aSet.className(), new CustomColors( Color( 255, 180, 20 ), Color( 200, 170, 0 ) ) )
84  << cipSet2;
85  board << SetMode( cip.className(), "Transparent" ) << cip;
86  board.saveEPS( "cip2.eps" );
87 #endif
88 
89  unsigned int nbok = 0;
90  unsigned int nb = 0;
91  for ( ConstIterator it = cipSet2.begin(), it_end = cipSet2.end();
92  it != it_end; ++it )
93  {
94  nbok += ( cipSet.find( *it ) != cipSet.end() ) ? 1 : 0;
95  ++nb;
96  nbok += hs( *it );
97  ++nb;
98  }
99  for ( ConstIterator it = cipSet.begin(), it_end = cipSet.end();
100  it != it_end; ++it )
101  {
102  if ( cipSet2.find( *it ) == cipSet2.end() )
103  nbok += ! hs( *it );
104  else
105  nbok += hs( *it );
106  ++nb;
107  }
108  trace.info() << "(" << nbok << "/" << nb << ")"
109  << " cip.size()=" << cip.size()
110  << " #before=" << cipSet.size()
111  << " #after=" << cipSet2.size()
112  << std::endl;
113  trace.endBlock();
114  return nbok == nb;
115 }
116 
121 template <typename Space>
123 {
124  unsigned int nbok = 0;
125  unsigned int nb = 0;
126 
127  trace.beginBlock ( "Testing block LatticePolytope2D area and centroid" );
128  typedef typename Space::Point Point;
129  typedef typename Space::Vector Vector;
130  typedef typename Space::Integer Integer;
131  typedef LatticePolytope2D<Space> CIP;
132  typedef typename CIP::Point3I Point3I;
133  typedef typename CIP::Domain Domain;
134  typedef typename CIP::HalfSpace HalfSpace;
135  typedef typename CIP::Iterator Iterator;
136  typedef typename DigitalSetSelector< Domain, BIG_DS+HIGH_BEL_DS >::Type DigitalSet;
137 
138  CIP cip;
139  cip.pushBack( Point( 0, 0 ) );
140  cip.pushBack( Point( 5, 0 ) );
141  cip.pushBack( Point( 0, 3 ) );
142  Integer area2 = cip.twiceArea();
143  trace.info() << "- 2*area = " << area2 << std::endl;
144  ++nb, nbok += ( area2 == 15 ) ? 1 : 0;
145  trace.info() << "(" << nbok << "/" << nb << ") "
146  << "2*area == 15" << std::endl;
147  Point3I c = cip.centroid( area2 );
148  trace.info() << "- centroid = " << c << std::endl;
149  ++nb, nbok += ( c == Point3I( 75, 45, 45 ) ) ? 1 : 0;
150  trace.info() << "(" << nbok << "/" << nb << ") "
151  << "centroid == [75,45,45]" << std::endl;
152  Domain d = cip.boundingBoxDomain();
153  trace.info() << "- domain = " << d << std::endl;
154  trace.endBlock();
155 
156  trace.beginBlock ( "Output LatticePolytope2D in <cip.eps>" );
157  cip.pushBack( Point( -4, 4 ) );
158  cip.pushBack( Point( -7, 2 ) );
159  cip.pushBack( Point( -5, 1 ) );
160  Board2D board;
161  d = cip.boundingBoxDomain();
162  board << SetMode( d.className(), "Grid" ) << d;
163  DigitalSet aSet( d );
164  HalfSpace h( Vector( 1, 3 ), 8 );
165  //HalfSpace h = cip.halfSpace( ++cip.begin() );
167  Color col1( 100, 100, 255 );
168  Color col2( 180, 180, 255 );
169  board << CustomStyle( aSet.className(), new CustomColors( col1, col2 ) )
170  << aSet;
171  cip.getIncludedDigitalPoints( aSet );
172  board << CustomStyle( aSet.className(), new CustomColors( Color( 255, 180, 20 ), Color( 200, 130, 0 ) ) )
173  << aSet;
174  board << SetMode( cip.className(), "Transparent" ) << cip;
175  Iterator itA1, itB2;
176  //SizeCouple nbs =
177  cip.findCut( itA1, itB2, h );
178  Iterator itB1 = itA1; ++itB1;
179  if ( itB1 == cip.end() ) itB1 = cip.begin();
180  Iterator itA2 = itB2; ++itA2;
181  if ( itA2 == cip.end() ) itA2 = cip.begin();
182  Color col3( 0, 255, 0 );
183  Color col4( 255, 0, 0 );
184  board << CustomStyle( Point().className(), new CustomColors( col3, col3 ) )
185  << *itA1 << *itA2;
186  board << CustomStyle( Point().className(), new CustomColors( col4, col4 ) )
187  << *itB1 << *itB2;
188  board.saveEPS( "cip.eps" );
189  board.saveSVG( "cip.svg" );
190  trace.endBlock();
191 
192  trace.beginBlock ( "Output cut LatticePolytope2D in <cip2.eps>" );
193  board.clear();
194  board << SetMode( d.className(), "Grid" ) << d;
195  board << SetMode( cip.className(), "Transparent" ) << cip;
196  bool wasCut = cip.cut( h );
197  FATAL_ERROR(wasCut);
198  board << SetMode( cip.className(), "Filled" ) << cip;
199  board.saveEPS( "cip2.eps" );
200  board.saveSVG( "cip2.svg" );
201  trace.endBlock();
202 
203  checkCut( cip, HalfSpace( Vector( -2, 3 ), 4 ) );
204 
205  return nbok == nb;
206 }
207 
208 int myRand( int nb )
209 {
210  return rand() % nb;
211 }
212 
217 template <typename Space>
219 {
220  unsigned int nbok = 0;
221  unsigned int nb = 0;
222 
223  trace.beginBlock ( "Testing block LatticePolytope2D area and centroid" );
224  typedef typename Space::Point Point;
225  typedef typename Space::Vector Vector;
226  typedef typename Space::Integer Integer;
227  typedef LatticePolytope2D<Space> CIP;
228  typedef typename CIP::Point3I Point3I;
229  typedef typename CIP::Domain Domain;
230  typedef typename CIP::HalfSpace HalfSpace;
231 
232  CIP cip;
233  cip.pushBack( Point( 0, 0 ) );
234  cip.pushBack( Point( 8, -3 ) );
235  cip.pushBack( Point( 17, 2 ) );
236  cip.pushBack( Point( 21, 13 ) );
237  cip.pushBack( Point( 13, 19 ) );
238  cip.pushBack( Point( 6, 17 ) );
239  cip.pushBack( Point( -3, 6 ) );
240  Integer area2 = cip.twiceArea();
241  trace.info() << "- 2*area = " << area2 << std::endl;
242  Point3I c = cip.centroid( area2 );
243  trace.info() << "- centroid = " << c << std::endl;
244  Domain d = cip.boundingBoxDomain();
245  trace.info() << "- domain = " << d << std::endl;
246  trace.endBlock();
247 
248  trace.beginBlock ( "Check cuts..." );
249  for ( unsigned int j = 0; j < 100; ++j )
250  {
251  CIP cip2 = cip;
252  int x = 0;
253  int y = 0;
254  while ( ( x == 0 ) && ( y == 0 ) )
255  {
256  x = myRand( 63 ) - 31;
257  y = myRand( 63 ) - 31;
258  }
259  int g = IntegerComputer<int>::staticGcd( x , y );
260  x /= g; y /= g;
261  int cc = myRand( 4 ) *x + myRand( 4 ) * y + myRand( 40 ) + 40;
262  for ( unsigned int i = 0; i < 10; ++i, cc -= myRand( 40 ) )
263  {
264  HalfSpace h( Vector( x, y ), cc );
265  trace.info() << "[" << j << " size=" << cip2.size() << "]"
266  << " cut by (" << x << "," << y << ")," << c << std::endl;
267  ++nb, nbok += checkCut( cip2, h ) ? 1 : 0;
268  trace.info() << "(" << nbok << "/" << nb << ") cuts" << std::endl;
269  //std::cerr << " " << cip2.size() << flush;
270  if ( nb != nbok ) break;
271  }
272  std::cerr << std::endl;
273  if ( nb != nbok ) break;
274  }
275  trace.endBlock();
276  return nbok == nb;
277 }
278 
283 template <typename Space>
285 {
286  unsigned int nbok = 0;
287  unsigned int nb = 0;
288 
289  typedef typename Space::Point Point;
290  typedef typename Space::Vector Vector;
291  typedef LatticePolytope2D<Space> CIP;
292  typedef typename CIP::Domain Domain;
293  typedef typename CIP::HalfSpace HalfSpace;
294  typedef typename CIP::ConstIterator ConstIterator;
295  typedef typename DigitalSetSelector< Domain, BIG_DS+HIGH_BEL_DS >::Type DigitalSet;
296 
297  CIP cip;
298  cip.pushBack( Point( 0, 0 ) );
299  cip.pushBack( Point( 8, -3 ) );
300  cip.pushBack( Point( 17, 2 ) );
301  cip.pushBack( Point( 21, 13 ) );
302  cip.pushBack( Point( 13, 19 ) );
303  cip.pushBack( Point( 6, 17 ) );
304  cip.pushBack( Point( -3, 6 ) );
305  HalfSpace hs1( Vector( -5, 11 ), 8 ); //12
306  HalfSpace hs2( Vector( -3, -11 ), 8 ); //-37
307  ++nb, nbok += checkCut( cip, hs1 ) ? 1 : 0;
308 
309  Domain d = cip.boundingBoxDomain();
310  Board2D board;
311  board << SetMode( d.className(), "Grid" ) << d;
312  DigitalSet aSet( d );
313  ConstIterator itv = cip.begin();
314  ++itv; ++itv; ++itv; ++itv; ++itv; ++itv; ++itv;
315  HalfSpace hs( cip.halfSpace( itv ) );
317  Color col1( 100, 180, 100 );
318  Color col2( 130, 200, 130 );
319  board << CustomStyle( aSet.className(), new CustomColors( col1, col2 ) )
320  << aSet;
321  board << SetMode( cip.className(), "Transparent" ) << cip;
322  Point p( 0, 0 );
323  board << CustomStyle( p.className(), new CustomColors( Color::Red, Color::Red ) )
324  << p;
325  board.saveEPS( "cip3.eps" );
326  board.clear();
327 
328  ++nb, nbok += checkCut( cip, hs2 ) ? 1 : 0;
329  return nbok == nb;
330 }
331 
332 template <typename Space>
333 bool
335 {
336  typedef typename Space::Point Point;
337  typedef typename Space::Vector Vector;
338  typedef typename Space::Integer Integer;
339  typedef LatticePolytope2D<Space> CIP;
340  typedef typename CIP::Domain Domain;
341  typedef typename CIP::HalfSpace HalfSpace;
342  typedef typename DigitalSetSelector< Domain, BIG_DS+HIGH_BEL_DS >::Type DigitalSet;
344 
345  BOOST_CONCEPT_ASSERT(( boost::Container< CIP > ));
346 
347  Point c1( 0, 0 );
348  Point c3( 30, 0 );
349  Point A( -10, -2 );
350  Point B( 40, 27 );
351  Point In( 1, 0 );
352  HalfSpace hs1( c1, c1 + Vector( 0, 1 ), In, ic );
353  HalfSpace hs2( A, B, In, ic );
354  HalfSpace hs3( c3, c3 + Vector( 0, 1 ), In, ic );
355  CIP cip;
356  cip.pushBack( c1 );
357  cip.computeConvexHullBorder( std::back_inserter( cip ), c1, c3, hs1, hs2, hs3 );
358  cip.pushBack( c3 );
359 
360  Domain d = cip.boundingBoxDomain();
361  Board2D board;
362  board << SetMode( d.className(), "Grid" ) << d;
363  DigitalSet aSet( d );
365  Color col1( 100, 180, 100 );
366  Color col2( 220, 250, 220 );
367  board << CustomStyle( aSet.className(), new CustomColors( col1, col2 ) )
368  << aSet;
369  board << SetMode( cip.className(), "Transparent" ) << cip;
370  // Point p( 0, 0 );
371  // board << CustomStyle( p.className(), new CustomColors( Color::Red, Color::Red ) )
372  // << p;
373  board.saveEPS( "cip4.eps" );
374  board.clear();
375  return true;
376 }
377 
379 // Standard services - public :
380 
381 int main( int, char** )
382 {
383  trace.beginBlock ( "Testing class LatticePolytope2D" );
384 
385  typedef SpaceND<2, DGtal::int64_t> Z2;
386  typedef SpaceND<2, DGtal::BigInteger> Z2I;
387  bool res = testLatticePolytope2D<Z2>()
388  && testLatticePolytope2D<Z2I>()
389  && exhaustiveTestLatticePolytope2D<Z2>()
390  && checkOutputConvexHullBorder<Z2>();
391  //&& specificTestLatticePolytope2D<Z2>();
392  //&& exhaustiveTestLatticePolytope2D<Z2I>();
393  trace.emphase() << ( res ? "Passed." : "Error." ) << endl;
394  trace.endBlock();
395  return res ? 0 : 1;
396 }
397 // //
void beginBlock(const std::string &keyword="")
std::string className() const
HyperRectDomain< Space > Domain
MyDigitalSurface::ConstIterator ConstIterator
Trace trace
Definition: Common.h:137
Aim: SpaceND is a utility class that defines the fundamental structure of a Digital Space in ND...
Definition: SpaceND.h:95
bool testLatticePolytope2D()
bool cut(const HalfSpace &hs)
STL namespace.
double endBlock()
Custom style class redefining the pen color and the fill color. You may use Board2D::Color::None for ...
Definition: Board2D.h:278
bool checkOutputConvexHullBorder()
void saveSVG(const char *filename, PageSize size=Board::BoundingBox, double margin=10.0) const
Definition: Board.cpp:1012
Aim: This class gathers several types and methods to make computation with integers.
int main(int, char **)
std::ostream & emphase()
void clear(const DGtal::Color &color=DGtal::Color::None)
Definition: Board.cpp:152
TInteger Integer
Arithmetic ring induced by (+,-,*) and Integer numbers.
Definition: SpaceND.h:102
void saveEPS(const char *filename, PageSize size=Board::BoundingBox, double margin=10.0) const
Definition: Board.cpp:805
std::string className() const
DGtal is the top-level namespace which contains all DGtal functions and types.
MyPointD Point
Definition: testClone2.cpp:383
Aim: A wrapper class around a STL associative container for storing sets of digital points within som...
Aim: A half-space specified by a vector N and a constant c. The half-space is the set ...
std::ostream & info()
FreemanChain< int >::Vector Vector
int myRand(int nb)
bool checkCut(LatticePolytope2D &cip, typename LatticePolytope2D::HalfSpace hs)
Modifier class in a Board2D stream. Useful to choose your own mode for a given class. Realizes the concept CDrawableWithBoard2D.
Definition: Board2D.h:247
Structure representing an RGB triple with alpha component.
Definition: Color.h:66
bool specificTestLatticePolytope2D()
Aim: A utility class for constructing different shapes (balls, diamonds, and others).
void getIncludedDigitalPoints(DigitalSet &aSet) const
bool exhaustiveTestLatticePolytope2D()
Domain boundingBoxDomain() const
Aim: Represents a 2D polytope, i.e. a convex polygon, in the two-dimensional digital plane...
Aim: This class specializes a &#39;Board&#39; class so as to display DGtal objects more naturally (with <<)...
Definition: Board2D.h:70
Go to http://www.sgi.com/tech/stl/Container.html.
Definition: Boost.dox:104