DGtal 2.1.0
Loading...
Searching...
No Matches
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
60namespace DGtal
61{
62namespace functors
63 {
65 // template class Projector
105 template <typename S = SpaceND< 2, DGtal::Z2i::Integer > >
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;
219 SliceRotator2D( const Dimension &dimAdded, const TDomain3D &aDomain3DImg,
220 const Integer &sliceIndex, const Dimension &dimRotated,
221 double rotationAngle, bool keepInside=true):
222 myPosDimAdded(dimAdded), mySliceIndex(sliceIndex), myDomain(aDomain3DImg),
223 myDimRotated(dimRotated), myRotationAngle(rotationAngle), myDefaultPoint (aDomain3DImg.lowerBound()), myKeepInsideDom(keepInside)
224 {
225 myCenter[0] = aDomain3DImg.lowerBound()[0]+((aDomain3DImg.upperBound())[0]-(aDomain3DImg.lowerBound())[0])/2.0;
226 myCenter[1] = aDomain3DImg.lowerBound()[1]+((aDomain3DImg.upperBound())[1]-(aDomain3DImg.lowerBound())[1])/2.0;
227 myCenter[2] = aDomain3DImg.lowerBound()[2]+((aDomain3DImg.upperBound())[2]-(aDomain3DImg.lowerBound())[2])/2.0;
228 myCenter[dimAdded]=sliceIndex;
229 };
230
242 SliceRotator2D( const Dimension &dimAdded, const TDomain3D &aDomain3DImg,
243 const Integer &sliceIndex, const Dimension &dimRotated,
244 double rotationAngle, const Point &defaultPoint, bool keepInside=true):
245 myPosDimAdded(dimAdded), mySliceIndex(sliceIndex), myDomain(aDomain3DImg),
246 myDimRotated(dimRotated), myRotationAngle(rotationAngle), myDefaultPoint (defaultPoint), myKeepInsideDom(keepInside)
247 {
248 myCenter[0] = aDomain3DImg.lowerBound()[0]+((aDomain3DImg.upperBound())[0]-(aDomain3DImg.lowerBound())[0])/2.0;
249 myCenter[1] = aDomain3DImg.lowerBound()[1]+((aDomain3DImg.upperBound())[1]-(aDomain3DImg.lowerBound())[1])/2.0;
250 myCenter[2] = aDomain3DImg.lowerBound()[2]+((aDomain3DImg.upperBound())[2]-(aDomain3DImg.lowerBound())[2])/2.0;
251 myCenter[dimAdded]=sliceIndex;
252 };
253
266 SliceRotator2D( const Dimension &dimAdded, const TDomain3D &aDomain3DImg, const Integer &sliceIndex,
267 const Dimension &dimRotated, const Point &ptCenter, double rotationAngle, const Point &defaultPoint,
268 bool keepInside=true):
269 myPosDimAdded(dimAdded), mySliceIndex(sliceIndex), myDomain(aDomain3DImg),
270 myDimRotated(dimRotated), myRotationAngle(rotationAngle), myCenter(ptCenter), myDefaultPoint (defaultPoint), myKeepInsideDom(keepInside)
271 {
272 };
273
286 SliceRotator2D( const Dimension &dimAdded, const TDomain3D &aDomain3DImg, const Integer &sliceIndex,
287 const Dimension &dimRotated, const Point &ptCenter, double rotationAngle, bool keepInside=true):
288 myPosDimAdded(dimAdded), mySliceIndex(sliceIndex), myDomain(aDomain3DImg),
289 myDimRotated(dimRotated), myRotationAngle(rotationAngle), myCenter(ptCenter), myDefaultPoint (aDomain3DImg.lowerBound()),
290 myKeepInsideDom(keepInside)
291 {
292 };
293
300 template <typename TPointDimMinus>
301 inline
302 Point operator()(const TPointDimMinus& aPoint) const
303 {
304 Point pt;
305 Dimension pos=0;
306 std::vector<Dimension> indexesRotate;
307 for( Dimension i=0; i<pt.size(); i++)
308 {
309 if(i!=myPosDimAdded)
310 {
311 pt[i]= aPoint[pos];
312 pos++;
313 }else
314 {
315 pt[i]=mySliceIndex;
316 }
317 }
318 for( Dimension i=0; i<pt.size(); i++)
319 {
320 if(i!=myDimRotated)
321 indexesRotate.push_back(i);
322 }
323 double d1 = pt[indexesRotate[0]] - myCenter[indexesRotate[0]];
324 double d2 = pt[indexesRotate[1]] - myCenter[indexesRotate[1]];
325
326 pt[indexesRotate[0]] = myCenter[indexesRotate[0]] + static_cast<Integer>(round(d1*cos(myRotationAngle)-d2*sin(myRotationAngle) ));
327 pt[indexesRotate[1]] = myCenter[indexesRotate[1]] + static_cast<Integer>(round(d1*sin(myRotationAngle)+d2*cos(myRotationAngle) ));
328
329 if(!myKeepInsideDom || myDomain.isInside(pt))
330 return pt;
331 else
332 return myDefaultPoint;
333 }
334 public:
335 // position of insertion of the new dimension
337 // the index of the slice associated to the new domain.
339 TDomain3D myDomain;
344 bool myKeepInsideDom = true;
345 };
346
347
378 template <typename TDomain3D, typename TInteger = DGtal::Z3i::Integer >
380 {
381 public:
382
384 typedef typename Space::Point Point;
385 typedef typename Space::Integer Integer;
386
397 Point2DEmbedderIn3D( const TDomain3D &aDomain3DImg,
398 const Point &anOriginPoint, const Point &anUpperPointOnAxis1,
399 const Point &anUpperPointOnAxis2,
400 const Point &aDefautPoint = Point(0,0,0)): myDomain(aDomain3DImg),
401 myOriginPointEmbeddedIn3D(anOriginPoint),
402 myDefaultPoint (aDefautPoint),
403 myFirstAxisEmbeddedDirection(Point(anUpperPointOnAxis1[0]-anOriginPoint[0],
404 anUpperPointOnAxis1[1]-anOriginPoint[1],
405 anUpperPointOnAxis1[2]-anOriginPoint[2])),
406 mySecondAxisEmbeddedDirection(Point(anUpperPointOnAxis2[0]-anOriginPoint[0],
407 anUpperPointOnAxis2[1]-anOriginPoint[1],
408 anUpperPointOnAxis2[2]-anOriginPoint[2]))
409
410
411 {
414 }
415
416
429 Point2DEmbedderIn3D( const TDomain3D &aDomain3DImg,
430 const Point &anOriginPoint, const typename Space::RealPoint & aNormalVector,
431 const typename Point::Component &aWidth,
432 const Point &aDefautPoint = Point(0,0,0)): myDomain(aDomain3DImg),
433 myDefaultPoint (aDefautPoint)
434 {
435 double d = -aNormalVector[0]*anOriginPoint[0] - aNormalVector[1]*anOriginPoint[1] - aNormalVector[2]*anOriginPoint[2];
436 typename Space::RealPoint pRefOrigin;
437 if(aNormalVector[0]!=0){
438 pRefOrigin [0]= -d/aNormalVector[0];
439 pRefOrigin [1]= 0.0;
440 pRefOrigin [2]= 0.0;
441 if(pRefOrigin==anOriginPoint){
442 pRefOrigin[1]=-1.0;
443 }
444 }else if (aNormalVector[1]!=0){
445 pRefOrigin [0]= 0.0;
446 pRefOrigin [1]= -d/aNormalVector[1];
447 pRefOrigin [2]= 0.0;
448 if(pRefOrigin==anOriginPoint){
449 pRefOrigin[0]=-1.0;
450 }
451 }else if (aNormalVector[2]!=0){
452 pRefOrigin [0]= 0.0;
453 pRefOrigin [1]= 0.0;
454 pRefOrigin [2]= -d/aNormalVector[2];
455 if(pRefOrigin==anOriginPoint){
456 pRefOrigin[0]=-1.0;
457 }
458 }
459 typename Space::RealPoint uDir1;
460 uDir1=(pRefOrigin-anOriginPoint)/((pRefOrigin-anOriginPoint).norm());
461 typename Space::RealPoint uDir2;
462 uDir2[0] = uDir1[1]*aNormalVector[2]-uDir1[2]*aNormalVector[1];
463 uDir2[1] = uDir1[2]*aNormalVector[0]-uDir1[0]*aNormalVector[2];
464 uDir2[2] = uDir1[0]*aNormalVector[1]-uDir1[1]*aNormalVector[0];
465
466 uDir2/=uDir2.norm();
467
468 myOriginPointEmbeddedIn3D = anOriginPoint + Point(uDir1*aWidth/2) + Point(uDir2*aWidth/2);
471 }
472
473
487 Point2DEmbedderIn3D( const TDomain3D &aDomain3DImg,
488 const Point &anOriginPoint, const typename Space::RealPoint & aNormalVector,
489 const typename Space::RealPoint & orientXaxisVector,
490 const typename Point::Component &aWidth,
491 const Point &aDefautPoint = Point(0,0,0)): myDomain(aDomain3DImg),
492 myDefaultPoint (aDefautPoint)
493 {
494
495 typename Space::RealPoint uDir1;
496 uDir1 = orientXaxisVector/orientXaxisVector.norm();
497 typename Space::RealPoint uDir2;
498 uDir2[0] = uDir1[1]*aNormalVector[2]-uDir1[2]*aNormalVector[1];
499 uDir2[1] = uDir1[2]*aNormalVector[0]-uDir1[0]*aNormalVector[2];
500 uDir2[2] = uDir1[0]*aNormalVector[1]-uDir1[1]*aNormalVector[0];
501 uDir2/=uDir2.norm();
502 myOriginPointEmbeddedIn3D = anOriginPoint + Point(-uDir1*aWidth/2) + Point(-uDir2*aWidth/2);
505 }
506
507
515 template <typename TPoint2D>
516 inline
517 Point operator()(const TPoint2D& aPoint, bool checkInsideDomain=true) const
518 {
519 Point pt ;
520 for( Dimension i=0; i<pt.size(); i++){
521
522 pt[i] = static_cast<Integer>(floor(NumberTraits<Integer>::castToDouble(aPoint[0])
524 pt[i] += static_cast<Integer>(floor(NumberTraits<Integer>::castToDouble(aPoint[1])
526 }
527
528 if(myDomain.isInside(pt)|| !checkInsideDomain)
529 {
530 return pt;
531 }
532 else
533 {
534#ifdef DEBUG_VERBOSE
535 trace.warning() << "Warning pt outside the 3D domain " << pt << std::endl;
536#endif
537 return myDefaultPoint;
538 }
539 }
540
541
547 inline
548 void shiftOriginPoint(const typename Space::RealPoint& shift)
549 {
550 for( Dimension i=0; i<myOriginPointEmbeddedIn3D.size(); i++){
552 }
553 }
554
555
556 private:
557 TDomain3D myDomain;
558
559 // Origin (or lower point) of the 2D image embedded in the 3D domain
561
563
564 // Point giving the direction of the embedded first axis of the 2D image.
566
567 // Point giving the direction of the embedded second axis of the 2D image.
569
570 };
571
572
576 template< typename TPointPredicate, typename TDomain, typename TValue=typename TDomain::Integer >
622
623
643 template <typename TDomain, typename TInteger = DGtal::int32_t, typename TValue = typename TDomain::Size >
645 {
646 public:
647 typedef typename TDomain::Space Space;
648 typedef typename TDomain::Size Size;
649 typedef typename TDomain::Integer IntergerDom;
650 typedef typename Space::Dimension Dimension;
651 typedef typename Space::Point Point;
652
664 BasicDomainSubSampler(const TDomain &aSourceDomain, const std::vector<TValue> &aGridSize,
665 const Point &aGridShift): mySourceDomain(aSourceDomain),
666 myGridShift(aGridShift),
667 myGridSize(aGridSize)
668 {
669 Point domainUpperBound=aSourceDomain.upperBound();
670 Point domainLowerBound=aSourceDomain.lowerBound();
671
672 for (Dimension dim=0; dim< Space::dimension; dim++){
673 domainLowerBound[dim] = static_cast<IntergerDom>(floor(NumberTraits<IntergerDom>::castToDouble(domainLowerBound[dim]) /
675 domainUpperBound[dim] = static_cast<IntergerDom>(floor(NumberTraits<IntergerDom>::castToDouble(domainUpperBound[dim]) /
677 }
678 myNewDomain = TDomain(domainLowerBound,
679 domainUpperBound);
680 Point upperGrid;
681 for (Dimension dim=0; dim < Space::dimension; dim++)
682 upperGrid[dim] = myGridSize[dim];
683 myGridSampleDomain = TDomain(Point::diagonal(0), upperGrid);
684 };
685
686
700 inline
702 {
703 Point ptRes = Point::diagonal(0);
704 if(!myNewDomain.isInside(aPoint)){
705 trace.error() << " The point is not in the source domain: "<< aPoint << std::endl;
706 return ptRes;
707 }
708
709 for (Dimension dim=0; dim< Space::dimension; dim++){
710 ptRes[dim] = static_cast<TInteger>(floor(NumberTraits<TInteger>::castToDouble(aPoint[dim])*
712 }
713 ptRes +=myGridShift;
714
715 if(!mySourceDomain.isInside(ptRes)){
716 // we are looking for a point inside the domain
717 for(typename TDomain::ConstIterator it = myGridSampleDomain.begin();
718 it!= myGridSampleDomain.end(); it++){
719 if (mySourceDomain.isInside(ptRes+(*it)))
720 return ptRes+(*it);
721 }
722 }
723 return ptRes;
724 }
725
732 inline
733 const TDomain & getSubSampledDomain(){
734 return myNewDomain;
735 }
736
737 private:
739 TDomain myNewDomain;
740 // used to search a point when the resulting point is outside the source domain.
743 std::vector<TValue> myGridSize;
744 };
745
746
764 template <typename TDomain>
766 {
767 public:
768 typedef typename TDomain::Space Space;
769 typedef typename TDomain::Size Size;
770 typedef typename Space::Dimension Dimension;
771 typedef typename Space::Point Point;
772
785 FlipDomainAxis(const TDomain &aSourceDomain, const std::vector<Dimension> & axisFlipped): mySourceDomain(aSourceDomain),
786 myAxisFlipped(axisFlipped){
787 };
788
789
799 inline
801 {
802 Point ptRes;
803 for (Dimension dim=0; dim< Space::dimension; dim++){
804 ptRes[dim] = aPoint[dim];
805 }
806 for(Dimension i = 0; i< myAxisFlipped.size(); i++){
807 ptRes[myAxisFlipped[i]] = mySourceDomain.upperBound()[myAxisFlipped[i]]-aPoint[myAxisFlipped[i]];
808 }
809 return ptRes;
810 }
811
812 private:
814 std::vector<Dimension> myAxisFlipped;
815 };
816
817
818 template <typename TRealVector, typename TVector>
820 {
821 BOOST_STATIC_ASSERT(( TRealVector::dimension == TVector::dimension ));
822 inline
823 TVector operator () ( const TRealVector & point ) const
824 {
825 TVector out;
826 for ( unsigned int i = 0; i < TVector::dimension; i++ )
827 out[i] = std::round ( point[i] );
828 return out;
829 }
830 };
831
832 }//namespace functors
833} // namespace dgtal
834
835
837// Includes inline functions.
838#include "DGtal/kernel/BasicPointFunctors.ih"
839// //
841
842#endif // !defined BasicPointFunctors_h
843#undef BasicPointFunctors_RECURSES
844#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.
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 & warning()
std::ostream & error()
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, const Point &ptCenter, double rotationAngle, bool keepInside=true)
SliceRotator2D(const Dimension &dimAdded, const TDomain3D &aDomain3DImg, const Integer &sliceIndex, const Dimension &dimRotated, double rotationAngle, const Point &defaultPoint, bool keepInside=true)
SliceRotator2D(const Dimension &dimAdded, const TDomain3D &aDomain3DImg, const Integer &sliceIndex, const Dimension &dimRotated, const Point &ptCenter, double rotationAngle, const Point &defaultPoint, bool keepInside=true)
SliceRotator2D(const Dimension &dimAdded, const TDomain3D &aDomain3DImg, const Integer &sliceIndex, const Dimension &dimRotated, double rotationAngle, bool keepInside=true)
DGtal is the top-level namespace which contains all DGtal functions and types.
DGtal::uint32_t Dimension
Definition Common.h:119
Trace trace
Aim: The traits class for all models of Cinteger.
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))
const Point aPoint(3, 4)