DGtal  1.2.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)
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 & 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 = anOriginPoint + Point(uDir1*anWidth/2) + Point(uDir2*anWidth/2);
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 TDomain::Integer IntergerDom;
596  typedef typename Space::Dimension Dimension;
597  typedef typename Space::Point Point;
598 
610  BasicDomainSubSampler(const TDomain &aSourceDomain, const std::vector<TValue> &aGridSize,
611  const Point &aGridShift): mySourceDomain(aSourceDomain),
612  myGridShift(aGridShift),
613  myGridSize(aGridSize)
614  {
615  Point domainUpperBound=aSourceDomain.upperBound();
616  Point domainLowerBound=aSourceDomain.lowerBound();
617 
618  for (Dimension dim=0; dim< Space::dimension; dim++){
619  domainLowerBound[dim] = static_cast<IntergerDom>(floor(NumberTraits<IntergerDom>::castToDouble(domainLowerBound[dim]) /
620  NumberTraits<TValue>::castToDouble( aGridSize[dim] )));
621  domainUpperBound[dim] = static_cast<IntergerDom>(floor(NumberTraits<IntergerDom>::castToDouble(domainUpperBound[dim]) /
622  NumberTraits<TValue>::castToDouble( aGridSize[dim] )));
623  }
624  myNewDomain = TDomain(domainLowerBound,
625  domainUpperBound);
626  Point upperGrid;
627  for (Dimension dim=0; dim < Space::dimension; dim++)
628  upperGrid[dim] = myGridSize[dim];
629  myGridSampleDomain = TDomain(Point::diagonal(0), upperGrid);
630  };
631 
632 
646  inline
647  Point operator()(const Point& aPoint) const
648  {
649  Point ptRes = Point::diagonal(0);
650  if(!myNewDomain.isInside(aPoint)){
651  trace.error() << " The point is not in the source domain: "<< aPoint << std::endl;
652  return ptRes;
653  }
654 
655  for (Dimension dim=0; dim< Space::dimension; dim++){
656  ptRes[dim] = static_cast<TInteger>(floor(NumberTraits<TInteger>::castToDouble(aPoint[dim])*
658  }
659  ptRes +=myGridShift;
660 
661  if(!mySourceDomain.isInside(ptRes)){
662  // we are looking for a point inside the domain
663  for(typename TDomain::ConstIterator it = myGridSampleDomain.begin();
664  it!= myGridSampleDomain.end(); it++){
665  if (mySourceDomain.isInside(ptRes+(*it)))
666  return ptRes+(*it);
667  }
668  }
669  return ptRes;
670  }
671 
678  inline
679  const TDomain & getSubSampledDomain(){
680  return myNewDomain;
681  }
682 
683  private:
684  TDomain mySourceDomain;
685  TDomain myNewDomain;
686  // used to search a point when the resulting point is outside the source domain.
689  std::vector<TValue> myGridSize;
690  };
691 
692 
710  template <typename TDomain>
712  {
713  public:
714  typedef typename TDomain::Space Space;
715  typedef typename TDomain::Size Size;
716  typedef typename Space::Dimension Dimension;
717  typedef typename Space::Point Point;
718 
731  FlipDomainAxis(const TDomain &aSourceDomain, const std::vector<Size> & axisFlipped): mySourceDomain(aSourceDomain),
732  myAxisFlipped(axisFlipped){
733  };
734 
735 
745  inline
746  Point operator()(const Point& aPoint) const
747  {
748  Point ptRes;
749  for (Dimension dim=0; dim< Space::dimension; dim++){
750  ptRes[dim] = aPoint[dim];
751  }
752  for(Dimension i = 0; i< myAxisFlipped.size(); i++){
753  ptRes[myAxisFlipped[i]] = mySourceDomain.upperBound()[myAxisFlipped[i]]-aPoint[myAxisFlipped[i]];
754  }
755  return ptRes;
756  }
757 
758  private:
759  TDomain mySourceDomain;
760  std::vector<Size> myAxisFlipped;
761  };
762 
763 
764  template <typename TRealVector, typename TVector>
766  {
767  BOOST_STATIC_ASSERT(( TRealVector::dimension == TVector::dimension ));
768  inline
769  TVector operator () ( const TRealVector & point ) const
770  {
771  TVector out;
772  for ( unsigned int i = 0; i < TVector::dimension; i++ )
773  out[i] = std::round ( point[i] );
774  return out;
775  }
776  };
777 
778  }//namespace functors
779 } // namespace dgtal
780 
781 
783 // Includes inline functions.
784 #include "DGtal/kernel/BasicPointFunctors.ih"
785 // //
787 
788 #endif // !defined BasicPointFunctors_h
789 #undef BasicPointFunctors_RECURSES
790 #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< Size > &axisFlipped)
Aim: Functor that embeds a 2D point into a 3D space from two axis vectors and an origin point given i...
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 &anNormalVector, const typename Point::Component &anWidth, 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:137
Trace trace
Definition: Common.h:154
Aim: The traits class for all models of Cinteger.
Definition: NumberTraits.h:533
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)