DGtal  0.9.2
Display2DFactory.ih
1 /**
2  * This program is free software: you can redistribute it and/or modify
3  * it under the terms of the GNU Lesser General Public License as
4  * published by the Free Software Foundation, either version 3 of the
5  * License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program. If not, see <http://www.gnu.org/licenses/>.
14  *
15  **/
16 
17 /**
18  * @file Display2DFactory.ih
19  * @author Martial Tola <http://liris.cnrs.fr/martial.tola/>
20  * @date mercredi 28 septembre 2011
21  *
22  * @brief
23  *
24  * Implementation of inline methods defined in Display2DFactory.h
25  *
26  * This file is part of the DGtal library.
27  */
28 
29 #include <DGtal/io/Style2DFactory.h>
30 #include <DGtal/io/colormaps/GradientColorMap.h>
31 #include <DGtal/topology/CanonicSCellEmbedder.h>
32 
33 ///////////////////////////////////////////////////////////////////////////////
34 // Implementation of inline methods //
35 
36 
37 ///////////////////////////////////////////////////////////////////////////////
38 // Implementation of inline functions and external operators //
39 template <DGtal::Dimension dim, typename TInteger>
40 inline
41 void
42 DGtal::Display2DFactory::drawDECSignedKhalimskyCell(DGtal::Board2D& board, const DGtal::SignedKhalimskyCell<dim, TInteger>& sk)
43 {
44  drawDECSignedKhalimskyCell( board, sk.preCell() );
45 }
46 
47 template <DGtal::Dimension dim, typename TInteger>
48 inline
49 void
50 DGtal::Display2DFactory::drawDECSignedKhalimskyCell(DGtal::Board2D& board, const DGtal::SignedKhalimskyPreCell<dim, TInteger>& sk)
51 {
52  FATAL_ERROR( dim == 2 );
53 
54  using KPS = DGtal::Z2i::KPreSpace;
55  const KPS K{};
56 
57  //FIXME: as for Display3D models, embedder should be factorized
58  //and not instantiated at each call.
59  using Embedder = DGtal::CanonicSCellEmbedder<KPS>;
60  const Embedder embedder( K );
61 
62  const Embedder::RealPoint coords = embedder( sk );
63  const float x = coords[0];
64  const float y = coords[1];
65  const float retract = 0.1f;
66  const bool xodd = ( KPS::sKCoord(sk, 0) & 1 );
67  const bool yodd = ( KPS::sKCoord(sk, 1) & 1 );
68  board.setLineWidth( .5 );
69  board.setPenColor( DGtal::Color::Black );
70  board.setLineStyle( Board2D::Shape::SolidStyle );
71  if (!xodd && !yodd)
72  {
73  if ( KPS::sSign(sk) == KPS::NEG ) DGtal::trace.warning() << "negative khalimsky 0-cell" << std::endl;
74  board.drawCircle(x, y, retract);
75  return;
76  }
77  if (xodd && !yodd)
78  {
79  if ( KPS::sSign(sk) == KPS::NEG ) board.drawTriangle(x-.5f, y-retract, x-.5f, y+retract, x+.5f, y);
80  else board.drawTriangle(x+.5f, y+retract, x+.5f, y-retract, x-.5f, y);
81  return;
82  }
83  if (!xodd && yodd)
84  {
85  if ( KPS::sSign(sk) == KPS::NEG ) board.drawTriangle(x-retract, y-.5f, x+retract, y-.5f, x, y+.5);
86  else board.drawTriangle(x+retract, y+.5f, x-retract, y+.5f, x, y-.5);
87  return;
88  }
89  if ( KPS::sSign(sk) == KPS::NEG ) DGtal::trace.warning() << "negative khalimsky 2-cell" << std::endl;
90  board.drawRectangle(x-.5, y+.5, 1, 1);
91 }
92 
93 // DiscreteExteriorCalculus
94 template <DGtal::Dimension dimEmbedded, DGtal::Dimension dimAmbient, typename TLinearAlgebraBackend, typename TInteger>
95 inline
96 void
97 DGtal::Display2DFactory::draw(DGtal::Board2D& board, const DGtal::DiscreteExteriorCalculus<dimEmbedded, dimAmbient, TLinearAlgebraBackend, TInteger>& calculus)
98 {
99  BOOST_STATIC_ASSERT(( dimAmbient == 2 ));
100 
101  typedef DiscreteExteriorCalculus<dimEmbedded, dimAmbient, TLinearAlgebraBackend, TInteger> Calculus;
102  typedef typename Calculus::ConstIterator ConstIterator;
103  typedef typename Calculus::Cell Cell;
104  typedef typename Calculus::SCell SCell;
105  typedef typename Calculus::KSpace KSpace;
106 
107  board.setFillColor( DGtal::Color(128,128,128) );
108  for (int kk=2; kk>=0; kk--)
109  for (ConstIterator ci=calculus.begin(), cie=calculus.end(); ci!=cie; ci++)
110  {
111  const Cell& cell = ci->first;
112  if (calculus.myKSpace.uDim(cell) != static_cast<DGtal::Dimension>(kk)) continue;
113 
114  const bool& flipped = ci->second.flipped;
115  const SCell displayed_cell = calculus.myKSpace.signs(cell, flipped ? KSpace::NEG : KSpace::POS);
116 
117  drawDECSignedKhalimskyCell(board, displayed_cell);
118  }
119 }
120 // DiscreteExteriorCalculus
121 
122 // KForm
123 template <typename TCalculus, DGtal::Order order, DGtal::Duality duality>
124 inline
125 void
126 DGtal::Display2DFactory::draw(DGtal::Board2D& board, const DGtal::KForm<TCalculus, order, duality>& kform)
127 {
128  BOOST_STATIC_ASSERT(( TCalculus::dimensionAmbient == 2 ));
129  ASSERT( kform.myCalculus );
130 
131  typedef typename TCalculus::Scalar Scalar;
132  typedef typename TCalculus::Index Index;
133 
134  Scalar cmap_min = 0;
135  Scalar cmap_max = 0;
136  DGtal::ColorGradientPreset cmap_preset = CMAP_JET;
137  int cmap_repeat = 0;
138 
139  {
140  const DGtal::KFormStyle2D* style = dynamic_cast<const DGtal::KFormStyle2D*>(board.myStyles["KForm"].get());
141  if (style)
142  {
143  cmap_min = style->cmap_min;
144  cmap_max = style->cmap_max;
145  cmap_preset = style->cmap_preset;
146  cmap_repeat = style->cmap_repeat;
147  }
148  }
149 
150  if (cmap_min == 0 && cmap_max == 0)
151  {
152  bool first = true;
153  for (Index index=0; index<kform.myContainer.rows(); index++)
154  {
155  const Scalar value = kform.myContainer(index);
156  if (!std::isfinite(value)) continue;
157  if (first || cmap_min > value) cmap_min = value;
158  if (first || cmap_max < value) cmap_max = value;
159  first = false;
160  }
161  }
162 
163  if (cmap_min == cmap_max) cmap_max += 1;
164 
165  board.setLineWidth( .5 );
166 
167  if (cmap_repeat < 1 && cmap_preset == DGtal::CMAP_JET)
168  {
169  typedef typename DGtal::GradientColorMap<Scalar, DGtal::CMAP_JET> ColorMap;
170  const ColorMap colormap(cmap_min, cmap_max);
171  drawWithColorMap(board, kform, colormap);
172  return;
173  }
174 
175  if (cmap_repeat < 1 && cmap_preset == DGtal::CMAP_GRAYSCALE)
176  {
177  typedef typename DGtal::GradientColorMap<Scalar, DGtal::CMAP_GRAYSCALE> ColorMap;
178  const ColorMap colormap(cmap_min, cmap_max);
179  drawWithColorMap(board, kform, colormap);
180  return;
181  }
182 
183  // @todo FIXME add other colomaps
184  if (cmap_repeat < 1)
185  {
186  typedef typename DGtal::GradientColorMap<Scalar, DGtal::CMAP_HOT> ColorMap;
187  const ColorMap colormap(cmap_min, cmap_max);
188  drawWithColorMap(board, kform, colormap);
189  return;
190  }
191 
192  ASSERT(cmap_repeat >= 1);
193  typedef typename DGtal::HueShadeColorMap<Scalar, DGtal::CMAP_HOT> ColorMap;
194  const ColorMap colormap(cmap_min, cmap_max, cmap_repeat);
195  drawWithColorMap(board, kform, colormap);
196 }
197 
198 template <typename TCalculus, DGtal::Order order, DGtal::Duality duality, typename TColorMap>
199 inline
200 void
201 DGtal::Display2DFactory::drawWithColorMap(DGtal::Board2D& board, const DGtal::KForm<TCalculus, order, duality>& kform, const TColorMap& colormap)
202 {
203  typedef typename TCalculus::Scalar Scalar;
204  typedef typename TCalculus::SCell SCell;
205 
206  for (typename TCalculus::Index index=0; index<kform.length(); index++)
207  {
208  const SCell displayed_cell = kform.getSCell(index);
209  const Scalar displayed_value = kform.myContainer(index);
210 
211  if (std::isfinite(displayed_value)) board.setFillColor( colormap(displayed_value) );
212  else continue;
213 
214  drawDECSignedKhalimskyCell(board, displayed_cell);
215  }
216 }
217 // KForm
218 
219 // VectorField
220 template <typename TCalculus, DGtal::Duality duality>
221 void
222 DGtal::Display2DFactory::draw(DGtal::Board2D& board, const DGtal::VectorField<TCalculus, duality>& vector_field)
223 {
224  BOOST_STATIC_ASSERT(( TCalculus::dimensionAmbient == 2 ));
225  ASSERT( vector_field.myCalculus );
226 
227  typedef typename DGtal::VectorField<TCalculus, duality>::Vector Vector;
228 
229  typename TCalculus::Scalar scale = .25;
230  typename TCalculus::Scalar epsilon = 1e-8;
231 
232  {
233  const DGtal::VectorFieldStyle2D* style = dynamic_cast<const DGtal::VectorFieldStyle2D*>(board.myStyles["VectorField"].get());
234  if (style)
235  {
236  scale = style->scale;
237  epsilon = style->epsilon;
238  }
239  }
240 
241  for (typename TCalculus::Index index=0; index<vector_field.length(); index++)
242  {
243  const typename TCalculus::SCell& cell = vector_field.getSCell(index);
244  const DGtal::Z2i::RealPoint origin = DGtal::Z2i::RealPoint(cell.preCell().coordinates[0]-1, cell.preCell().coordinates[1]-1)/2.;
245 
246  Vector vector = vector_field.getVector(index);
247 
248  vector *= scale;
249  if (!std::isfinite(vector[0]) || !std::isfinite(vector[1])) continue;
250  const typename TCalculus::Scalar& norm = vector.norm();
251  if (norm <= epsilon) continue;
252  if (norm <= .5) vector *= .5/norm;
253 
254  board.drawArrow(origin[0],origin[1],origin[0]+vector[0],origin[1]+vector[1]);
255  }
256 
257 }
258 // VectorField
259 
260 // AngleLinearMinimizer
261 inline
262 void DGtal::Display2DFactory::draw( DGtal::Board2D & board,
263  const DGtal::AngleLinearMinimizer & a )
264 {
265  double distance=5.0;
266  board.setLineWidth(3.0);
267  board.setPenColor(Color(20,20,200));
268  // now with accessor
269  for(int i=0; i< (int)a.size(); i++){
270  board.drawArc(0.0, 0.0, distance, a.ro(i).min, a.ro(i).max, false, 1);
271  board.drawDot(cos(a.ro(i).value)*distance, sin(a.ro(i).value)*distance );
272  distance+=a.ro(i).distToNext;
273  }
274  distance=5.0;
275  double distanceNext;
276  // now with accessor
277  for(int i=0; i< (int) (a.size()-1); i++){
278  distanceNext= distance+ a.ro(i).distToNext;
279  board.setPenColor(Color(200,20,20));
280  board.drawLine(cos(a.ro(i).value)*distance, sin(a.ro(i).value)*distance,
281  cos(a.ro(i+1).value)*distanceNext, sin(a.ro(i+1).value)*distanceNext);
282  distance=distanceNext;
283  }
284 }
285 // AngleLinearMinimizer
286 
287 // ArithmeticalDSS
288 template <typename TCoordinate, typename TInteger, unsigned short adjacency>
289 inline
290 void DGtal::Display2DFactory::drawAsBoundingBox( DGtal::Board2D & aBoard,
291  const DGtal::ArithmeticalDSS<TCoordinate,TInteger,adjacency> & a )
292 {
293  typedef typename DGtal::ArithmeticalDSS<TCoordinate,TInteger,adjacency>::PointD PointD;
294 
295  //draw bounding box
296  PointD topLeft = a.project(a.back(), a.Uf());
297  PointD bottomLeft = a.project(a.back(), a.Lf());
298  PointD bottomRight = a.project(a.front(), a.Lf());
299  PointD topRight = a.project(a.front(), a.Uf());
300 
301  LibBoard::Point topLeftBoard(topLeft[0],topLeft[1]);
302  LibBoard::Point bottomLeftBoard(bottomLeft[0],bottomLeft[1]);
303  LibBoard::Point bottomRightBoard(bottomRight[0],bottomRight[1]);
304  LibBoard::Point topRightBoard(topRight[0],topRight[1]);
305 
306  std::vector<LibBoard::Point> bb;
307  bb.push_back(topLeftBoard);
308  bb.push_back(bottomLeftBoard);
309  bb.push_back(bottomRightBoard);
310  bb.push_back(topRightBoard);
311 
312  aBoard.drawClosedPolyline(bb);
313 }
314 
315 template <typename TCoordinate, typename TInteger, unsigned short adjacency>
316 inline
317 void DGtal::Display2DFactory::drawAsDigitalPoints( DGtal::Board2D & aBoard,
318  const DGtal::ArithmeticalDSS<TCoordinate,TInteger,adjacency> & a )
319 {
320  typedef typename DGtal::ArithmeticalDSS<TCoordinate,TInteger,adjacency>::ConstIterator ConstIterator;
321  typedef typename IteratorCirculatorTraits<ConstIterator>::Value Point;
322 
323  // Draw a linking polygonal line if the pixels are drawn as points.
324  if(aBoard.getMode("PointVector")=="Grid" || aBoard.getMode("PointVector")=="")
325  {
326  std::vector<LibBoard::Point> contour;
327  for (ConstIterator it = a.begin(), itEnd = a.end();
328  it != itEnd; ++it)
329  {
330  Point p = *it;
331  double xp = NumberTraits<TInteger>::castToDouble(p[0]);
332  double yp = NumberTraits<TInteger>::castToDouble(p[1]);
333  contour.push_back(LibBoard::Point(xp,yp));
334  }
335  aBoard.drawPolyline(contour);
336  }
337 
338  // Draw points
339  for (ConstIterator it = a.begin(), itEnd = a.end();
340  it != itEnd; ++it)
341  {
342  Point p = *it;
343  aBoard << p;
344  }
345 }
346 
347 template <typename TCoordinate, typename TInteger, unsigned short adjacency>
348 inline
349 void DGtal::Display2DFactory::draw( DGtal::Board2D & board,
350  const DGtal::ArithmeticalDSS<TCoordinate,TInteger,adjacency> & a )
351 {
352  std::string mode = board.getMode( a.className() );
353  if ( mode == "BoundingBox" )
354  drawAsBoundingBox( board, a );
355  else if ( mode == "Points" )
356  drawAsDigitalPoints( board, a );
357  else if ( ( mode == "" ) )
358  {
359  auto style = new DefaultDrawStyleBB_ArithmeticalDSS();
360  drawAsDigitalPoints( board, a );
361  Style2DFactory::draw( board, style);
362  drawAsBoundingBox( board, a );
363  delete style;
364  }
365  else
366  ASSERT(false && ("draw( DGtal::Board2D & board, const DGtal::ArithmeticalDSS<TCoordinate,TInteger,adjacency> & a ): Unknown mode "+mode)=="" );
367 }
368 // ArithmeticalDSS
369 
370 // ArithmeticalDSSComputer
371 template <typename TIterator, typename TInteger, int connectivity>
372 inline
373 void DGtal::Display2DFactory::drawAsBoundingBox( DGtal::Board2D & aBoard,
374  const DGtal::ArithmeticalDSSComputer<TIterator,TInteger,connectivity> & a )
375 {
376  typedef DGtal::PointVector<2,double> PointD;
377 
378  //draw bounding box
379  PointD topLeft = a.project(*a.myF, a.myUf);
380  PointD bottomLeft = a.project(*a.myF, a.myLf);
381  PointD bottomRight = a.project(*a.myL, a.myLf);
382  PointD topRight = a.project(*a.myL, a.myUf);
383 
384 
385  LibBoard::Point topLeftBoard(topLeft[0],topLeft[1]);
386  LibBoard::Point bottomLeftBoard(bottomLeft[0],bottomLeft[1]);
387  LibBoard::Point bottomRightBoard(bottomRight[0],bottomRight[1]);
388  LibBoard::Point topRightBoard(topRight[0],topRight[1]);
389 
390  std::vector<LibBoard::Point> bb;
391  bb.push_back(topLeftBoard);
392  bb.push_back(bottomLeftBoard);
393  bb.push_back(bottomRightBoard);
394  bb.push_back(topRightBoard);
395 
396  aBoard.drawClosedPolyline(bb);
397 }
398 
399 template <typename TIterator, typename TInteger, int connectivity>
400 inline
401 void DGtal::Display2DFactory::drawAsDigitalPoints( DGtal::Board2D & aBoard,
402  const DGtal::ArithmeticalDSSComputer<TIterator,TInteger,connectivity> & a )
403 {
404  typedef TIterator ConstIterator;
405  typedef typename IteratorCirculatorTraits<ConstIterator>::Value Point;
406 
407  ConstIterator itend = a.myL; ++itend;
408 
409  // Draw a linking polygonal line if the pixels are drawn as points.
410  if(aBoard.getMode("PointVector")=="Grid" || aBoard.getMode("PointVector")=="")
411  {
412  std::vector<LibBoard::Point> contour;
413  for (ConstIterator i = a.myF; i != itend; ++i) {
414  Point p = *i;
415  double xp = NumberTraits<TInteger>::castToDouble(p[0]);
416  double yp = NumberTraits<TInteger>::castToDouble(p[1]);
417  contour.push_back(LibBoard::Point(xp,yp));
418  }
419  aBoard.drawPolyline(contour);
420  }
421 
422  // Draw points
423  for (ConstIterator i = a.myF; i != itend; ++i) {
424  Point p = *i;
425  aBoard << p;
426  }
427 }
428 
429 template <typename TIterator, typename TInteger, int connectivity>
430 inline
431 void DGtal::Display2DFactory::draw( DGtal::Board2D & board,
432  const DGtal::ArithmeticalDSSComputer<TIterator,TInteger,connectivity> & a )
433 {
434  std::string mode = board.getMode( a.className() );
435  if ( mode == "BoundingBox" )
436  drawAsBoundingBox( board, a );
437  else if ( mode == "Points" )
438  drawAsDigitalPoints( board, a );
439  else if ( ( mode == "" ) )
440  {
441  drawAsDigitalPoints( board, a );
442  drawAsBoundingBox( board, a );
443  }
444  else
445  FATAL_ERROR_MSG(false, "draw( DGtal::Board2D & board, const DGtal::ArithmeticalDSSComputer<TIterator,TInteger,connectivity> & a ): Unknown mode "+mode);
446 
447 }
448 // ArithmeticalDSSComputer
449 
450 
451 // AlphaThickSegmentComputer
452 template <typename TInputPoint, typename TConstIterator>
453 void DGtal::Display2DFactory::drawAsBoundingBox( DGtal::Board2D & aBoard,
454  const DGtal::AlphaThickSegmentComputer< TInputPoint, TConstIterator> & anAlphaThickSegment){
455  typedef DGtal::PointVector<2,double> PointD;
456 
457  PointD topLeft, topRight, bottomRight, bottomLeft;
458  anAlphaThickSegment.getBoundingBox(topLeft, topRight, bottomRight, bottomLeft);
459  //draw bounding box
460  aBoard.drawLine(topLeft[0],topLeft[1],topRight[0],topRight[1]);
461  aBoard.drawLine(topRight[0],topRight[1],bottomRight[0], bottomRight[1] );
462  aBoard.drawLine(bottomRight[0], bottomRight[1], bottomLeft[0], bottomLeft[1]);
463  aBoard.drawLine(bottomLeft[0], bottomLeft[1],topLeft[0],topLeft[1]);
464 }
465 
466 
467 template < typename TInputPoint, typename TConstIterator>
468 void DGtal::Display2DFactory::drawAsDigitalPoints( DGtal::Board2D & aBoard,
469  const DGtal::AlphaThickSegmentComputer< TInputPoint, TConstIterator> & anAlphaThickSegment){
470  typedef typename DGtal::AlphaThickSegmentComputer< TInputPoint, TConstIterator>::ContainerConstIterator ContConstIterator;
471  typedef TConstIterator ConstIterator;
472  typedef TInputPoint Point;
473  // Draw a linking polygonal line if the pixels are drawn as points.
474  if(aBoard.getMode("PointVector")=="Grid" || aBoard.getMode("PointVector")=="")
475  {
476  std::vector<LibBoard::Point> contour;
477  if (anAlphaThickSegment.isStoringSegmentPoints()){
478  for (ContConstIterator it = anAlphaThickSegment.containerBegin();
479  it != anAlphaThickSegment.containerEnd(); it++) {
480  Point p = *it;
481  double xp = NumberTraits<typename TInputPoint::Component>::castToDouble(p[0]);
482  double yp = NumberTraits<typename TInputPoint::Component>::castToDouble(p[1]);
483  contour.push_back(LibBoard::Point(xp,yp));
484  }
485 
486  }else{
487  for (ConstIterator it = anAlphaThickSegment.begin(); it != anAlphaThickSegment.end(); it++) {
488  Point p = *it;
489  double xp = NumberTraits<typename TInputPoint::Component>::castToDouble(p[0]);
490  double yp = NumberTraits<typename TInputPoint::Component>::castToDouble(p[1]);
491  contour.push_back(LibBoard::Point(xp,yp));
492  }
493  }
494  if(contour.size()>0){
495  aBoard.drawPolyline(contour);
496  }
497  }
498  // Draw points
499  if (anAlphaThickSegment.isStoringSegmentPoints()){
500  for (ContConstIterator it = anAlphaThickSegment.containerBegin();
501  it != anAlphaThickSegment.containerEnd(); it++) {
502  Point p = *it;
503  draw(aBoard,p );
504  }
505  }else {
506  for (ConstIterator it = anAlphaThickSegment.begin(); it != anAlphaThickSegment.end(); it++) {
507  Point p = *it;
508  draw(aBoard,p );
509  }
510  }
511 }
512 
513 template < typename TInputPoint, typename TConstIterator>
514 void DGtal::Display2DFactory::draw( DGtal::Board2D & aBoard,
515  const DGtal::AlphaThickSegmentComputer< TInputPoint, TConstIterator> & anAlphaThickSegment ){
516  std::string mode = aBoard.getMode( anAlphaThickSegment.className() );
517  if ( mode == "BoundingBox" )
518  drawAsBoundingBox( aBoard, anAlphaThickSegment );
519  else if ( mode == "Points" )
520  drawAsDigitalPoints( aBoard, anAlphaThickSegment );
521  else if ( ( mode == "" ) )
522  {
523  drawAsDigitalPoints( aBoard, anAlphaThickSegment );
524  drawAsBoundingBox( aBoard, anAlphaThickSegment );
525  }
526  else
527  FATAL_ERROR_MSG(false, "draw( DGtal::Board2D & board, const DGtal::ArithmeticalDSSComputer<TIterator,TInteger,connectivity> & a ): Unknown mode "+mode);
528  }
529 // AlphaThickSegmentComputer
530 
531 
532 // CircleFrom2Points
533 template <typename TPoint>
534 inline
535 void DGtal::Display2DFactory::draw(Board2D & aBoard, const DGtal::CircleFrom2Points<TPoint> & cf2p)
536 {
537  // now with accessor
538  CircleFrom3Points<TPoint> c(cf2p.pole(),cf2p.p(),cf2p.q());
539  drawArc(aBoard,c,cf2p.p(),cf2p.q(),true);
540 }
541 // CircleFrom2Points
542 
543 
544 // CircleFrom3Points
545 template <typename Point>
546 inline
547 void DGtal::Display2DFactory::drawArc(Board2D & aBoard, const DGtal::CircleFrom3Points<Point> & cf3p, const Point& aPoint1, const Point& aPoint2, bool anOrientation)
548 {
549  typedef typename Point::Coordinate Coordinate;
550  typedef Point Vector;
551 
552  double cx = 0, cy = 0, radius = 1;
553  try
554  {
555  //circle parameters
556  cf3p.getParameters(cx, cy, radius);
557  //angle parameters
558  double alpha1 = std::atan2( NumberTraits<Coordinate>::castToDouble(aPoint1[1])-cy,
559  NumberTraits<Coordinate>::castToDouble(aPoint1[0])-cx );
560  alpha1 = (alpha1<0)?(alpha1+2.0*M_PI):alpha1;
561  double alpha2 = std::atan2( NumberTraits<Coordinate>::castToDouble(aPoint2[1])-cy,
562  NumberTraits<Coordinate>::castToDouble(aPoint2[0])-cx );
563  alpha2 = (alpha2<0)?(alpha2+2.0*M_PI):alpha2;
564  // now with accessor
565  Vector u(cf3p.p() - cf3p.q());
566  Vector v(cf3p.r() - cf3p.p());
567  bool orientation = ( ( (u[0] * v[1]) - (u[1] * v[0]) ) < 0 )?(!anOrientation):anOrientation;
568  //drawing
569  aBoard.drawArc (cx, cy, radius, alpha1, alpha2, orientation);
570  }
571  catch ( InfiniteNumberException e )
572  {
573  aBoard.drawLine( NumberTraits<Coordinate>::castToDouble(aPoint1[0]),
574  NumberTraits<Coordinate>::castToDouble(aPoint1[1]),
575  NumberTraits<Coordinate>::castToDouble(aPoint2[0]),
576  NumberTraits<Coordinate>::castToDouble(aPoint2[1]) );
577  }
578 }
579 
580 template <typename Point>
581 inline
582 void DGtal::Display2DFactory::drawSector(Board2D & aBoard, const DGtal::CircleFrom3Points<Point> & cf3p, const Point& aPoint1, const Point& aPoint2, bool anOrientation)
583 {
584  typedef typename Point::Coordinate Coordinate;
585  typedef Point Vector;
586 
587  double cx = 0, cy = 0, radius = 1;
588  try
589  {
590  //circle parameters
591  cf3p.getParameters(cx, cy, radius);
592  //angle parameters
593  double alpha1 = std::atan2( NumberTraits<Coordinate>::castToDouble(aPoint1[1])-cy,
594  NumberTraits<Coordinate>::castToDouble(aPoint1[0])-cx );
595  alpha1 = (alpha1<0)?(alpha1+2.0*M_PI):alpha1;
596  double alpha2 = std::atan2( NumberTraits<Coordinate>::castToDouble(aPoint2[1])-cy,
597  NumberTraits<Coordinate>::castToDouble(aPoint2[0])-cx );
598  alpha2 = (alpha2<0)?(alpha2+2.0*M_PI):alpha2;
599  // now with accessor
600  Vector u(cf3p.p() - cf3p.q());
601  Vector v(cf3p.r() - cf3p.p());
602  bool orientation = ( ( (u[0] * v[1]) - (u[1] * v[0]) ) < 0 )?(!anOrientation):anOrientation;
603  //arc drawing
604  aBoard.drawArc (cx, cy, radius, alpha1, alpha2, orientation);
605  //draw the segments tied to the center
606  double fx = cx + radius*std::cos(alpha1);
607  double fy = cy + radius*std::sin(alpha1);
608  double lx = cx + radius*std::cos(alpha2);
609  double ly = cy + radius*std::sin(alpha2);
610  aBoard.drawLine(fx, fy, cx, cy );
611  aBoard.drawLine(lx, ly, cx, cy );
612 
613  }
614  catch ( InfiniteNumberException e )
615  {
616  aBoard.drawLine( NumberTraits<Coordinate>::castToDouble(aPoint1[0]),
617  NumberTraits<Coordinate>::castToDouble(aPoint1[1]),
618  NumberTraits<Coordinate>::castToDouble(aPoint2[0]),
619  NumberTraits<Coordinate>::castToDouble(aPoint2[1]) );
620  }
621 }
622 
623 template <typename Point>
624 inline
625 void DGtal::Display2DFactory::drawAnnulus(Board2D & aBoard, const DGtal::CircleFrom3Points<Point> & cf3p,
626  const Point& aPoint1, const Point& aPoint2, bool anOrientation, const double& w)
627 {
628  typedef typename Point::Coordinate Coordinate;
629  typedef Point Vector;
630 
631  double cx = 0, cy = 0, radius = 1;
632  try
633  {
634  //circle parameters
635  cf3p.getParameters(cx, cy, radius);
636  //angle parameters
637  double alpha1 = std::atan2( NumberTraits<Coordinate>::castToDouble(aPoint1[1])-cy,
638  NumberTraits<Coordinate>::castToDouble(aPoint1[0])-cx );
639  alpha1 = (alpha1<0)?(alpha1+2.0*M_PI):alpha1;
640  double alpha2 = std::atan2( NumberTraits<Coordinate>::castToDouble(aPoint2[1])-cy,
641  NumberTraits<Coordinate>::castToDouble(aPoint2[0])-cx );
642  alpha2 = (alpha2<0)?(alpha2+2.0*M_PI):alpha2;
643  // now with accessor
644  Vector u(cf3p.p() - cf3p.q());
645  Vector v(cf3p.r() - cf3p.p());
646  bool orientation = ( ( (u[0] * v[1]) - (u[1] * v[0]) ) < 0 )?(!anOrientation):anOrientation;
647  //inner arc
648  aBoard.drawArc (cx, cy, radius-w, alpha1, alpha2, orientation);
649  //outer arc
650  aBoard.drawArc (cx, cy, radius+w, alpha1, alpha2, orientation);
651  //first segment
652  double ifx = cx + (radius-w)*std::cos(alpha1);
653  double ify = cy + (radius-w)*std::sin(alpha1);
654  double ofx = cx + (radius+w)*std::cos(alpha1);
655  double ofy = cy + (radius+w)*std::sin(alpha1);
656  aBoard.drawLine(ifx, ify, ofx, ofy);
657  //second segment
658  double ilx = cx + (radius-w)*std::cos(alpha2);
659  double ily = cy + (radius-w)*std::sin(alpha2);
660  double olx = cx + (radius+w)*std::cos(alpha2);
661  double oly = cy + (radius+w)*std::sin(alpha2);
662  aBoard.drawLine(ilx, ily, olx, oly);
663  }
664  catch ( InfiniteNumberException e )
665  {
666  aBoard.drawLine( NumberTraits<Coordinate>::castToDouble(aPoint1[0]),
667  NumberTraits<Coordinate>::castToDouble(aPoint1[1]),
668  NumberTraits<Coordinate>::castToDouble(aPoint2[0]),
669  NumberTraits<Coordinate>::castToDouble(aPoint2[1]) );
670  }
671 }
672 
673 template <typename Point>
674 inline
675 void DGtal::Display2DFactory::draw(Board2D & aBoard, const DGtal::CircleFrom3Points<Point> & cf3p, const Point& aPoint1, const Point& aPoint2, bool anOrientation)
676 {
677  std::string mode = aBoard.getMode( cf3p.className() );
678  FATAL_ERROR( (mode=="Arc" || mode=="" || mode=="Sector"|| mode=="Annulus") ||
679  ("draw(Board2D & aBoard, const DGtal::CircleFrom3Points<Point> & cf3p, const Point& aPoint1, const Point& aPoint2): Unknown mode "+mode)=="" );
680 
681  if ( mode == "Arc" || ( mode == "" ) )
682  drawArc( aBoard, cf3p, aPoint1, aPoint2, anOrientation);
683  else if ( mode == "Sector" )
684  drawSector( aBoard, cf3p, aPoint1, aPoint2, anOrientation);
685  else if ( mode == "Annulus" )
686  drawAnnulus( aBoard, cf3p, aPoint1, aPoint2, anOrientation);
687 }
688 
689 template <typename TPoint>
690 inline
691 void DGtal::Display2DFactory::draw(Board2D & aBoard, const DGtal::CircleFrom3Points<TPoint> & cf3p)
692 {
693  typedef typename TPoint::Coordinate Coordinate;
694 
695  double cx = 0, cy = 0, radius = 1;
696  try
697  {
698  cf3p.getParameters(cx,cy,radius);
699  aBoard.drawCircle (cx,cy,radius);
700  }
701  catch ( InfiniteNumberException e )
702  {
703  aBoard.drawLine( NumberTraits<Coordinate>::castToDouble(cf3p.myP[0]),
704  NumberTraits<Coordinate>::castToDouble(cf3p.myP[1]),
705  NumberTraits<Coordinate>::castToDouble(cf3p.myR[0]),
706  NumberTraits<Coordinate>::castToDouble(cf3p.myR[1]) );
707  }
708 }
709 // CircleFrom3Points
710 
711 
712 // DigitalSetBySTLSet
713 template<typename Domain, typename Compare>
714 inline
715 void DGtal::Display2DFactory::draw( DGtal::Board2D & board,
716  const DGtal::DigitalSetBySTLSet<Domain, Compare> & s )
717 {
718  typedef typename Domain::Point Point;
719  typedef typename std::set<Point>::const_iterator ConstIterator;
720 
721  BOOST_STATIC_ASSERT(Domain::Space::dimension == 2);
722  for(ConstIterator it = s.begin(); it != s.end(); ++it)
723  draw(board, *it);
724 }
725 // DigitalSetBySTLSet
726 
727 
728 // DigitalSetByAssociativeContainer
729 template<typename Domain, typename Container>
730 inline
731 void DGtal::Display2DFactory::draw( DGtal::Board2D & board,
732  const DGtal::DigitalSetByAssociativeContainer<Domain,Container> & s )
733 {
734  typedef typename DigitalSetByAssociativeContainer<Domain,Container>::ConstIterator ConstIterator;
735 
736  BOOST_STATIC_ASSERT(Domain::Space::dimension == 2);
737  for(ConstIterator it = s.begin(); it != s.end(); ++it)
738  draw(board, *it);
739 }
740 // DigitalSetByAssociativeContainer
741 
742 
743 // DigitalSetBySTLVector
744 template<typename Domain>
745 inline
746 void DGtal::Display2DFactory::draw( DGtal::Board2D & board,
747  const DGtal::DigitalSetBySTLVector<Domain> & v )
748 {
749  typedef typename Domain::Point Point;
750  typedef typename std::vector<Point>::const_iterator ConstIterator;
751 
752  if (Domain::dimension == 2)
753  {
754  for(ConstIterator it = v.begin(); it != v.end(); ++it)
755  draw(board, *it);
756  }
757  else
758  FATAL_ERROR_MSG(false, "draw-NOT-YET-IMPLEMENTED-in-ND");
759 }
760 // DigitalSetBySTLVector
761 
762 
763 // FP
764 template <typename TIterator, typename TInteger, int connectivity>
765 inline
766 void DGtal::Display2DFactory::drawAsPolygon( DGtal::Board2D & aBoard,
767  const DGtal::FP<TIterator,TInteger,connectivity> & fp )
768 {
769  typedef DGtal::PointVector<2,TInteger> Point;
770  typedef std::list<Point> Polygon;
771 
772  typedef typename Polygon::const_iterator ConstIterator;
773 
774  //polyline to draw
775  std::vector<LibBoard::Point> polyline;
776 
777  // now with accessor
778  ConstIterator i = fp.polygon().begin();
779  for ( ;i != fp.polygon().end();++i) {
780  Point p = (*i);
781  double xp = (double)NumberTraits<TInteger>::castToInt64_t(p[0]);
782  double yp = (double)NumberTraits<TInteger>::castToInt64_t(p[1]);
783  polyline.push_back(LibBoard::Point(xp,yp));
784  }
785 
786  // now with accessor
787  if (fp.isClosed()) {
788  Point p = (*fp.polygon().begin());
789  double xp = (double)NumberTraits<TInteger>::castToInt64_t(p[0]);
790  double yp = (double)NumberTraits<TInteger>::castToInt64_t(p[1]);
791  polyline.push_back(LibBoard::Point(xp,yp));
792  }
793  aBoard.drawPolyline(polyline);
794 }
795 
796 template <typename TIterator, typename TInteger, int connectivity>
797 inline
798 void DGtal::Display2DFactory::draw( DGtal::Board2D & board,
799  const DGtal::FP<TIterator,TInteger,connectivity> & fp )
800 {
801  std::string mode = board.getMode( fp.className() );
802  if ( mode == "Polygon" )
803  drawAsPolygon( board, fp );
804  else if ( ( mode == "Both" ) || ( mode == "" ) )
805  {
806  drawAsPolygon( board, fp );
807  }
808  else
809  {
810  FATAL_ERROR_MSG(false, "draw( DGtal::Board2D & board, const DGtal::FP<TIterator,TInteger,connectivity> & fp ): Unknown mode "+mode);
811  }
812 }
813 // FP
814 
815 
816 // FreemanChain
817 template <typename TInteger>
818 inline
819 void DGtal::Display2DFactory::drawAsGrid( DGtal::Board2D & aBoard,
820  const DGtal::FreemanChain<TInteger> & f )
821 {
822  typedef TInteger Integer;
823  typedef PointVector<2, Integer> Point;
824 
825  std::vector<Point> aVContour;
826  FreemanChain<TInteger>::getContourPoints(f, aVContour);
827  TInteger minX, minY, maxX, maxY;
828  f.computeBoundingBox(minX, minY, maxX, maxY);
829 
830  std::vector<LibBoard::Point> contour;
831  for(unsigned int i=0; i< aVContour.size(); i++){
832  contour.push_back(LibBoard::Point(NumberTraits<TInteger>::castToDouble(aVContour[i][0]),
833  NumberTraits<TInteger>::castToDouble(aVContour[i][1])));
834  }
835  aBoard.drawPolyline(contour);
836 }
837 
838 template <typename TInteger>
839 inline
840 void DGtal::Display2DFactory::drawAsInterGrid( DGtal::Board2D & aBoard,
841  const DGtal::FreemanChain<TInteger> & f )
842 {
843  typedef TInteger Integer;
844  typedef PointVector<2, Integer> Point;
845 
846  std::vector<Point> aVContour;
847  FreemanChain<TInteger>::getContourPoints(f, aVContour);
848  TInteger minX, minY, maxX, maxY;
849  f.computeBoundingBox(minX, minY, maxX, maxY);
850 
851  std::vector<LibBoard::Point> contour;
852  for(unsigned int i=0; i< aVContour.size(); i++){
853  contour.push_back(LibBoard::Point(NumberTraits<TInteger>::castToInt64_t(aVContour[i][0])-0.5,
854  NumberTraits<TInteger>::castToInt64_t(aVContour[i][1])+0.5));
855  }
856  aBoard.drawPolyline(contour);
857 }
858 
859 template <typename TInteger>
860 inline
861 void DGtal::Display2DFactory::draw( DGtal::Board2D & aBoard,
862  const DGtal::FreemanChain<TInteger> & f )
863 {
864  std::string mode = aBoard.getMode( f.className() );
865  FATAL_ERROR_MSG( (mode=="Grid" || mode=="" || mode=="InterGrid"),
866  "draw( DGtal::Board2D & board, const DGtal::FreemanChain<TInteger> & f ): Unknown mode "+mode);
867 
868  if ( mode == "Grid" || ( mode == "" ) )
869  drawAsGrid( aBoard, f );
870  else if ( mode == "InterGrid" )
871  drawAsInterGrid( aBoard, f );
872 }
873 // FreemanChain
874 
875 
876 // StabbingLineComputer
877 template <typename TConstIterator>
878 inline
879 void DGtal::Display2DFactory::draw(DGtal::Board2D & aBoard,
880  const DGtal::StabbingLineComputer<TConstIterator> & g)
881 {
882  typedef TConstIterator ConstIterator;
883  typedef typename IteratorCirculatorTraits<ConstIterator>::Value Pair;
884  typedef typename Pair::first_type Point;
885 
886  double alpha, beta, gamma;
887  g.getParameters(alpha, beta, gamma);
888 
889  typedef typename Point::Coordinate Coordinate;
890 
891  // now with accessor
892  Pair firstPair( *g.begin() );
893  double fx1 = NumberTraits<Coordinate>::castToDouble(firstPair.first[0]);
894  double fx2 = NumberTraits<Coordinate>::castToDouble(firstPair.second[0]);
895  double fy1 = NumberTraits<Coordinate>::castToDouble(firstPair.first[1]);
896  double fy2 = NumberTraits<Coordinate>::castToDouble(firstPair.second[1]);
897  double fx = (fx1+fx2)/2.0;
898  double fy = (fy1+fy2)/2.0;
899  g.projects(fx, fy, alpha, beta, gamma);
900 
901  // now with accessor
902  ConstIterator it (g.end());
903  --it;
904  Pair lastPair( *it );
905  double lx1 = NumberTraits<Coordinate>::castToDouble(lastPair.first[0]);
906  double lx2 = NumberTraits<Coordinate>::castToDouble(lastPair.second[0]);
907  double ly1 = NumberTraits<Coordinate>::castToDouble(lastPair.first[1]);
908  double ly2 = NumberTraits<Coordinate>::castToDouble(lastPair.second[1]);
909  double lx = (lx1+lx2)/2.0;
910  double ly = (ly1+ly2)/2.0;
911  g.projects(lx, ly, alpha, beta, gamma);
912 
913  aBoard.drawLine(fx,fy,lx,ly);
914 }
915 // StabbingLineComputer
916 
917 // StabbingCircleComputer
918 template <typename TConstIterator>
919 inline
920 void DGtal::Display2DFactory::draw(DGtal::Board2D & aBoard,
921  const DGtal::StabbingCircleComputer<TConstIterator> & g)
922 {
923 
924  typedef TConstIterator ConstIterator;
925  typedef typename IteratorCirculatorTraits<ConstIterator>::Value Pair;
926  typedef typename Pair::first_type Point;
927 
928  if (g.isValid())
929  {
930  if (!g.isStraight())
931  {
932  typedef typename Point::Coordinate Coordinate;
933 
934  //points
935  Pair firstPair( *g.begin() );
936  double fx1 = NumberTraits<Coordinate>::castToDouble(firstPair.first[0]);
937  double fx2 = NumberTraits<Coordinate>::castToDouble(firstPair.second[0]);
938  double fy1 = NumberTraits<Coordinate>::castToDouble(firstPair.first[1]);
939  double fy2 = NumberTraits<Coordinate>::castToDouble(firstPair.second[1]);
940  PointVector<2,double> p1( (fx1+fx2)/2.0, (fy1+fy2)/2.0 );
941 
942  ConstIterator it (g.end());
943  --it;
944  Pair lastPair( *it );
945  double lx1 = NumberTraits<Coordinate>::castToDouble(lastPair.first[0]);
946  double lx2 = NumberTraits<Coordinate>::castToDouble(lastPair.second[0]);
947  double ly1 = NumberTraits<Coordinate>::castToDouble(lastPair.first[1]);
948  double ly2 = NumberTraits<Coordinate>::castToDouble(lastPair.second[1]);
949  PointVector<2,double> p2( (lx1+lx2)/2.0, (ly1+ly2)/2.0 );
950 
951  //circle
952  CircleFrom3Points<Point> separatingCircle = g.getSeparatingCircle();
953  double px = NumberTraits<Coordinate>::castToDouble(separatingCircle.p()[0]);
954  double py = NumberTraits<Coordinate>::castToDouble(separatingCircle.p()[1]);
955  double qx = NumberTraits<Coordinate>::castToDouble(separatingCircle.q()[0]);
956  double qy = NumberTraits<Coordinate>::castToDouble(separatingCircle.q()[1]);
957  double rx = NumberTraits<Coordinate>::castToDouble(separatingCircle.r()[0]);
958  double ry = NumberTraits<Coordinate>::castToDouble(separatingCircle.r()[1]);
959  CircleFrom3Points<PointVector<2,double> > circleToDraw;
960  circleToDraw.init( PointVector<2,double>(px,py),
961  PointVector<2,double>(qx,qy),
962  PointVector<2,double>(rx,ry) );
963 
964  //orientation
965  FATAL_ERROR( g.getStabbingLineComputerPtr().get() != 0 );
966  bool orientation = g.getStabbingLineComputerPtr()->isClockwiseOriented();
967 
968  //mode
969  std::string mode = aBoard.getMode( g.className() );
970  if ( mode == "Sector" )
971  drawSector( aBoard, circleToDraw, p1, p2, orientation );
972  else if ( mode == "Annulus" )
973  drawAnnulus( aBoard, circleToDraw, p1, p2, orientation );
974  else
975  drawArc( aBoard, circleToDraw, p1, p2, orientation );
976  }
977  else
978  {
979  FATAL_ERROR( g.getStabbingLineComputerPtr().get() != 0 );
980  aBoard << ( *(g.getStabbingLineComputerPtr()) );
981  }
982  }
983 
984 }
985 // StabbingCircleComputer
986 
987 
988 
989 // FrechetShortcut
990 template <typename TIterator,typename TInteger>
991 inline
992  void DGtal::Display2DFactory::draw(DGtal::Board2D & aBoard, const DGtal::FrechetShortcut<TIterator,TInteger> & f)
993 {
994  typedef TIterator Iterator;
995  typedef PointVector<2,TInteger> Point;
996  typedef typename Point::Coordinate Coordinate;
997 
998  // get first point of the shortcut
999  Point p1 = *(f.begin());
1000  double px1 = NumberTraits<Coordinate>::castToDouble(p1[0]);
1001  double py1 = NumberTraits<Coordinate>::castToDouble(p1[1]);
1002 
1003  // get last point of the shortcut
1004  Iterator it (f.end());
1005  --it;
1006  Point p2(*it);
1007  double px2 = NumberTraits<Coordinate>::castToDouble(p2[0]);
1008  double py2 = NumberTraits<Coordinate>::castToDouble(p2[1]);
1009 
1010  aBoard.drawLine(px1,py1,px2,py2);
1011 }
1012 // FrechetShortcut
1013 
1014 
1015 
1016 // GridCurve
1017 template <typename TKSpace>
1018 void DGtal::Display2DFactory::draw( DGtal::Board2D & aBoard,
1019  const GridCurve<TKSpace> & object )
1020 {
1021 
1022  std::string mode = aBoard.getMode( object.className() );
1023  if(mode=="Fill"){
1024  DGtal::Display2DFactory::drawFill(aBoard, object);
1025  }else{
1026  typedef typename GridCurve<TKSpace>::ConstIterator ConstIterator;
1027  ConstIterator it ( object.begin() );
1028  ConstIterator itEnd ( object.end() );
1029  for( ; it != itEnd; ++it)
1030  {
1031  aBoard << *it;
1032  }
1033  }
1034 }
1035 
1036 template <typename TKSpace>
1037 void DGtal::Display2DFactory::drawFill( DGtal::Board2D & aBoard,
1038  const GridCurve<TKSpace> & object )
1039 {
1040 
1041 
1042  typedef typename GridCurve<TKSpace>::PointsRange::ConstIterator Iterator;
1043  typedef typename GridCurve<TKSpace>::PointsRange Range; //range
1044 
1045  Range r = object.getPointsRange();
1046  Iterator it (r.begin());
1047  Iterator itEnd (r.end());
1048 
1049  std::vector< LibBoard::Point > aPolygon;
1050  for( ; it != itEnd; ++it)
1051  {
1052  LibBoard::Point pt((*it)[0], (*it)[1]);
1053  aPolygon.push_back(pt);
1054  }
1055  aBoard.fillPolyline(aPolygon);
1056 }
1057 
1058 
1059 
1060 
1061 // GridCurve
1062 
1063 // SCellsRange
1064 template <typename TIterator, typename TSCell>
1065 void DGtal::Display2DFactory::draw( DGtal::Board2D & aBoard,
1066  const ConstRangeAdapter<TIterator, functors::Identity, TSCell> & object )
1067 {
1068  typedef ConstRangeAdapter<TIterator, functors::Identity, TSCell> Range;
1069  typedef typename Range::ConstIterator ConstIterator;
1070 
1071  ConstIterator it ( object.begin() );
1072  ConstIterator itEnd ( object.end() );
1073  for( ; it != itEnd; ++it)
1074  {
1075  aBoard << *it;
1076  }
1077 }
1078 // SCellsRange
1079 
1080 // PointsRange
1081 template <typename TIterator, typename TKSpace>
1082 void DGtal::Display2DFactory::draw( DGtal::Board2D & aBoard,
1083  const ConstRangeAdapter<TIterator, functors::SCellToPoint<TKSpace>, typename TKSpace::Point> & object )
1084 {
1085  typedef ConstRangeAdapter<TIterator, functors::SCellToPoint<TKSpace>, typename TKSpace::Point> Range;
1086  typedef typename Range::ConstIterator ConstIterator;
1087 
1088  ConstIterator it ( object.begin() );
1089  ConstIterator itEnd ( object.end() );
1090  for( ; it != itEnd; ++it)
1091  {
1092  aBoard << SetMode(it->className(),"Grid");
1093  aBoard << *it;
1094  }
1095 }
1096 // PointsRange
1097 
1098 // MidPointsRange
1099 template <typename TIterator, typename TKSpace>
1100 void DGtal::Display2DFactory::draw( DGtal::Board2D & aBoard,
1101  const ConstRangeAdapter<TIterator, CanonicSCellEmbedder<TKSpace>,
1102  typename TKSpace::Space::RealPoint> & object )
1103 {
1104  typedef typename TKSpace::Space::RealPoint RPoint;
1105  typedef ConstRangeAdapter<TIterator, CanonicSCellEmbedder<TKSpace>, RPoint > Range;
1106  typedef typename Range::ConstIterator ConstIterator;
1107 
1108  ConstIterator it ( object.begin() );
1109  ConstIterator itEnd ( object.end() );
1110  for( ; it != itEnd; ++it)
1111  {
1112  RPoint p(*it);
1113  double s = 0.1;
1114  aBoard.drawLine( p[0]-s, p[1]-s, p[0]+s, p[1]+s );
1115  aBoard.drawLine( p[0]-s, p[1]+s, p[0]+s, p[1]-s );
1116  }
1117 }
1118 // MidPointsRange
1119 
1120 // ArrowsRange
1121 template <typename TIterator, typename TKSpace>
1122 void DGtal::Display2DFactory::draw( DGtal::Board2D & aBoard,
1123  const ConstRangeAdapter<TIterator, functors::SCellToArrow<TKSpace>,
1124  std::pair<typename TKSpace::Point, typename TKSpace::Vector> > & object )
1125 {
1126  typedef typename TKSpace::Point Point;
1127  typedef typename TKSpace::Vector Vector;
1128  typedef std::pair<Point, Vector> Arrow;
1129  typedef ConstRangeAdapter<TIterator, functors::SCellToArrow<TKSpace>, Arrow > Range;
1130  typedef typename Range::ConstIterator ConstIterator;
1131 
1132  ConstIterator it ( object.begin() );
1133  ConstIterator itEnd ( object.end() );
1134  for( ; it != itEnd; ++it)
1135  {
1136  Arrow a(*it);
1137  Vector shift( a.second );
1138  aBoard << CustomStyle( shift.className(),
1139  new CustomPen( Color::Black, Color::Black, 1.0,
1140  Board2D::Shape::SolidStyle,
1141  Board2D::Shape::RoundCap,
1142  Board2D::Shape::RoundJoin ) );
1143  draw(aBoard, shift, a.first);
1144  }
1145 }
1146 // ArrowsRange
1147 
1148 // InnerPointsRange
1149 template <typename TIterator, typename TKSpace>
1150 void DGtal::Display2DFactory::draw( DGtal::Board2D & aBoard,
1151  const ConstRangeAdapter<TIterator, functors::SCellToInnerPoint<TKSpace>,
1152  typename TKSpace::Point > & object )
1153 {
1154  typedef typename TKSpace::Point Point;
1155  typedef ConstRangeAdapter<TIterator, functors::SCellToInnerPoint<TKSpace>, Point > Range;
1156  typedef typename Range::ConstIterator ConstIterator;
1157 
1158  ConstIterator it ( object.begin() );
1159  ConstIterator itEnd ( object.end() );
1160  for( ; it != itEnd; ++it)
1161  {
1162  aBoard << SetMode( it->className(), "Both" )
1163  << CustomStyle( it->className(),
1164  new CustomFillColor( Color::Blue ) )
1165  << *it;
1166  }
1167 }
1168 // InnerPointsRange
1169 
1170 // OuterPointsRange
1171 template <typename TIterator, typename TKSpace>
1172 void DGtal::Display2DFactory::draw( DGtal::Board2D & aBoard,
1173  const ConstRangeAdapter<TIterator, functors::SCellToOuterPoint<TKSpace>,
1174  typename TKSpace::Point > & object )
1175 {
1176  typedef typename TKSpace::Point Point;
1177  typedef ConstRangeAdapter<TIterator, functors::SCellToOuterPoint<TKSpace>, Point > Range;
1178  typedef typename Range::ConstIterator ConstIterator;
1179 
1180  ConstIterator it ( object.begin() );
1181  ConstIterator itEnd ( object.end() );
1182  for( ; it != itEnd; ++it)
1183  {
1184  aBoard << SetMode( it->className(), "Both" )
1185  << CustomStyle( it->className(),
1186  new CustomFillColor( Color::Green ) )
1187  << *it;
1188  }
1189 }
1190 // OuterPointsRange
1191 
1192 // IncidentPointsRange
1193 template <typename TIterator, typename TKSpace>
1194 void DGtal::Display2DFactory::draw( DGtal::Board2D & aBoard,
1195  const ConstRangeAdapter<TIterator, functors::SCellToIncidentPoints<TKSpace>,
1196  std::pair<typename TKSpace::Point, typename TKSpace::Point> > & object )
1197 {
1198  typedef typename TKSpace::Point Point;
1199  typedef std::pair<Point, Point> Pair;
1200  typedef ConstRangeAdapter<TIterator, functors::SCellToIncidentPoints<TKSpace>, Pair > Range;
1201  typedef typename Range::ConstIterator ConstIterator;
1202 
1203  ConstIterator it ( object.begin() );
1204  ConstIterator itEnd ( object.end() );
1205  for( ; it != itEnd; ++it)
1206  {
1207  Pair pair(*it);
1208  aBoard << SetMode( pair.first.className(), "Both" )
1209  << CustomStyle( pair.first.className(),
1210  new CustomFillColor( Color::Blue ) )
1211  << pair.first
1212  << CustomStyle( pair.second.className(),
1213  new CustomFillColor( Color::Green ) )
1214  << pair.second;
1215  }
1216 }
1217 // IncidentPointsRange
1218 
1219 // HyperRectDomain
1220 template<typename TSpace>
1221 inline
1222 void DGtal::Display2DFactory::drawAsGrid( DGtal::Board2D & aboard,
1223  const DGtal::HyperRectDomain<TSpace> & h )
1224 {
1225  typedef typename TSpace::Integer Integer;
1226 
1227  FATAL_ERROR(TSpace::dimension == 2 || "drawAsGrid-NOT-YET-IMPLEMENTED-in-ND");
1228 
1229  if (TSpace::dimension == 2)
1230  {
1231  for (double x = NumberTraits<Integer>::castToDouble(h.myLowerBound[0]);
1232  x <= NumberTraits<Integer>::castToDouble(h.myUpperBound[0]); x++)
1233  aboard.drawLine(x,
1234  NumberTraits<Integer>::castToDouble(h.myLowerBound[1]) -
1235  0.5,
1236  x,
1237  NumberTraits<Integer>::castToDouble(h.myUpperBound[1]) +
1238  0.5);
1239 
1240  for (double y = NumberTraits<Integer>::castToDouble(h.myLowerBound[1]);
1241  y <= NumberTraits<Integer>::castToDouble(h.myUpperBound[1]); y++)
1242  aboard.drawLine(NumberTraits<Integer>::castToDouble(h.myLowerBound[0]) -
1243  0.5,
1244  y,
1245  NumberTraits<Integer>::castToDouble(h.myUpperBound[0]) +
1246  0.5,
1247  y);
1248 
1249  for (double x = NumberTraits<Integer>::castToDouble(h.myLowerBound[0]);
1250  x <= NumberTraits<Integer>::castToDouble(h.myUpperBound[0]); x++)
1251  for (double y = NumberTraits<Integer>::castToDouble(h.myLowerBound[1]);
1252  y <= NumberTraits<Integer>::castToDouble(h.myUpperBound[1]); y++)
1253  aboard.fillCircle(x, y, 0.1);
1254  }
1255 }
1256 
1257 template<typename TSpace>
1258 inline
1259 void DGtal::Display2DFactory::drawAsPaving( DGtal::Board2D & aboard,
1260  const DGtal::HyperRectDomain<TSpace> & h )
1261 {
1262  typedef typename TSpace::Integer Integer;
1263 
1264  FATAL_ERROR(TSpace::dimension==2 || "drawAsPaving-NOT-YET-IMPLEMENTED-in-ND" );
1265 
1266  if (TSpace::dimension == 2)
1267  {
1268  for (DGtal::int64_t x = NumberTraits<Integer>::castToInt64_t(h.myLowerBound[0]);
1269  x <= NumberTraits<Integer>::castToInt64_t(h.myUpperBound[0]); x++)
1270  for (DGtal::int64_t y = NumberTraits<Integer>::castToInt64_t(h.myLowerBound[1]);
1271  y <= NumberTraits<Integer>::castToInt64_t(h.myUpperBound[1]); y++)
1272  aboard.drawRectangle(x - 0.5, y + 0.5, 1, 1);
1273  }
1274 }
1275 
1276 template<typename TSpace>
1277 inline
1278 void DGtal::Display2DFactory::draw( DGtal::Board2D & board,
1279  const DGtal::HyperRectDomain<TSpace> & h )
1280 {
1281  std::string mode = board.getMode( h.className() );
1282  FATAL_ERROR((mode=="" || mode=="Grid" || mode=="Paving") ||
1283  ("draw( DGtal::Board2D & board, const DGtal::HyperRectDomain<TSpace> & h ): Unknown mode "+mode)=="");
1284 
1285  if ( ( mode == "" ) || ( mode == "Grid" ) )
1286  drawAsGrid( board, h );
1287  else if ( mode == "Paving" )
1288  drawAsPaving( board, h );
1289 }
1290 // HyperRectDomain
1291 
1292 
1293 // ImageContainerByHashTree
1294 template <typename C, typename Domain, typename Value, typename HashKey>
1295 inline
1296 void DGtal::Display2DFactory::drawImageRecursive( DGtal::Board2D & aBoard,
1297  const DGtal::experimental::ImageContainerByHashTree<Domain, Value, HashKey> & i,
1298  HashKey key,
1299  const double p[2],
1300  const double len,
1301  LibBoard::Board & board,
1302  const C& cmap )
1303 {
1304 
1305  FATAL_ERROR ( Domain::dimension == 2 );
1306 
1307  double np[2], nlen;
1308 
1309  //Node* n = i.getNode ( key );
1310  if ( i.getNode ( key ) )
1311  {
1312  Color c;
1313  c = cmap ( i.getNode ( key )->getObject() );
1314  board.setFillColorRGBi ( c.red(), c.green(), c.blue() );
1315 
1316  board.drawRectangle ( p[0], p[1], len, len );
1317  }
1318  else
1319  {
1320  HashKey children[4];
1321  i.myMorton.childrenKeys ( key, children );
1322 
1323  nlen = len / 2.0;
1324 
1325  np[0] = p[0];
1326  np[1] = p[1] - nlen;
1327  drawImageRecursive<C>( aBoard, i, children[0], np, nlen, board, cmap );
1328 
1329  np[0] = p[0] + nlen;
1330  np[1] = p[1] - nlen;
1331  drawImageRecursive<C>( aBoard, i, children[1], np, nlen, board, cmap );
1332 
1333  np[0] = p[0];
1334  np[1] = p[1];
1335  drawImageRecursive<C>( aBoard, i, children[2], np, nlen, board, cmap );
1336 
1337  np[0] = p[0] + nlen;
1338  np[1] = p[1];
1339  drawImageRecursive<C>( aBoard, i, children[3], np, nlen, board, cmap );
1340  }
1341 }
1342 
1343 template <typename C, typename Domain, typename Value, typename HashKey>
1344 inline
1345 void DGtal::Display2DFactory::drawImageHashTree( Board2D & board,
1346  const DGtal::experimental::ImageContainerByHashTree<Domain, Value, HashKey> & i,
1347  const Value &minV, const Value &maxV )
1348 {
1349  static const HashKey ROOT_KEY = static_cast<HashKey>(1);
1350 
1351  FATAL_ERROR ( Domain::dimension == 2 );
1352 
1353  C colormap ( minV, maxV );
1354 
1355  double p[2];
1356  double len;
1357 
1358  p[0] = i.myOrigin[0];
1359  p[1] = i.myOrigin[1] + i.getSpanSize();
1360 
1361  len = i.getSpanSize();
1362 
1363  drawImageRecursive<C>( board, i, ROOT_KEY, p, len, board, colormap );
1364 }
1365 // ImageContainerByHashTree
1366 
1367 // Draw image generic
1368 // ImageContainerBySTLVector, ImageContainerByHashTree, Image and ImageAdapter...
1369 template <typename Colormap, typename Image>
1370 inline
1371 void DGtal::Display2DFactory::drawImage( DGtal::Board2D & board,
1372  const Image & i,
1373  const typename Image::Value & minV,
1374  const typename Image::Value & maxV )
1375 {
1376  typedef typename Image::Domain D;
1377 
1378  FATAL_ERROR(D::Space::dimension == 2);
1379 
1380  Colormap colormap(minV, maxV);
1381  Color c;
1382  typename Image::Value val;
1383  for (typename Image::Domain::ConstIterator it = i.domain().begin();
1384  it != i.domain().end(); ++it)
1385  {
1386  val = i.operator()( (*it) );
1387  c = colormap( val );
1388  board.setFillColorRGBi( c.red(), c.green(), c.blue());
1389  board.drawRectangle( NumberTraits<typename Image::Domain::Space::Integer>::
1390  castToDouble((*it)[0]) - 0.5,
1391  NumberTraits<typename Image::Domain::Space::Integer>::
1392  castToDouble((*it)[1]) + 0.5, 1, 1);
1393  }
1394 }
1395 
1396 // KhalimskyPreCell
1397 template < DGtal::Dimension dim, typename TInteger >
1398 inline
1399 void DGtal::Display2DFactory::draw( DGtal::Board2D & board,
1400  const DGtal::KhalimskyCell<dim, TInteger> & k )
1401 {
1402  draw( board, k.preCell() );
1403 }
1404 
1405 // KhalimskyPreCell
1406 template < DGtal::Dimension dim, typename TInteger >
1407 inline
1408 void DGtal::Display2DFactory::draw( DGtal::Board2D & board,
1409  const DGtal::KhalimskyPreCell<dim, TInteger> & k )
1410 {
1411  FATAL_ERROR( dim == 2 );
1412 
1413  float x = (float)
1414  ( NumberTraits<TInteger>::castToInt64_t( k.coordinates[0] ) >> 1 );
1415  float y = (float)
1416  ( NumberTraits<TInteger>::castToInt64_t( k.coordinates[1] ) >> 1 );
1417  float retract = 0.05f;
1418  bool xodd = ( k.coordinates[ 0 ] & 1 );
1419  bool yodd = ( k.coordinates[ 1 ] & 1 );
1420  float dx = xodd ? 1.0f - 2.0f*retract : 2.0f*retract;
1421  float dy = yodd ? 1.0f - 2.0f*retract : 2.0f*retract;
1422  board.drawRectangle( !xodd ? x - retract - 0.5 : x + retract - 0.5,
1423  !yodd ? y + retract - 0.5 : y - retract + 0.5,
1424  dx, dy );
1425 }
1426 // KhalimskyPreCell
1427 
1428 
1429 // Object
1430 template <typename TDigitalTopology, typename TDigitalSet>
1431 inline
1432 void DGtal::Display2DFactory::drawWithAdjacencies( DGtal::Board2D & aBoard,
1433  const DGtal::Object<TDigitalTopology, TDigitalSet> & o )
1434 {
1435  typedef TDigitalSet DigitalSet;
1436  typedef typename DigitalSet::Point Point;
1437 
1438  typedef TDigitalTopology DigitalTopology;
1439  typedef typename DigitalSet::Domain Domain;
1440  typedef
1441  typename DigitalSetSelector < Domain,
1442  SMALL_DS + HIGH_ITER_DS >::Type SmallSet;
1443  typedef Object<DigitalTopology, SmallSet> SmallObject;
1444 
1445  Point p;
1446 
1447  for (typename TDigitalSet::ConstIterator it = o.pointSet().begin();
1448  it != o.pointSet().end();
1449  ++it)
1450  {
1451  //Brute-force scan of the neighborhood.
1452  SmallObject neig = o.properNeighborhood(*it);
1453  for (typename SmallObject::DigitalSet::ConstIterator it2 = neig.pointSet().begin();
1454  it2 != neig.pointSet().end();
1455  ++it2)
1456  {
1457  p = (*it2) - (*it);
1458  draw(aBoard, p, (*it));
1459  }
1460  }
1461 }
1462 
1463 template <typename TDigitalTopology, typename TDigitalSet>
1464 inline
1465 void DGtal::Display2DFactory::draw( DGtal::Board2D & board,
1466  const DGtal::Object<TDigitalTopology, TDigitalSet> & o )
1467 {
1468  std::string mode = board.getMode( o.className() );
1469  if ( mode == "" )
1470  draw( board, o.pointSet() );
1471  else
1472  if ( mode == "DrawAdjacencies" )
1473  {
1474  draw( board, o.pointSet() );
1475  drawWithAdjacencies( board, o );
1476  }
1477  else
1478  FATAL_ERROR(false && (("draw( DGtal::Board2D & board, const DGtal::Object<TDigitalTopology, TDigitalSet> & o ): Unknown mode " + mode) == ""));
1479 }
1480 // Object
1481 
1482 // CubicalComplex
1483 template < typename TKSpace, typename TCellContainer >
1484 inline
1485 void
1486 DGtal::Display2DFactory::draw( DGtal::Board2D & board,
1487  const DGtal::CubicalComplex<TKSpace, TCellContainer> & cc )
1488 {
1489  FATAL_ERROR( cc.dimension == 2);
1490  typedef DGtal::CubicalComplex<TKSpace, TCellContainer> CC;
1491  typedef typename CC::KSpace KSpace;
1492  typedef typename CC::Point Point;
1493  typedef typename CC::ConstIterator ConstIterator;
1494  typedef typename KSpace::Integer Integer;
1495  for ( ConstIterator it = cc.begin(), itE = cc.end(); it != itE; ++it )
1496  { // We are not using operator << for cells in order to use the
1497  // style specified for the cubical complex.
1498  Point kx = cc.space().uKCoords( *it );
1499  float x = (float) ( NumberTraits<Integer>::castToInt64_t( kx[0] ) >> 1 );
1500  float y = (float) ( NumberTraits<Integer>::castToInt64_t( kx[1] ) >> 1 );
1501  float retract = 0.05f;
1502  bool xodd = ( kx[ 0 ] & 1 );
1503  bool yodd = ( kx[ 1 ] & 1 );
1504  float dx = xodd ? 1.0f - 2.0f*retract : 2.0f*retract;
1505  float dy = yodd ? 1.0f - 2.0f*retract : 2.0f*retract;
1506  board.drawRectangle( !xodd ? x - retract - 0.5 : x + retract - 0.5,
1507  !yodd ? y + retract - 0.5 : y - retract + 0.5,
1508  dx, dy );
1509  }
1510 }
1511 // CubicalComplex
1512 
1513 
1514 // PointVector
1515 template<DGtal::Dimension dim, typename TComponent>
1516 inline
1517 void DGtal::Display2DFactory::drawAsPaving( DGtal::Board2D & board,
1518  const DGtal::PointVector<dim,TComponent> & p )
1519 {
1520  FATAL_ERROR(dim == 2);
1521  board.drawRectangle( (float) NumberTraits<TComponent>::castToDouble(p[0]) - 0.5f,
1522  (float) NumberTraits<TComponent>::castToDouble(p[1]) + 0.5f, 1, 1 );
1523 }
1524 
1525 template<DGtal::Dimension dim, typename TComponent>
1526 inline
1527 void DGtal::Display2DFactory::drawAsGrid( DGtal::Board2D & board,
1528  const DGtal::PointVector<dim,TComponent> & p )
1529 {
1530  FATAL_ERROR(dim == 2);
1531  board.fillCircle((float) NumberTraits<TComponent>::castToDouble(p[0]),
1532  (float) NumberTraits<TComponent>::castToDouble(p[1]),0.1);
1533 }
1534 
1535 template<DGtal::Dimension dim, typename TComponent>
1536 inline
1537 void DGtal::Display2DFactory::draw( DGtal::Board2D & board,
1538  const DGtal::PointVector<dim,TComponent> & p )
1539 {
1540  std::string mode = board.getMode( p.className() );
1541  FATAL_ERROR( (mode=="Paving" || mode=="Grid" || mode=="Both" || mode=="") ||
1542  ("draw( DGtal::Board2D & board, const DGtal::PointVector<dim,TComponent> & p ): Unknown mode "+mode)=="" );
1543 
1544  if ( mode == "Paving" || ( mode == "" ) )
1545  drawAsPaving( board, p );
1546  else if ( mode == "Grid" )
1547  drawAsGrid( board, p );
1548  else if ( ( mode == "Both" ))
1549  {
1550  drawAsPaving( board, p );
1551  drawAsGrid( board, p );
1552  }
1553 }
1554 
1555 template<DGtal::Dimension dim, typename TComponent>
1556 inline
1557 void DGtal::Display2DFactory::draw( DGtal::Board2D & board,
1558  const DGtal::PointVector<dim,TComponent> & p,
1559  const DGtal::PointVector<dim,TComponent> & apoint )
1560 {
1561  FATAL_ERROR(dim == 2);
1562 
1563  board.drawArrow((float)apoint[0], (float) apoint[1],
1564  (float) apoint[0] + p[0], (float)apoint[1] + p[1],
1565  true);
1566 }
1567 // PointVector
1568 
1569 
1570 // Preimage2D
1571 template <typename Shape>
1572 inline
1573 void DGtal::Display2DFactory::draw( DGtal::Board2D & aBoard,
1574  const DGtal::Preimage2D<Shape> & p )
1575 {
1576  typedef typename Shape::Point Point;
1577  typedef typename std::list<Point>::const_iterator ConstForwardIterator;
1578 
1579  // now with accessor
1580  Shape s( p.shape() );
1581  ConstForwardIterator i = p.pHull().begin();
1582  Point pt(*i);
1583  ++i;
1584  while ( i != p.pHull().end() ) {
1585  s.init(pt, *i);
1586  draw(aBoard, s); //s.setStyle(aBoard);
1587  pt = Point(*i);
1588  ++i;
1589  }
1590 
1591  i = p.qHull().begin();
1592  pt = Point(*i);
1593  ++i;
1594  while ( i != p.qHull().end() ) {
1595  s.init(pt, *i);
1596  draw(aBoard, s); //s.setStyle(aBoard);
1597  pt = Point(*i);
1598  ++i;
1599  }
1600 
1601  Point Pf(*p.pHull().begin());
1602  Point Pl(*p.pHull().rbegin());
1603  Point Qf(*p.qHull().begin());
1604  Point Ql(*p.qHull().rbegin());
1605 
1606  s.init(Pf, Ql);
1607  draw(aBoard, s); //s.setStyle(aBoard);
1608  s.init(Qf, Pl);
1609  draw(aBoard, s); //s.setStyle(aBoard);
1610 }
1611 // Preimage2D
1612 
1613 // SignedKhalimskyCell
1614 template < DGtal::Dimension dim, typename TInteger >
1615 inline
1616 void DGtal::Display2DFactory::draw( DGtal::Board2D & board,
1617  const DGtal::SignedKhalimskyCell<dim, TInteger> & sk )
1618 {
1619  draw( board, static_cast< DGtal::SignedKhalimskyPreCell<dim, TInteger> const& >(sk) );
1620 }
1621 
1622 // SignedKhalimskyPreCell
1623 template < DGtal::Dimension dim, typename TInteger >
1624 inline
1625 void DGtal::Display2DFactory::draw( DGtal::Board2D & board,
1626  const DGtal::SignedKhalimskyPreCell<dim, TInteger> & sk )
1627 {
1628  FATAL_ERROR( dim == 2 );
1629  float x = (float)
1630  ( NumberTraits<TInteger>::castToInt64_t( sk.coordinates[0] ) >> 1 );
1631  float y = (float)
1632  ( NumberTraits<TInteger>::castToInt64_t( sk.coordinates[1] ) >> 1 );
1633  float retract = 0.05f;
1634  bool xodd = ( sk.coordinates[ 0 ] & 1 );
1635  bool yodd = ( sk.coordinates[ 1 ] & 1 );
1636  float dx = xodd ? 1.0f - 2.0f*retract : 2.0f*retract;
1637  float dy = yodd ? 1.0f - 2.0f*retract : 2.0f*retract;
1638  board.drawRectangle( !xodd ? x - retract - 0.5 : x + retract - 0.5,
1639  !yodd ? y + retract - 0.5 : y - retract + 0.5,
1640  dx, dy );
1641 }
1642 // SignedKhalimskyPreCell
1643 
1644 
1645 // StraightLineFrom2Points
1646 template <typename TPoint>
1647 inline
1648 void DGtal::Display2DFactory::draw(Board2D & aBoard, const DGtal::StraightLineFrom2Points<TPoint> & slf2p)
1649 {
1650  // now with accessor
1651  aBoard.drawLine(slf2p.p()[0],slf2p.p()[1],slf2p.q()[0],slf2p.q()[1]);
1652 }
1653 // StraightLineFrom2Points
1654 
1655 
1656 //
1657 
1658 
1659 inline
1660 void DGtal::Display2DFactory::draw( DGtal::Board2D & board,
1661  const DGtal::CustomStyle & cs )
1662 {
1663  board.myStyles[ cs.myClassname ] = cs.myStyle;
1664 }
1665 
1666 inline
1667 void DGtal::Display2DFactory::draw( DGtal::Board2D & board,
1668  const DGtal::SetMode & sm )
1669 {
1670  board.myModes[ sm.myClassname ] = sm.myMode;
1671 }
1672 
1673 template <typename TSpace, typename TSequence>
1674 inline
1675 void
1676 DGtal::Display2DFactory::draw
1677 ( DGtal::Board2D & aBoard,
1678  const DGtal::LatticePolytope2D<TSpace, TSequence> & cip )
1679 {
1680  typedef typename LibBoard::Point BoardPoint;
1681  typedef typename DGtal::LatticePolytope2D<TSpace>::Point CIPPoint;
1682  typedef typename DGtal::LatticePolytope2D<TSpace>::ConstIterator ConstIterator;
1683  typedef typename DGtal::LatticePolytope2D<TSpace>::Integer Integer;
1684  std::string mode = aBoard.getMode( cip.className() );
1685  FATAL_ERROR( mode=="Filled" || mode=="" || mode=="Transparent" ||
1686  ("draw(Board2D & aBoard, const DGtal::LatticePolytope2D<Space,Sequence> & cip): Unknown mode "+mode)=="" );
1687 
1688  std::vector<BoardPoint> pts;
1689 
1690  for ( ConstIterator it = cip.begin(), it_end = cip.end(); it != it_end; ++it )
1691  {
1692  CIPPoint p = *it;
1693  pts.push_back( BoardPoint( NumberTraits<Integer>::castToDouble( p[ 0 ] ),
1694  NumberTraits<Integer>::castToDouble( p[ 1 ] ) ) );
1695  }
1696  aBoard.drawClosedPolyline( pts );
1697 }
1698 
1699 
1700 // //
1701 ///////////////////////////////////////////////////////////////////////////////