DGtal  1.0.0
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 <array>
47 #include <cmath>
48 
49 #include "DGtal/base/Common.h"
50 #include "DGtal/helpers/StdDefs.h"
51 #include "DGtal/kernel/SpaceND.h"
52 #include "DGtal/kernel/NumberTraits.h"
53 #include "DGtal/base/BasicBoolFunctors.h"
54 #include "DGtal/kernel/CPointPredicate.h"
55 #include "DGtal/base/CQuantity.h"
56 #include "DGtal/kernel/domains/CDomain.h"
57 #include "DGtal/base/ConstAlias.h"
59 
60 namespace DGtal
61 {
62 namespace functors
63  {
65  // template class Projector
105  template <typename S = SpaceND< 2, DGtal::Z2i::Integer > >
106  struct Projector
107  {
108  typedef S Space;
109  typedef typename Space::Dimension Dimension;
111  typedef typename Space::Integer Integer;
112  typedef typename Space::Point Point;
113 
117  Projector(const Integer& aDefaultInteger = NumberTraits<Integer>::zero());
118 
119 
125  template<typename TIterator>
126  void init ( const TIterator& itb, const TIterator& ite );
127 
128 
133  void initRemoveOneDim ( const Dimension &dimRemoved );
134 
139  void initAddOneDim ( const Dimension & newDim );
140 
141 
147  template<typename TInputPoint>
148  Point operator()( const TInputPoint& aPoint ) const;
149 
150  private:
155  std::array<Dimension, dimension> myDims;
156 
162 
163  }; // end of class ConstantPointFunctors
164 
165 
166 
167 
168 
199  template <typename TDomain3D, typename TInteger = DGtal::Z3i::Integer >
201  {
202  public:
203 
205  typedef typename Space::Dimension Dimension;
206  typedef typename Space::Point Point;
207  typedef typename Space::Integer Integer;
218  SliceRotator2D( const Dimension &dimAdded, const TDomain3D &aDomain3DImg,
219  const Integer &sliceIndex, const Dimension &dimRotated,
220  double rotationAngle):
221  myPosDimAdded(dimAdded), mySliceIndex(sliceIndex), myDomain(aDomain3DImg),
222  myDimRotated(dimRotated), myRotationAngle(rotationAngle), myDefaultPoint (aDomain3DImg.lowerBound())
223  {
224  myCenter[0] = aDomain3DImg.lowerBound()[0]+((aDomain3DImg.upperBound())[0]-(aDomain3DImg.lowerBound())[0])/2.0;
225  myCenter[1] = aDomain3DImg.lowerBound()[1]+((aDomain3DImg.upperBound())[1]-(aDomain3DImg.lowerBound())[1])/2.0;
226  myCenter[2] = aDomain3DImg.lowerBound()[2]+((aDomain3DImg.upperBound())[2]-(aDomain3DImg.lowerBound())[2])/2.0;
227  myCenter[dimAdded]=sliceIndex;
228  };
229 
240  SliceRotator2D( const Dimension &dimAdded, const TDomain3D &aDomain3DImg,
241  const Integer &sliceIndex, const Dimension &dimRotated,
242  double rotationAngle, const Point &defaultPoint):
243  myPosDimAdded(dimAdded), mySliceIndex(sliceIndex), myDomain(aDomain3DImg),
244  myDimRotated(dimRotated), myRotationAngle(rotationAngle), myDefaultPoint (defaultPoint)
245  {
246  myCenter[0] = aDomain3DImg.lowerBound()[0]+((aDomain3DImg.upperBound())[0]-(aDomain3DImg.lowerBound())[0])/2.0;
247  myCenter[1] = aDomain3DImg.lowerBound()[1]+((aDomain3DImg.upperBound())[1]-(aDomain3DImg.lowerBound())[1])/2.0;
248  myCenter[2] = aDomain3DImg.lowerBound()[2]+((aDomain3DImg.upperBound())[2]-(aDomain3DImg.lowerBound())[2])/2.0;
249  myCenter[dimAdded]=sliceIndex;
250  };
251 
263  SliceRotator2D( const Dimension &dimAdded, const TDomain3D &aDomain3DImg, const Integer &sliceIndex,
264  const Dimension &dimRotated, const Point &ptCenter, double rotationAngle, const Point &defaultPoint):
265  myPosDimAdded(dimAdded), mySliceIndex(sliceIndex), myDomain(aDomain3DImg),
266  myDimRotated(dimRotated), myRotationAngle(rotationAngle), myCenter(ptCenter), myDefaultPoint (defaultPoint)
267  {
268  };
269 
281  SliceRotator2D( const Dimension &dimAdded, const TDomain3D &aDomain3DImg, const Integer &sliceIndex,
282  const Dimension &dimRotated, const Point &ptCenter, double rotationAngle):
283  myPosDimAdded(dimAdded), mySliceIndex(sliceIndex), myDomain(aDomain3DImg),
284  myDimRotated(dimRotated), myRotationAngle(rotationAngle), myCenter(ptCenter), myDefaultPoint (aDomain3DImg.lowerBound())
285  {
286  };
287 
294  template <typename TPointDimMinus>
295  inline
296  Point operator()(const TPointDimMinus& aPoint) const
297  {
298  Point pt;
299  Dimension pos=0;
300  std::vector<Dimension> indexesRotate;
301  for( Dimension i=0; i<pt.size(); i++)
302  {
303  if(i!=myPosDimAdded)
304  {
305  pt[i]= aPoint[pos];
306  pos++;
307  }else
308  {
309  pt[i]=mySliceIndex;
310  }
311  }
312  for( Dimension i=0; i<pt.size(); i++)
313  {
314  if(i!=myDimRotated)
315  indexesRotate.push_back(i);
316  }
317  double d1 = pt[indexesRotate[0]] - myCenter[indexesRotate[0]];
318  double d2 = pt[indexesRotate[1]] - myCenter[indexesRotate[1]];
319 
320  pt[indexesRotate[0]] = myCenter[indexesRotate[0]] + static_cast<Integer>(round(d1*cos(myRotationAngle)-d2*sin(myRotationAngle) ));
321  pt[indexesRotate[1]] = myCenter[indexesRotate[1]] + static_cast<Integer>(round(d1*sin(myRotationAngle)+d2*cos(myRotationAngle) ));
322 
323  if(myDomain.isInside(pt))
324  return pt;
325  else
326  return myDefaultPoint;
327  }
328  private:
329  // position of insertion of the new dimension
331  // the index of the slice associated to the new domain.
333  TDomain3D myDomain;
338  };
339 
340 
371  template <typename TDomain3D, typename TInteger = DGtal::Z3i::Integer >
373  {
374  public:
375 
377  typedef typename Space::Point Point;
378  typedef typename Space::Integer Integer;
379 
390  Point2DEmbedderIn3D( const TDomain3D &aDomain3DImg,
391  const Point &anOriginPoint, const Point &anUpperPointOnAxis1,
392  const Point &anUpperPointOnAxis2,
393  const Point &aDefautPoint = Point(0,0,0)): myDomain(aDomain3DImg),
394  myOriginPointEmbeddedIn3D(anOriginPoint),
395  myDefaultPoint (aDefautPoint),
396  myFirstAxisEmbeddedDirection(Point(anUpperPointOnAxis1[0]-anOriginPoint[0],
397  anUpperPointOnAxis1[1]-anOriginPoint[1],
398  anUpperPointOnAxis1[2]-anOriginPoint[2])),
399  mySecondAxisEmbeddedDirection(Point(anUpperPointOnAxis2[0]-anOriginPoint[0],
400  anUpperPointOnAxis2[1]-anOriginPoint[1],
401  anUpperPointOnAxis2[2]-anOriginPoint[2]))
402 
403 
404  {
407  }
408 
409 
422  Point2DEmbedderIn3D( const TDomain3D &aDomain3DImg,
423  const Point &anOriginPoint, const typename Space::RealPoint & anNormalVector,
424  const typename Point::Component &anWidth,
425  const Point &aDefautPoint = Point(0,0,0)): myDomain(aDomain3DImg),
426  myDefaultPoint (aDefautPoint)
427  {
428  double d = -anNormalVector[0]*anOriginPoint[0] - anNormalVector[1]*anOriginPoint[1] - anNormalVector[2]*anOriginPoint[2];
429  typename Space::RealPoint pRefOrigin;
430  if(anNormalVector[0]!=0){
431  pRefOrigin [0]= -d/anNormalVector[0];
432  pRefOrigin [1]= 0.0;
433  pRefOrigin [2]= 0.0;
434  if(pRefOrigin==anOriginPoint){
435  pRefOrigin[1]=-1.0;
436  }
437  }else if (anNormalVector[1]!=0){
438  pRefOrigin [0]= 0.0;
439  pRefOrigin [1]= -d/anNormalVector[1];
440  pRefOrigin [2]= 0.0;
441  if(pRefOrigin==anOriginPoint){
442  pRefOrigin[0]=-1.0;
443  }
444  }else if (anNormalVector[2]!=0){
445  pRefOrigin [0]= 0.0;
446  pRefOrigin [1]= 0.0;
447  pRefOrigin [2]= -d/anNormalVector[2];
448  if(pRefOrigin==anOriginPoint){
449  pRefOrigin[0]=-1.0;
450  }
451  }
452  typename Space::RealPoint uDir1;
453  uDir1=(pRefOrigin-anOriginPoint)/((pRefOrigin-anOriginPoint).norm());
454  typename Space::RealPoint uDir2;
455  uDir2[0] = uDir1[1]*anNormalVector[2]-uDir1[2]*anNormalVector[1];
456  uDir2[1] = uDir1[2]*anNormalVector[0]-uDir1[0]*anNormalVector[2];
457  uDir2[2] = uDir1[0]*anNormalVector[1]-uDir1[1]*anNormalVector[0];
458 
459  uDir2/=uDir2.norm();
460 
461  myOriginPointEmbeddedIn3D = Point(anOriginPoint + uDir1*anWidth/2 + uDir2*anWidth/2, functors::Round<>());
464  }
465 
466 
467 
468 
476  template <typename TPoint2D>
477  inline
478  Point operator()(const TPoint2D& aPoint, bool checkInsideDomain=true) const
479  {
481  for( Dimension i=0; i<pt.size(); i++){
482 
483  pt[i] = pt[i]+static_cast<Integer>(floor(NumberTraits<Integer>::castToDouble(aPoint[0])
485  pt[i] = pt[i]+static_cast<Integer>(floor(NumberTraits<Integer>::castToDouble(aPoint[1])
487  }
488 
489  if(myDomain.isInside(pt)|| !checkInsideDomain)
490  {
491  return pt;
492  }
493  else
494  {
495 #ifdef DEBUG_VERBOSE
496  trace.warning() << "Warning pt outside the 3D domain " << pt << std::endl;
497 #endif
498  return myDefaultPoint;
499  }
500  }
501 
502  private:
503  TDomain3D myDomain;
504 
505  // Origin (or lower point) of the 2D image embedded in the 3D domain
507 
509 
510  // Point giving the direction of the embedded first axis of the 2D image.
512 
513  // Point giving the direction of the embedded second axis of the 2D image.
515 
516  };
517 
518 
522  template< typename TPointPredicate, typename TDomain, typename TValue=typename TDomain::Integer >
524  {
525  typedef TPointPredicate PointPredicate;
526  typedef TDomain Domain;
527  typedef TValue Value;
528  typedef typename Domain::Point Point;
529 
533 
542  const Value aTrueValue, const Value aFalseValue );
543 
545 
551  Value operator()( const Point& aPoint ) const;
552 
560 
561  private:
563  const Domain * myDomain;
566 
567  };
568 
569 
589  template <typename TDomain, typename TInteger = DGtal::int32_t, typename TValue = DGtal::uint32_t >
591  {
592  public:
593  typedef typename TDomain::Space Space;
594  typedef typename TDomain::Size Size;
595  typedef typename Space::Dimension Dimension;
596  typedef typename Space::Point Point;
597 
609  BasicDomainSubSampler(const TDomain &aSourceDomain, const std::vector<TValue> &aGridSize,
610  const Point &aGridShift): mySourceDomain(aSourceDomain),
611  myGridShift(aGridShift),
612  myGridSize(aGridSize)
613  {
614  Point domainUpperBound=aSourceDomain.upperBound();
615  Point domainLowerBound=aSourceDomain.lowerBound();
616 
617  for (Dimension dim=0; dim< Space::dimension; dim++){
618  domainLowerBound[dim] /= aGridSize[dim];
619  domainUpperBound[dim] /= aGridSize[dim];
620  }
621  myNewDomain = TDomain(domainLowerBound,
622  domainUpperBound);
623  Point upperGrid;
624  for (Dimension dim=0; dim < Space::dimension; dim++)
625  upperGrid[dim] = myGridSize[dim];
626  myGridSampleDomain = TDomain(Point::diagonal(0), upperGrid);
627  };
628 
629 
643  inline
644  Point operator()(const Point& aPoint) const
645  {
646  Point ptRes = Point::diagonal(0);
647  if(!myNewDomain.isInside(aPoint)){
648  trace.error() << " The point is not in the source domain: "<< aPoint << std::endl;
649  return ptRes;
650  }
651 
652  for (Dimension dim=0; dim< Space::dimension; dim++){
653  ptRes[dim] = static_cast<TInteger>(floor(NumberTraits<TInteger>::castToDouble(aPoint[dim])*
655  }
656  ptRes +=myGridShift;
657 
658  if(!mySourceDomain.isInside(ptRes)){
659  // we are looking for a point inside the domain
660  for(typename TDomain::ConstIterator it = myGridSampleDomain.begin();
661  it!= myGridSampleDomain.end(); it++){
662  if (mySourceDomain.isInside(ptRes+(*it)))
663  return ptRes+(*it);
664  }
665  }
666  return ptRes;
667  }
668 
675  inline
676  const TDomain & getSubSampledDomain(){
677  return myNewDomain;
678  }
679 
680  private:
681  TDomain mySourceDomain;
682  TDomain myNewDomain;
683  // used to search a point when the resulting point is outside the source domain.
686  std::vector<TValue> myGridSize;
687  };
688 
689 
707  template <typename TDomain>
709  {
710  public:
711  typedef typename TDomain::Space Space;
712  typedef typename TDomain::Size Size;
713  typedef typename Space::Dimension Dimension;
714  typedef typename Space::Point Point;
715 
728  FlipDomainAxis(const TDomain &aSourceDomain, const std::vector<Size> & axisFlipped): mySourceDomain(aSourceDomain),
729  myAxisFlipped(axisFlipped){
730  };
731 
732 
742  inline
743  Point operator()(const Point& aPoint) const
744  {
745  Point ptRes;
746  for (Dimension dim=0; dim< Space::dimension; dim++){
747  ptRes[dim] = aPoint[dim];
748  }
749  for(Dimension i = 0; i< myAxisFlipped.size(); i++){
750  ptRes[myAxisFlipped[i]] = mySourceDomain.upperBound()[myAxisFlipped[i]]-aPoint[myAxisFlipped[i]];
751  }
752  return ptRes;
753  }
754 
755  private:
756  TDomain mySourceDomain;
757  std::vector<Size> myAxisFlipped;
758  };
759 
760 
761  template <typename TRealVector, typename TVector>
763  {
764  BOOST_STATIC_ASSERT(( TRealVector::dimension == TVector::dimension ));
765  inline
766  TVector operator () ( const TRealVector & point ) const
767  {
768  TVector out;
769  for ( unsigned int i = 0; i < TVector::dimension; i++ )
770  out[i] = std::round ( point[i] );
771  return out;
772  }
773  };
774 
775  }//namespace functors
776 } // namespace dgtal
777 
778 
780 // Includes inline functions.
781 #include "DGtal/kernel/BasicPointFunctors.ih"
782 // //
784 
785 #endif // !defined BasicPointFunctors_h
786 #undef BasicPointFunctors_RECURSES
787 #endif // else defined(BasicPointFunctors_RECURSES)
const Point aPoint(3, 4)
static const Dimension dimension
static constants to store the dimension.
Definition: SpaceND.h:132
BOOST_CONCEPT_ASSERT((concepts::CPointPredicate< PointPredicate >))
MyDigitalSurface::ConstIterator ConstIterator
Trace trace
Definition: Common.h:144
static Self diagonal(Component val=1)
Aim: This class encapsulates its parameter class so that to indicate to the user that the object/poin...
Definition: ConstAlias.h:186
DGtal::uint32_t Dimension
Definition: Common.h:127
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....
TVector operator()(const TRealVector &point) const
BOOST_STATIC_ASSERT((TRealVector::dimension==TVector::dimension))
DGtal::Dimension Dimension
Copy of the type used for the dimension.
Definition: SpaceND.h:129
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:531
double norm(const NormType type=L_2) const
Point operator()(const TPoint2D &aPoint, bool checkInsideDomain=true) const
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
Value operator()(const Point &aPoint) const
operator ()
Aim: defines the concept of quantity in DGtal.
Definition: CQuantity.h:92
Point operator()(const TInputPoint &aPoint) const
Functor that rounds to the nearest integer.
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.
Point operator()(const Point &aPoint) const
static Dimension size()
unsigned int dim(const Vector &z)
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())
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))
PointVector< 3, double > myCenter
std::ostream & error()
PointFunctorFromPointPredicateAndDomain(ConstAlias< PointPredicate > aPtrPredicate, ConstAlias< Domain > aDomain, const Value aTrueValue, const Value aFalseValue)
Constructor.
Point operator()(const TPointDimMinus &aPoint) const
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...
Point operator()(const Point &aPoint) const
Integer Component
Type for Vector elements.
Definition: PointVector.h:614