DGtal  1.5.beta
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)
36 #define BasicPointFunctors_RECURSES
37 
38 #if !defined BasicPointFunctors_h
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;
110  BOOST_STATIC_CONSTANT( Dimension, dimension = Space::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 & aNormalVector,
424  const typename Point::Component &aWidth,
425  const Point &aDefautPoint = Point(0,0,0)): myDomain(aDomain3DImg),
426  myDefaultPoint (aDefautPoint)
427  {
428  double d = -aNormalVector[0]*anOriginPoint[0] - aNormalVector[1]*anOriginPoint[1] - aNormalVector[2]*anOriginPoint[2];
429  typename Space::RealPoint pRefOrigin;
430  if(aNormalVector[0]!=0){
431  pRefOrigin [0]= -d/aNormalVector[0];
432  pRefOrigin [1]= 0.0;
433  pRefOrigin [2]= 0.0;
434  if(pRefOrigin==anOriginPoint){
435  pRefOrigin[1]=-1.0;
436  }
437  }else if (aNormalVector[1]!=0){
438  pRefOrigin [0]= 0.0;
439  pRefOrigin [1]= -d/aNormalVector[1];
440  pRefOrigin [2]= 0.0;
441  if(pRefOrigin==anOriginPoint){
442  pRefOrigin[0]=-1.0;
443  }
444  }else if (aNormalVector[2]!=0){
445  pRefOrigin [0]= 0.0;
446  pRefOrigin [1]= 0.0;
447  pRefOrigin [2]= -d/aNormalVector[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]*aNormalVector[2]-uDir1[2]*aNormalVector[1];
456  uDir2[1] = uDir1[2]*aNormalVector[0]-uDir1[0]*aNormalVector[2];
457  uDir2[2] = uDir1[0]*aNormalVector[1]-uDir1[1]*aNormalVector[0];
458 
459  uDir2/=uDir2.norm();
460 
461  myOriginPointEmbeddedIn3D = anOriginPoint + Point(uDir1*aWidth/2) + Point(uDir2*aWidth/2);
464  }
465 
466 
480  Point2DEmbedderIn3D( const TDomain3D &aDomain3DImg,
481  const Point &anOriginPoint, const typename Space::RealPoint & aNormalVector,
482  const typename Space::RealPoint & orientXaxisVector,
483  const typename Point::Component &aWidth,
484  const Point &aDefautPoint = Point(0,0,0)): myDomain(aDomain3DImg),
485  myDefaultPoint (aDefautPoint)
486  {
487 
488  typename Space::RealPoint uDir1;
489  uDir1 = orientXaxisVector/orientXaxisVector.norm();
490  typename Space::RealPoint uDir2;
491  uDir2[0] = uDir1[1]*aNormalVector[2]-uDir1[2]*aNormalVector[1];
492  uDir2[1] = uDir1[2]*aNormalVector[0]-uDir1[0]*aNormalVector[2];
493  uDir2[2] = uDir1[0]*aNormalVector[1]-uDir1[1]*aNormalVector[0];
494  uDir2/=uDir2.norm();
495  myOriginPointEmbeddedIn3D = anOriginPoint + Point(-uDir1*aWidth/2) + Point(-uDir2*aWidth/2);
498  }
499 
500 
508  template <typename TPoint2D>
509  inline
510  Point operator()(const TPoint2D& aPoint, bool checkInsideDomain=true) const
511  {
512  Point pt ;
513  for( Dimension i=0; i<pt.size(); i++){
514 
515  pt[i] = static_cast<Integer>(floor(NumberTraits<Integer>::castToDouble(aPoint[0])
517  pt[i] += static_cast<Integer>(floor(NumberTraits<Integer>::castToDouble(aPoint[1])
519  }
520 
521  if(myDomain.isInside(pt)|| !checkInsideDomain)
522  {
523  return pt;
524  }
525  else
526  {
527 #ifdef DEBUG_VERBOSE
528  trace.warning() << "Warning pt outside the 3D domain " << pt << std::endl;
529 #endif
530  return myDefaultPoint;
531  }
532  }
533 
534 
540  inline
541  void shiftOriginPoint(const typename Space::RealPoint& shift)
542  {
543  for( Dimension i=0; i<myOriginPointEmbeddedIn3D.size(); i++){
545  }
546  }
547 
548 
549  private:
550  TDomain3D myDomain;
551 
552  // Origin (or lower point) of the 2D image embedded in the 3D domain
554 
556 
557  // Point giving the direction of the embedded first axis of the 2D image.
559 
560  // Point giving the direction of the embedded second axis of the 2D image.
562 
563  };
564 
565 
569  template< typename TPointPredicate, typename TDomain, typename TValue=typename TDomain::Integer >
571  {
572  typedef TPointPredicate PointPredicate;
573  typedef TDomain Domain;
574  typedef TValue Value;
575  typedef typename Domain::Point Point;
576 
580 
589  const Value aTrueValue, const Value aFalseValue );
590 
592 
598  Value operator()( const Point& aPoint ) const;
599 
607 
608  private:
610  const Domain * myDomain;
613 
614  };
615 
616 
636  template <typename TDomain, typename TInteger = DGtal::int32_t, typename TValue = typename TDomain::Size >
638  {
639  public:
640  typedef typename TDomain::Space Space;
641  typedef typename TDomain::Size Size;
642  typedef typename TDomain::Integer IntergerDom;
643  typedef typename Space::Dimension Dimension;
644  typedef typename Space::Point Point;
645 
657  BasicDomainSubSampler(const TDomain &aSourceDomain, const std::vector<TValue> &aGridSize,
658  const Point &aGridShift): mySourceDomain(aSourceDomain),
659  myGridShift(aGridShift),
660  myGridSize(aGridSize)
661  {
662  Point domainUpperBound=aSourceDomain.upperBound();
663  Point domainLowerBound=aSourceDomain.lowerBound();
664 
665  for (Dimension dim=0; dim< Space::dimension; dim++){
666  domainLowerBound[dim] = static_cast<IntergerDom>(floor(NumberTraits<IntergerDom>::castToDouble(domainLowerBound[dim]) /
667  NumberTraits<TValue>::castToDouble( aGridSize[dim] )));
668  domainUpperBound[dim] = static_cast<IntergerDom>(floor(NumberTraits<IntergerDom>::castToDouble(domainUpperBound[dim]) /
669  NumberTraits<TValue>::castToDouble( aGridSize[dim] )));
670  }
671  myNewDomain = TDomain(domainLowerBound,
672  domainUpperBound);
673  Point upperGrid;
674  for (Dimension dim=0; dim < Space::dimension; dim++)
675  upperGrid[dim] = myGridSize[dim];
676  myGridSampleDomain = TDomain(Point::diagonal(0), upperGrid);
677  };
678 
679 
693  inline
694  Point operator()(const Point& aPoint) const
695  {
696  Point ptRes = Point::diagonal(0);
697  if(!myNewDomain.isInside(aPoint)){
698  trace.error() << " The point is not in the source domain: "<< aPoint << std::endl;
699  return ptRes;
700  }
701 
702  for (Dimension dim=0; dim< Space::dimension; dim++){
703  ptRes[dim] = static_cast<TInteger>(floor(NumberTraits<TInteger>::castToDouble(aPoint[dim])*
705  }
706  ptRes +=myGridShift;
707 
708  if(!mySourceDomain.isInside(ptRes)){
709  // we are looking for a point inside the domain
710  for(typename TDomain::ConstIterator it = myGridSampleDomain.begin();
711  it!= myGridSampleDomain.end(); it++){
712  if (mySourceDomain.isInside(ptRes+(*it)))
713  return ptRes+(*it);
714  }
715  }
716  return ptRes;
717  }
718 
725  inline
726  const TDomain & getSubSampledDomain(){
727  return myNewDomain;
728  }
729 
730  private:
731  TDomain mySourceDomain;
732  TDomain myNewDomain;
733  // used to search a point when the resulting point is outside the source domain.
736  std::vector<TValue> myGridSize;
737  };
738 
739 
757  template <typename TDomain>
759  {
760  public:
761  typedef typename TDomain::Space Space;
762  typedef typename TDomain::Size Size;
763  typedef typename Space::Dimension Dimension;
764  typedef typename Space::Point Point;
765 
778  FlipDomainAxis(const TDomain &aSourceDomain, const std::vector<Dimension> & axisFlipped): mySourceDomain(aSourceDomain),
779  myAxisFlipped(axisFlipped){
780  };
781 
782 
792  inline
793  Point operator()(const Point& aPoint) const
794  {
795  Point ptRes;
796  for (Dimension dim=0; dim< Space::dimension; dim++){
797  ptRes[dim] = aPoint[dim];
798  }
799  for(Dimension i = 0; i< myAxisFlipped.size(); i++){
800  ptRes[myAxisFlipped[i]] = mySourceDomain.upperBound()[myAxisFlipped[i]]-aPoint[myAxisFlipped[i]];
801  }
802  return ptRes;
803  }
804 
805  private:
806  TDomain mySourceDomain;
807  std::vector<Dimension> myAxisFlipped;
808  };
809 
810 
811  template <typename TRealVector, typename TVector>
813  {
814  BOOST_STATIC_ASSERT(( TRealVector::dimension == TVector::dimension ));
815  inline
816  TVector operator () ( const TRealVector & point ) const
817  {
818  TVector out;
819  for ( unsigned int i = 0; i < TVector::dimension; i++ )
820  out[i] = std::round ( point[i] );
821  return out;
822  }
823  };
824 
825  }//namespace functors
826 } // namespace dgtal
827 
828 
830 // Includes inline functions.
831 #include "DGtal/kernel/BasicPointFunctors.ih"
832 // //
834 
835 #endif // !defined BasicPointFunctors_h
836 #undef BasicPointFunctors_RECURSES
837 #endif // else defined(BasicPointFunctors_RECURSES)
Aim: This class encapsulates its parameter class so that to indicate to the user that the object/poin...
Definition: ConstAlias.h:187
double norm(const NormType type=L_2) const
static Dimension size()
Integer Component
Type for Vector elements.
Definition: PointVector.h:614
static Self diagonal(Component val=1)
TInteger Integer
Arithmetic ring induced by (+,-,*) and Integer numbers.
Definition: SpaceND.h:102
DGtal::Dimension Dimension
Copy of the type used for the dimension.
Definition: SpaceND.h:129
std::ostream & error()
std::ostream & warning()
Aim: Functor that subsamples an initial domain by given a grid size and a shift vector....
Point operator()(const Point &aPoint) const
BasicDomainSubSampler(const TDomain &aSourceDomain, const std::vector< TValue > &aGridSize, const Point &aGridShift)
Aim: Functor that flips the domain coordinate system from some selected axis. For instance,...
Point operator()(const Point &aPoint) const
FlipDomainAxis(const TDomain &aSourceDomain, const std::vector< Dimension > &axisFlipped)
std::vector< Dimension > myAxisFlipped
Aim: Functor that embeds a 2D point into a 3D space from two axis vectors and an origin point given i...
void shiftOriginPoint(const typename Space::RealPoint &shift)
Point2DEmbedderIn3D(const TDomain3D &aDomain3DImg, const Point &anOriginPoint, const Point &anUpperPointOnAxis1, const Point &anUpperPointOnAxis2, const Point &aDefautPoint=Point(0, 0, 0))
Point2DEmbedderIn3D(const TDomain3D &aDomain3DImg, const Point &anOriginPoint, const typename Space::RealPoint &aNormalVector, const typename Point::Component &aWidth, const Point &aDefautPoint=Point(0, 0, 0))
Point2DEmbedderIn3D(const TDomain3D &aDomain3DImg, const Point &anOriginPoint, const typename Space::RealPoint &aNormalVector, const typename Space::RealPoint &orientXaxisVector, const typename Point::Component &aWidth, const Point &aDefautPoint=Point(0, 0, 0))
Point operator()(const TPoint2D &aPoint, bool checkInsideDomain=true) const
Special Point Functor that adds one dimension to a 2D point and apply on it a rotation of angle alpha...
PointVector< 3, double > myCenter
Point operator()(const TPointDimMinus &aPoint) const
SliceRotator2D(const Dimension &dimAdded, const TDomain3D &aDomain3DImg, const Integer &sliceIndex, const Dimension &dimRotated, double rotationAngle)
SliceRotator2D(const Dimension &dimAdded, const TDomain3D &aDomain3DImg, const Integer &sliceIndex, const Dimension &dimRotated, const Point &ptCenter, double rotationAngle, const Point &defaultPoint)
SliceRotator2D(const Dimension &dimAdded, const TDomain3D &aDomain3DImg, const Integer &sliceIndex, const Dimension &dimRotated, double rotationAngle, const Point &defaultPoint)
SliceRotator2D(const Dimension &dimAdded, const TDomain3D &aDomain3DImg, const Integer &sliceIndex, const Dimension &dimRotated, const Point &ptCenter, double rotationAngle)
MyDigitalSurface::ConstIterator ConstIterator
DGtal is the top-level namespace which contains all DGtal functions and types.
DGtal::uint32_t Dimension
Definition: Common.h:136
Trace trace
Definition: Common.h:153
Aim: The traits class for all models of Cinteger.
Definition: NumberTraits.h:564
Aim: This concept represents a digital domain, i.e. a non mutable subset of points of the given digit...
Definition: CDomain.h:130
Aim: Defines a predicate on a point.
Aim: defines the concept of quantity in DGtal.
Definition: CQuantity.h:93
Create a point functor from a point predicate and a domain.
Value operator()(const Point &aPoint) const
operator ()
BOOST_CONCEPT_ASSERT((concepts::CQuantity< Value >))
PointFunctorFromPointPredicateAndDomain(ConstAlias< PointPredicate > aPtrPredicate, ConstAlias< Domain > aDomain, const Value aTrueValue, const Value aFalseValue)
Constructor.
PointFunctorFromPointPredicateAndDomain(const PointFunctorFromPointPredicateAndDomain &other)
BOOST_CONCEPT_ASSERT((concepts::CPointPredicate< PointPredicate >))
PointFunctorFromPointPredicateAndDomain & operator=(const PointFunctorFromPointPredicateAndDomain &other)
Aim: Functor that maps a point P of dimension i to a point Q of dimension j. The member myDims is an ...
void initAddOneDim(const Dimension &newDim)
void init(const TIterator &itb, const TIterator &ite)
void initRemoveOneDim(const Dimension &dimRemoved)
Projector(const Integer &aDefaultInteger=NumberTraits< Integer >::zero())
Point operator()(const TInputPoint &aPoint) const
BOOST_STATIC_CONSTANT(Dimension, dimension=Space::dimension)
std::array< Dimension, dimension > myDims
TVector operator()(const TRealVector &point) const
BOOST_STATIC_ASSERT((TRealVector::dimension==TVector::dimension))
HalfEdgeDataStructure::Size Size
const Point aPoint(3, 4)
unsigned int dim(const Vector &z)