DGtal  0.9.2
DigitalShapesDecorator.h
1 
17 #pragma once
18 
30 #if defined(DigitalShapesDecorator_RECURSES)
31 #error Recursive header files inclusion detected in DigitalShapesDecorator.h
32 #else // defined(DigitalShapesDecorator_RECURSES)
33 
34 #define DigitalShapesDecorator_RECURSES
35 
36 #if !defined DigitalShapesDecorator_h
37 
38 #define DigitalShapesDecorator_h
39 
41 // Inclusions
42 #include <iostream>
43 #include "DGtal/base/Common.h"
44 #include "DGtal/base/ConstAlias.h"
45 
46 #include "DGtal/shapes/CDigitalBoundedShape.h"
47 #include "DGtal/shapes/CDigitalOrientedShape.h"
49 
50 namespace DGtal
51 {
52 
54  // template class DigitalShapesCSG
66  template <typename ShapeA, typename ShapeB>
68  {
69  protected:
71  {
75  };
76 
77  public:
80 
81  typedef typename ShapeA::Space Space;
82  typedef typename ShapeA::Point Point;
83 
89  : bIsValid(false)
90  {}
91 
98  : myShapeA(other.myShapeA), v_shapes(other.v_shapes),
100  bIsValid(other.bIsValid)
101  {}
102 
103 
110  : myShapeA( a )
111  {
112  myLowerBound = myShapeA->getLowerBound();
113  myUpperBound = myShapeA->getUpperBound();
114 
115  bIsValid = true;
116  }
117 
126  {
127  myShapeA = other.myShapeA;
128  v_shapes = other.v_shapes;
129 
130  myLowerBound = other.myLowerBound;
131  myUpperBound = other.myUpperBound;
132 
133  bIsValid = other.bIsValid;
134 
135  return *this;
136  }
137 
144  {
145  myShapeA = a;
146 
147  myLowerBound = myShapeA->getLowerBound();
148  myUpperBound = myShapeA->getUpperBound();
149 
150  bIsValid = true;
151  }
152 
160  {
163 
164  FATAL_ERROR_MSG( isValid(), "Operation invalid. Maybe you don't set a ShapeA object." );
165 
166  std::pair<e_operator, CountedConstPtrOrConstPtr< ShapeB > > shape( e_plus, b );
167 
168  for(Dimension i =0; i < Space::dimension; ++i)
169  {
170  myLowerBound[i] = std::min(myLowerBound[i], b->getLowerBound()[i]);
171  myUpperBound[i] = std::max(myUpperBound[i], b->getUpperBound()[i]);
172  }
173 
174  v_shapes.push_back(shape);
175  }
176 
184  {
187 
188  FATAL_ERROR_MSG( isValid(), "Operation invalid. Maybe you don't set a ShapeA object." );
189 
190  std::pair<e_operator, CountedConstPtrOrConstPtr< ShapeB > > shape( e_intersection, b );
191 
192  for(Dimension i=0; i < Space::dimension; ++i)
193  {
194  myLowerBound[i] = std::max(myLowerBound[i], b->getLowerBound()[i]);
195  myUpperBound[i] = std::min(myUpperBound[i], b->getUpperBound()[i]);
196  }
197 
198  v_shapes.push_back(shape);
199  }
200 
208  {
211 
212  FATAL_ERROR_MSG( isValid(), "Operation invalid. Maybe you don't set a ShapeA object." );
213 
214  std::pair<e_operator, CountedConstPtrOrConstPtr< ShapeB > > shape( e_minus, b );
215 
216  v_shapes.push_back(shape);
217 
218  }
219 
224  Point getLowerBound() const
225  {
226  FATAL_ERROR_MSG( isValid(), "Operation invalid. Maybe you don't set a ShapeA object." );
227 
228  return myLowerBound;
229  }
230 
235  Point getUpperBound() const
236  {
237  FATAL_ERROR_MSG( isValid(), "Operation invalid. Maybe you don't set a ShapeA object." );
238 
239  return myUpperBound;
240  }
241 
250  Orientation orientation( const Point & p ) const
251  {
252  FATAL_ERROR_MSG( isValid(), "Operation invalid. Maybe you don't set a ShapeA object." );
253 
254  Orientation orient = myShapeA->orientation( p );
255 
256  for(unsigned int i = 0; i < v_shapes.size(); ++i)
257  {
258  if( v_shapes[i].first == e_minus )
259  {
260  if (( v_shapes[i].second->orientation( p ) == INSIDE ) || ( v_shapes[i].second->orientation( p ) == ON ))
261  {
262  orient = OUTSIDE;
263  }
264  }
265  else if( v_shapes[i].first == e_intersection )
266  {
267  if (( orient == ON ) && ( v_shapes[i].second->orientation( p ) != OUTSIDE ))
268  {
269  orient = ON;
270  }
271  else if (( v_shapes[i].second->orientation( p ) == ON ) && ( orient != OUTSIDE ))
272  {
273  orient = ON;
274  }
275  else if (( orient == INSIDE ) && ( v_shapes[i].second->orientation( p ) == INSIDE ))
276  {
277  orient = INSIDE;
278  }
279  else
280  {
281  orient = OUTSIDE;
282  }
283  }
284  else
285  {
286  if (( orient == INSIDE ) || ( v_shapes[i].second->orientation( p ) == INSIDE ))
287  {
288  orient = INSIDE;
289  }
290  else if (( orient == ON ) || ( v_shapes[i].second->orientation( p ) == ON ))
291  {
292  orient = ON;
293  }
294  else
295  {
296  orient = OUTSIDE;
297  }
298  }
299  }
300 
301  return orient;
302  }
303 
304  public:
305 
310  void selfDisplay ( std::ostream & out ) const;
311 
316  bool isValid() const
317  {
318  return bIsValid;
319  }
320 
321  // ------------------------- Internals ------------------------------------
322  private:
323 
326 
328  std::vector< std::pair<e_operator, CountedConstPtrOrConstPtr< ShapeB > > > v_shapes;
329 
332 
335 
337  bool bIsValid;
338 
339  };
340 
341 namespace deprecated
342 {
343 
345 // template class DigitalShapesUnion
353 template <typename ShapeA, typename ShapeB>
355 {
356  // ----------------------- Standard services ------------------------------
357 public:
362 
363  typedef typename ShapeA::Space Space;
364  typedef typename ShapeA::Point Point;
365 
373  : myShapeA( a ),
374  myShapeB( b )
375  {
376  Point shapeALowerBoundary = myShapeA.getLowerBound();
377  Point shapeBLowerBoundary = myShapeB.getLowerBound();
378  Point shapeAUpperBoundary = myShapeA.getUpperBound();
379  Point shapeBUpperBoundary = myShapeB.getUpperBound();
380  for ( unsigned int i = 0; i < myLowerBound.size(); ++i )
381  {
382  myLowerBound[ i ] = std::min( shapeALowerBoundary[ i ], shapeBLowerBoundary[ i ] );
383  myUpperBound[ i ] = std::max( shapeAUpperBoundary[ i ], shapeBUpperBoundary[ i ] );
384  }
385  }
386 
387 
392  Point getLowerBound() const
393  {
394  return myLowerBound;
395  }
396 
401  Point getUpperBound() const
402  {
403  return myUpperBound;
404  }
405 
413  Orientation orientation( const Point & p ) const
414  {
415  if (( myShapeA.orientation( p ) == INSIDE ) || ( myShapeB.orientation( p ) == INSIDE ))
416  {
417  return INSIDE;
418  }
419  else if (( myShapeA.orientation( p ) == ON ) || ( myShapeB.orientation( p ) == ON ))
420  {
421  return ON;
422  }
423  return OUTSIDE;
424  }
425 
430 
431  // ----------------------- Interface --------------------------------------
432 public:
433 
438  void selfDisplay ( std::ostream & out ) const;
439 
444  bool isValid() const;
445 
446  // ------------------------- Hidden services ------------------------------
447 protected:
448 
454 
455 private:
456 
462  DigitalShapesUnion ( const DigitalShapesUnion & other );
463 
471 
472  // ------------------------- Internals ------------------------------------
473 private:
474  const ShapeA & myShapeA;
475  const ShapeB & myShapeB;
476 
479 
480 }; // end of class DigitalShapesUnion
481 
483 // template class DigitalShapesIntersection
491 template <typename ShapeA, typename ShapeB>
493 {
494  // ----------------------- Standard services ------------------------------
495 public:
500 
501  typedef typename ShapeA::Space Space;
502  typedef typename ShapeA::Point Point;
503 
511  : myShapeA( a ),
512  myShapeB( b )
513  {
514  Point shapeALowerBoundary = myShapeA.getLowerBound();
515  Point shapeBLowerBoundary = myShapeB.getLowerBound();
516  Point shapeAUpperBoundary = myShapeA.getUpperBound();
517  Point shapeBUpperBoundary = myShapeB.getUpperBound();
518  for ( unsigned int i = 0; i < myLowerBound.size(); ++i )
519  {
520  myLowerBound[ i ] = std::min( shapeALowerBoundary[ i ], shapeBLowerBoundary[ i ] );
521  myUpperBound[ i ] = std::max( shapeAUpperBoundary[ i ], shapeBUpperBoundary[ i ] );
522  }
523  }
524 
525 
530  Point getLowerBound() const
531  {
532  return myLowerBound;
533  }
534 
539  Point getUpperBound() const
540  {
541  return myUpperBound;
542  }
543 
551  Orientation orientation( const Point & p ) const
552  {
553  if (( myShapeA.orientation( p ) == ON ) && ( myShapeB.orientation( p ) != OUTSIDE ))
554  {
555  return ON;
556  }
557  else if (( myShapeB.orientation( p ) == ON ) && ( myShapeA.orientation( p ) != OUTSIDE ))
558  {
559  return ON;
560  }
561  else if (( myShapeA.orientation( p ) == INSIDE ) && ( myShapeB.orientation( p ) == INSIDE ))
562  {
563  return INSIDE;
564  }
565 
566  return OUTSIDE;
567  }
568 
569 
574 
575  // ----------------------- Interface --------------------------------------
576 public:
577 
582  void selfDisplay ( std::ostream & out ) const;
583 
588  bool isValid() const;
589 
590  // ------------------------- Hidden services ------------------------------
591 protected:
592 
598 
599 private:
600 
607 
615 
616  // ------------------------- Internals ------------------------------------
617 private:
618  const ShapeA & myShapeA;
619  const ShapeB & myShapeB;
620 
623 
624 }; // end of class DigitalShapesIntersection
625 
627 // template class DigitalShapesMinus
635 template <typename ShapeA, typename ShapeB>
637 {
638  // ----------------------- Standard services ------------------------------
639 public:
644 
645  typedef typename ShapeA::Space Space;
646  typedef typename ShapeA::Point Point;
647 
655  : myShapeA( a ),
656  myShapeB( b )
657  {
658  Point shapeALowerBoundary = myShapeA.getLowerBound();
659  Point shapeBLowerBoundary = myShapeB.getLowerBound();
660  Point shapeAUpperBoundary = myShapeA.getUpperBound();
661  Point shapeBUpperBoundary = myShapeB.getUpperBound();
662  for ( unsigned int i = 0; i < myLowerBound.size(); ++i )
663  {
664  myLowerBound[ i ] = std::min( shapeALowerBoundary[ i ], shapeBLowerBoundary[ i ] );
665  myUpperBound[ i ] = std::max( shapeAUpperBoundary[ i ], shapeBUpperBoundary[ i ] );
666  }
667  }
668 
669 
674  Point getLowerBound() const
675  {
676  return myLowerBound;
677  }
678 
683  Point getUpperBound() const
684  {
685  return myUpperBound;
686  }
687 
695  Orientation orientation( const Point & p ) const
696  {
697  if (( myShapeB.orientation( p ) == INSIDE ) || ( myShapeB.orientation( p ) == ON ))
698  {
699  return OUTSIDE;
700  }
701  return myShapeA.orientation( p );
702  }
703 
704 
709 
710  // ----------------------- Interface --------------------------------------
711 public:
712 
717  void selfDisplay ( std::ostream & out ) const;
718 
723  bool isValid() const;
724 
725  // ------------------------- Hidden services ------------------------------
726 protected:
727 
733 
734 private:
735 
741  DigitalShapesMinus ( const DigitalShapesMinus & other );
742 
750 
751  // ------------------------- Internals ------------------------------------
752 private:
753  const ShapeA & myShapeA;
754  const ShapeB & myShapeB;
755 
758 
759 }; // end of class DigitalShapesMinus
760 }
761 
768  template <typename ShapeA, typename ShapeB>
769  std::ostream&
770  operator<< ( std::ostream & out, const deprecated::DigitalShapesUnion< ShapeA, ShapeB > & object );
771 
772  template <typename ShapeA, typename ShapeB>
773  std::ostream&
774  operator<< ( std::ostream & out, const deprecated::DigitalShapesIntersection< ShapeA, ShapeB > & object );
775 
776  template <typename ShapeA, typename ShapeB>
777  std::ostream&
778  operator<< ( std::ostream & out, const deprecated::DigitalShapesMinus< ShapeA, ShapeB > & object );
779 
780 } // namespace DGtal
781 
782 
783 
784 #endif // !defined DigitalShapesDecorator_h
785 
786 #undef DigitalShapesDecorator_RECURSES
787 #endif // else defined(DigitalShapesDecorator_RECURSES)
static const Dimension dimension
static constants to store the dimension.
Definition: SpaceND.h:132
BOOST_CONCEPT_ASSERT((concepts::CDigitalBoundedShape< ShapeA >))
CountedConstPtrOrConstPtr< ShapeA > myShapeA
Base Shape.
Aim: Minus between two models of CDigitalBoundedShape and CDigitalOrientedShape.
std::vector< std::pair< e_operator, CountedConstPtrOrConstPtr< ShapeB > > > v_shapes
Vector of all operations (ordered) of ShapeB.
DigitalShapesUnion & operator=(const DigitalShapesUnion &other)
Aim: This class encapsulates its parameter class so that to indicate to the user that the object/poin...
Definition: ConstAlias.h:186
void intersection(ConstAlias< ShapeB > b)
DGtal::uint32_t Dimension
Definition: Common.h:113
void setParams(ConstAlias< ShapeA > a)
void selfDisplay(std::ostream &out) const
DigitalShapesIntersection & operator=(const DigitalShapesIntersection &other)
BOOST_CONCEPT_ASSERT((concepts::CDigitalBoundedShape< ShapeA >))
DigitalShapesMinus & operator=(const DigitalShapesMinus &other)
Orientation orientation(const Point &p) const
Aim: designs the concept of bounded shapes in DGtal (shape for which upper and lower bounding bounds ...
Orientation
Definition: Common.h:118
Aim: characterizes models of digital oriented shapes. For example, models should provide an orientati...
void minus(ConstAlias< ShapeB > b)
Aim: Union between two models of CDigitalBoundedShape and CDigitalOrientedShape.
Orientation orientation(const Point &p) const
void plus(ConstAlias< ShapeB > b)
DigitalShapesUnion(ConstAlias< ShapeA > a, ConstAlias< ShapeB > b)
Point myLowerBound
Domain lower bound.
DigitalShapesCSG & operator=(const DigitalShapesCSG &other)
Aim: Constructive Solid Geometry (CSG) between models of CDigitalBoundedShape and CDigitalOrientedSha...
BOOST_CONCEPT_ASSERT((concepts::CDigitalBoundedShape< ShapeA >))
Aim: Intersection between two models of CDigitalBoundedShape and CDigitalOrientedShape.
void selfDisplay(std::ostream &out) const
DGtal is the top-level namespace which contains all DGtal functions and types.
Orientation orientation(const Point &p) const
bool bIsValid
if the CSG is valid.
DigitalShapesCSG(const DigitalShapesCSG &other)
DigitalShapesMinus(ConstAlias< ShapeA > a, ConstAlias< ShapeB > b)
BOOST_CONCEPT_ASSERT((concepts::CDigitalBoundedShape< ShapeA >))
void selfDisplay(std::ostream &out) const
DigitalShapesCSG(ConstAlias< ShapeA > a)
DigitalShapesIntersection(ConstAlias< ShapeA > a, ConstAlias< ShapeB > b)
void selfDisplay(std::ostream &out) const
Orientation orientation(const Point &p) const
Point myUpperBound
Domain upper bound.