DGtal  0.9.4beta
BasicPointFunctors.h
1 
17 #pragma once
18 
32 #if defined(BasicPointFunctors_RECURSES)
33 #error Recursive header files inclusion detected in BasicPointFunctors.h
34 #else // defined(BasicPointFunctors_RECURSES)
35 
36 #define BasicPointFunctors_RECURSES
37 
38 #if !defined BasicPointFunctors_h
39 
40 #define BasicPointFunctors_h
41 
43 // Inclusions
44 #include <iostream>
45 #include <iterator>
46 #include "DGtal/base/Common.h"
47 #include "DGtal/helpers/StdDefs.h"
48 #include "DGtal/kernel/SpaceND.h"
49 #include "DGtal/kernel/NumberTraits.h"
50 #include "DGtal/base/BasicBoolFunctors.h"
51 #include "DGtal/kernel/CPointPredicate.h"
52 #include "DGtal/base/CQuantity.h"
53 #include "DGtal/kernel/domains/CDomain.h"
54 #include "DGtal/base/ConstAlias.h"
55 #include <array>
57 
58 namespace DGtal
59 {
60 namespace functors
61  {
63  // template class Projector
103  template <typename S = SpaceND< 2, DGtal::Z2i::Integer > >
104  struct Projector
105  {
106  typedef S Space;
107  typedef typename Space::Dimension Dimension;
108  BOOST_STATIC_CONSTANT( Dimension, dimension = Space::dimension );
109  typedef typename Space::Integer Integer;
110  typedef typename Space::Point Point;
111 
115  Projector(const Integer& aDefaultInteger = NumberTraits<Integer>::zero());
116 
117 
123  template<typename TIterator>
124  void init ( const TIterator& itb, const TIterator& ite );
125 
126 
131  void initRemoveOneDim ( const Dimension &dimRemoved );
132 
137  void initAddOneDim ( const Dimension & newDim );
138 
139 
145  template<typename TInputPoint>
146  Point operator()( const TInputPoint& aPoint ) const;
147 
148  private:
153  std::array<Dimension, dimension> myDims;
154 
160 
161  }; // end of class ConstantPointFunctors
162 
163 
164 
165 
166 
197  template <typename TDomain3D, typename TInteger = DGtal::Z3i::Integer >
199  {
200  public:
201 
203  typedef typename Space::Dimension Dimension;
204  typedef typename Space::Point Point;
205  typedef typename Space::Integer Integer;
216  SliceRotator2D( const Dimension &dimAdded, const TDomain3D &aDomain3DImg,
217  const Integer &sliceIndex, const Dimension &dimRotated,
218  double rotationAngle):
219  myPosDimAdded(dimAdded), mySliceIndex(sliceIndex), myDomain(aDomain3DImg),
220  myDimRotated(dimRotated), myRotationAngle(rotationAngle), myDefaultPoint (aDomain3DImg.lowerBound())
221  {
222  myCenter[0] = aDomain3DImg.lowerBound()[0]+((aDomain3DImg.upperBound())[0]-(aDomain3DImg.lowerBound())[0])/2.0;
223  myCenter[1] = aDomain3DImg.lowerBound()[1]+((aDomain3DImg.upperBound())[1]-(aDomain3DImg.lowerBound())[1])/2.0;
224  myCenter[2] = aDomain3DImg.lowerBound()[2]+((aDomain3DImg.upperBound())[2]-(aDomain3DImg.lowerBound())[2])/2.0;
225  myCenter[dimAdded]=sliceIndex;
226  };
227 
238  SliceRotator2D( const Dimension &dimAdded, const TDomain3D &aDomain3DImg,
239  const Integer &sliceIndex, const Dimension &dimRotated,
240  double rotationAngle, const Point &defaultPoint):
241  myPosDimAdded(dimAdded), mySliceIndex(sliceIndex), myDomain(aDomain3DImg),
242  myDimRotated(dimRotated), myRotationAngle(rotationAngle), myDefaultPoint (defaultPoint)
243  {
244  myCenter[0] = aDomain3DImg.lowerBound()[0]+((aDomain3DImg.upperBound())[0]-(aDomain3DImg.lowerBound())[0])/2.0;
245  myCenter[1] = aDomain3DImg.lowerBound()[1]+((aDomain3DImg.upperBound())[1]-(aDomain3DImg.lowerBound())[1])/2.0;
246  myCenter[2] = aDomain3DImg.lowerBound()[2]+((aDomain3DImg.upperBound())[2]-(aDomain3DImg.lowerBound())[2])/2.0;
247  myCenter[dimAdded]=sliceIndex;
248  };
249 
261  SliceRotator2D( const Dimension &dimAdded, const TDomain3D &aDomain3DImg, const Integer &sliceIndex,
262  const Dimension &dimRotated, const Point &ptCenter, double rotationAngle, const Point &defaultPoint):
263  myPosDimAdded(dimAdded), mySliceIndex(sliceIndex), myDomain(aDomain3DImg),
264  myDimRotated(dimRotated), myRotationAngle(rotationAngle), myCenter(ptCenter), myDefaultPoint (defaultPoint)
265  {
266  };
267 
279  SliceRotator2D( const Dimension &dimAdded, const TDomain3D &aDomain3DImg, const Integer &sliceIndex,
280  const Dimension &dimRotated, const Point &ptCenter, double rotationAngle):
281  myPosDimAdded(dimAdded), mySliceIndex(sliceIndex), myDomain(aDomain3DImg),
282  myDimRotated(dimRotated), myRotationAngle(rotationAngle), myCenter(ptCenter), myDefaultPoint (aDomain3DImg.lowerBound())
283  {
284  };
285 
292  template <typename TPointDimMinus>
293  inline
294  Point operator()(const TPointDimMinus& aPoint) const
295  {
296  Point pt;
297  Dimension pos=0;
298  std::vector<Dimension> indexesRotate;
299  for( Dimension i=0; i<pt.size(); i++)
300  {
301  if(i!=myPosDimAdded)
302  {
303  pt[i]= aPoint[pos];
304  pos++;
305  }else
306  {
307  pt[i]=mySliceIndex;
308  }
309  }
310  for( Dimension i=0; i<pt.size(); i++)
311  {
312  if(i!=myDimRotated)
313  indexesRotate.push_back(i);
314  }
315  double d1 = pt[indexesRotate[0]] - myCenter[indexesRotate[0]];
316  double d2 = pt[indexesRotate[1]] - myCenter[indexesRotate[1]];
317 
318  pt[indexesRotate[0]] = myCenter[indexesRotate[0]] + static_cast<Integer>(round(d1*cos(myRotationAngle)-d2*sin(myRotationAngle) ));
319  pt[indexesRotate[1]] = myCenter[indexesRotate[1]] + static_cast<Integer>(round(d1*sin(myRotationAngle)+d2*cos(myRotationAngle) ));
320 
321  if(myDomain.isInside(pt))
322  return pt;
323  else
324  return myDefaultPoint;
325  }
326  private:
327  // position of insertion of the new dimension
328  Dimension myPosDimAdded;
329  // the index of the slice associated to the new domain.
330  Integer mySliceIndex;
331  TDomain3D myDomain;
332  Dimension myDimRotated;
336  };
337 
338 
369  template <typename TDomain3D, typename TInteger = DGtal::Z3i::Integer >
371  {
372  public:
373 
375  typedef typename Space::Point Point;
376  typedef typename Space::Integer Integer;
377 
388  Point2DEmbedderIn3D( const TDomain3D &aDomain3DImg,
389  const Point &anOriginPoint, const Point &anUpperPointOnAxis1,
390  const Point &anUpperPointOnAxis2,
391  const Point &aDefautPoint = Point(0,0,0)): myDomain(aDomain3DImg),
392  myOriginPointEmbeddedIn3D(anOriginPoint),
393  myDefaultPoint (aDefautPoint),
394  myFirstAxisEmbeddedDirection(Point(anUpperPointOnAxis1[0]-anOriginPoint[0],
395  anUpperPointOnAxis1[1]-anOriginPoint[1],
396  anUpperPointOnAxis1[2]-anOriginPoint[2])),
397  mySecondAxisEmbeddedDirection(Point(anUpperPointOnAxis2[0]-anOriginPoint[0],
398  anUpperPointOnAxis2[1]-anOriginPoint[1],
399  anUpperPointOnAxis2[2]-anOriginPoint[2]))
400 
401 
402  {
405  }
406 
407 
420  Point2DEmbedderIn3D( const TDomain3D &aDomain3DImg,
421  const Point &anOriginPoint, const typename Space::RealPoint & anNormalVector,
422  const typename Point::Component &anWidth,
423  const Point &aDefautPoint = Point(0,0,0)): myDomain(aDomain3DImg),
424  myDefaultPoint (aDefautPoint)
425  {
426  double d = -anNormalVector[0]*anOriginPoint[0] - anNormalVector[1]*anOriginPoint[1] - anNormalVector[2]*anOriginPoint[2];
427  typename Space::RealPoint pRefOrigin;
428  if(anNormalVector[0]!=0){
429  pRefOrigin [0]= -d/anNormalVector[0];
430  pRefOrigin [1]= 0.0;
431  pRefOrigin [2]= 0.0;
432  if(pRefOrigin==anOriginPoint){
433  pRefOrigin[1]=-1.0;
434  }
435  }else if (anNormalVector[1]!=0){
436  pRefOrigin [0]= 0.0;
437  pRefOrigin [1]= -d/anNormalVector[1];
438  pRefOrigin [2]= 0.0;
439  if(pRefOrigin==anOriginPoint){
440  pRefOrigin[0]=-1.0;
441  }
442  }else if (anNormalVector[2]!=0){
443  pRefOrigin [0]= 0.0;
444  pRefOrigin [1]= 0.0;
445  pRefOrigin [2]= -d/anNormalVector[2];
446  if(pRefOrigin==anOriginPoint){
447  pRefOrigin[0]=-1.0;
448  }
449  }
450  typename Space::RealPoint uDir1;
451  uDir1=(pRefOrigin-anOriginPoint)/((pRefOrigin-anOriginPoint).norm());
452  typename Space::RealPoint uDir2;
453  uDir2[0] = uDir1[1]*anNormalVector[2]-uDir1[2]*anNormalVector[1];
454  uDir2[1] = uDir1[2]*anNormalVector[0]-uDir1[0]*anNormalVector[2];
455  uDir2[2] = uDir1[0]*anNormalVector[1]-uDir1[1]*anNormalVector[0];
456 
457  uDir2/=uDir2.norm();
458 
459  myOriginPointEmbeddedIn3D = anOriginPoint + uDir1*anWidth/2 + uDir2*anWidth/2;
462 
463  }
464 
465 
466 
467 
475  template <typename TPoint2D>
476  inline
477  Point operator()(const TPoint2D& aPoint, bool checkInsideDomain=true) const
478  {
479  Point pt = myOriginPointEmbeddedIn3D;
480  for( Dimension i=0; i<pt.size(); i++){
481 
482  pt[i] = pt[i]+static_cast<Integer>(floor(NumberTraits<Integer>::castToDouble(aPoint[0])
484  pt[i] = pt[i]+static_cast<Integer>(floor(NumberTraits<Integer>::castToDouble(aPoint[1])
486  }
487 
488  if(myDomain.isInside(pt)|| !checkInsideDomain)
489  {
490  return pt;
491  }
492  else
493  {
494 #ifdef DEBUG_VERBOSE
495  trace.warning() << "Warning pt outside the 3D domain " << pt << std::endl;
496 #endif
497  return myDefaultPoint;
498  }
499  }
500 
501  private:
502  TDomain3D myDomain;
503 
504  // Origin (or lower point) of the 2D image embedded in the 3D domain
506 
508 
509  // Point giving the direction of the embedded first axis of the 2D image.
511 
512  // Point giving the direction of the embedded second axis of the 2D image.
514 
515  };
516 
517 
521  template< typename TPointPredicate, typename TDomain, typename TValue=typename TDomain::Integer >
523  {
524  typedef TPointPredicate PointPredicate;
525  typedef TDomain Domain;
526  typedef TValue Value;
527  typedef typename Domain::Point Point;
528 
532 
541  const Value aTrueValue, const Value aFalseValue );
542 
544 
550  Value operator()( const Point& aPoint ) const;
551 
559 
560  private:
561  const PointPredicate * myPtrPredicate;
562  const Domain * myDomain;
563  Value myTrueValue;
565 
566  };
567 
568 
588  template <typename TDomain, typename TInteger = DGtal::int32_t, typename TValue = DGtal::uint32_t >
590  {
591  public:
592  typedef typename TDomain::Space Space;
593  typedef typename TDomain::Size Size;
594  typedef typename Space::Dimension Dimension;
595  typedef typename Space::Point Point;
596 
608  BasicDomainSubSampler(const TDomain &aSourceDomain, const std::vector<TValue> &aGridSize,
609  const Point &aGridShift): mySourceDomain(aSourceDomain),
610  myGridShift(aGridShift),
611  myGridSize(aGridSize)
612  {
613  Point domainUpperBound=aSourceDomain.upperBound();
614  Point domainLowerBound=aSourceDomain.lowerBound();
615 
616  for (Dimension dim=0; dim< Space::dimension; dim++){
617  domainLowerBound[dim] /= aGridSize[dim];
618  domainUpperBound[dim] /= aGridSize[dim];
619  }
620  myNewDomain = TDomain(domainLowerBound,
621  domainUpperBound);
622  Point upperGrid;
623  for (Dimension dim=0; dim < Space::dimension; dim++)
624  upperGrid[dim] = myGridSize[dim];
625  myGridSampleDomain = TDomain(Point::diagonal(0), upperGrid);
626  };
627 
628 
642  inline
643  Point operator()(const Point& aPoint) const
644  {
645  Point ptRes = Point::diagonal(0);
646  if(!myNewDomain.isInside(aPoint)){
647  trace.error() << " The point is not in the source domain: "<< aPoint << std::endl;
648  return ptRes;
649  }
650 
651  for (Dimension dim=0; dim< Space::dimension; dim++){
652  ptRes[dim] = static_cast<TInteger>(floor(NumberTraits<TInteger>::castToDouble(aPoint[dim])*
654  }
655  ptRes +=myGridShift;
656 
657  if(!mySourceDomain.isInside(ptRes)){
658  // we are looking for a point inside the domain
659  for(typename TDomain::ConstIterator it = myGridSampleDomain.begin();
660  it!= myGridSampleDomain.end(); it++){
661  if (mySourceDomain.isInside(ptRes+(*it)))
662  return ptRes+(*it);
663  }
664  }
665  return ptRes;
666  }
667 
674  inline
675  const TDomain & getSubSampledDomain(){
676  return myNewDomain;
677  }
678 
679  private:
680  TDomain mySourceDomain;
681  TDomain myNewDomain;
682  // used to search a point when the resulting point is outside the source domain.
684  Point myGridShift;
685  std::vector<TValue> myGridSize;
686  };
687 
688 
706  template <typename TDomain>
708  {
709  public:
710  typedef typename TDomain::Space Space;
711  typedef typename TDomain::Size Size;
712  typedef typename Space::Dimension Dimension;
713  typedef typename Space::Point Point;
714 
727  FlipDomainAxis(const TDomain &aSourceDomain, const std::vector<Size> & axisFlipped): mySourceDomain(aSourceDomain),
728  myAxisFlipped(axisFlipped){
729  };
730 
731 
741  inline
742  Point operator()(const Point& aPoint) const
743  {
744  Point ptRes;
745  for (Dimension dim=0; dim< Space::dimension; dim++){
746  ptRes[dim] = aPoint[dim];
747  }
748  for(Dimension i = 0; i< myAxisFlipped.size(); i++){
749  ptRes[myAxisFlipped[i]] = mySourceDomain.upperBound()[myAxisFlipped[i]]-aPoint[myAxisFlipped[i]];
750  }
751  return ptRes;
752  }
753 
754  private:
755  TDomain mySourceDomain;
756  std::vector<Size> myAxisFlipped;
757  };
758 
759 
760 
761 
762 
763 
764 
765 
766 
767  }//namespace functors
768 } // namespace dgtal
769 
770 
772 // Includes inline functions.
773 #include "DGtal/kernel/BasicPointFunctors.ih"
774 // //
776 
777 #endif // !defined BasicPointFunctors_h
778 #undef BasicPointFunctors_RECURSES
779 #endif // else defined(BasicPointFunctors_RECURSES)
static const Dimension dimension
static constants to store the dimension.
Definition: SpaceND.h:132
BOOST_CONCEPT_ASSERT((concepts::CPointPredicate< PointPredicate >))
Trace trace
Definition: Common.h:137
static Self diagonal(Component val=1)
Aim: SpaceND is a utility class that defines the fundamental structure of a Digital Space in ND...
Definition: SpaceND.h:95
Aim: This class encapsulates its parameter class so that to indicate to the user that the object/poin...
Definition: ConstAlias.h:186
SliceRotator2D(const Dimension &dimAdded, const TDomain3D &aDomain3DImg, const Integer &sliceIndex, const Dimension &dimRotated, const Point &ptCenter, double rotationAngle)
PointFunctorFromPointPredicateAndDomain & operator=(const PointFunctorFromPointPredicateAndDomain &other)
SliceRotator2D(const Dimension &dimAdded, const TDomain3D &aDomain3DImg, const Integer &sliceIndex, const Dimension &dimRotated, const Point &ptCenter, double rotationAngle, const Point &defaultPoint)
void initRemoveOneDim(const Dimension &dimRemoved)
Aim: Functor that maps a point P of dimension i to a point Q of dimension j. The member myDims is an ...
Aim: Functor that subsamples an initial domain by given a grid size and a shift vector. By this way, for a given point considered in a new domain, it allows to recover the point coordinates in the source domain. Such functor can be usefull to apply basic image subsampling in any dimensions by using ImageAdapter class.
DGtal::Dimension Dimension
Copy of the type used for the dimension.
Definition: SpaceND.h:129
Point operator()(const TInputPoint &aPoint) const
Point operator()(const Point &aPoint) const
Aim: This concept represents a digital domain, i.e. a non mutable subset of points of the given digit...
Definition: CDomain.h:129
std::array< Dimension, dimension > myDims
Aim: Defines a predicate on a point.
Aim: Functor that embeds a 2D point into a 3D space from two axis vectors and an origin point given i...
Create a point functor from a point predicate and a domain.
Aim: The traits class for all models of Cinteger.
Definition: NumberTraits.h:69
SliceRotator2D(const Dimension &dimAdded, const TDomain3D &aDomain3DImg, const Integer &sliceIndex, const Dimension &dimRotated, double rotationAngle, const Point &defaultPoint)
Aim: Functor that flips the domain coordinate system from some selected axis. For instance...
TInteger Integer
Arithmetic ring induced by (+,-,*) and Integer numbers.
Definition: SpaceND.h:102
Aim: defines the concept of quantity in DGtal.
Definition: CQuantity.h:92
Point2DEmbedderIn3D(const TDomain3D &aDomain3DImg, const Point &anOriginPoint, const typename Space::RealPoint &anNormalVector, const typename Point::Component &anWidth, const Point &aDefautPoint=Point(0, 0, 0))
DGtal is the top-level namespace which contains all DGtal functions and types.
static Dimension size()
double norm(const NormType type=L_2) const
std::ostream & warning()
SliceRotator2D(const Dimension &dimAdded, const TDomain3D &aDomain3DImg, const Integer &sliceIndex, const Dimension &dimRotated, double rotationAngle)
void init(const TIterator &itb, const TIterator &ite)
void initAddOneDim(const Dimension &newDim)
BOOST_STATIC_CONSTANT(Dimension, dimension=Space::dimension)
Projector(const Integer &aDefaultInteger=NumberTraits< Integer >::zero())
Value operator()(const Point &aPoint) const
operator ()
Point operator()(const TPoint2D &aPoint, bool checkInsideDomain=true) const
Point operator()(const Point &aPoint) const
FlipDomainAxis(const TDomain &aSourceDomain, const std::vector< Size > &axisFlipped)
Point2DEmbedderIn3D(const TDomain3D &aDomain3DImg, const Point &anOriginPoint, const Point &anUpperPointOnAxis1, const Point &anUpperPointOnAxis2, const Point &aDefautPoint=Point(0, 0, 0))
Point operator()(const TPointDimMinus &aPoint) const
PointVector< 3, double > myCenter
std::ostream & error()
PointFunctorFromPointPredicateAndDomain(ConstAlias< PointPredicate > aPtrPredicate, ConstAlias< Domain > aDomain, const Value aTrueValue, const Value aFalseValue)
Constructor.
BasicDomainSubSampler(const TDomain &aSourceDomain, const std::vector< TValue > &aGridSize, const Point &aGridShift)
Special Point Functor that adds one dimension to a 2D point and apply on it a rotation of angle alpha...
Integer Component
Type for Vector elements.
Definition: PointVector.h:155