DGtal  0.9.2
RigidTransformation3D.h
1 
17 #pragma once
18 
31 #if defined(RigidTransformation3D_RECURSES)
32 #error Recursive header files inclusion detected in RigidTransformation3D.h
33 #else // defined(RigidTransformation3D_RECURSES)
34 
35 #define RigidTransformation3D_RECURSES
36 
37 #if !defined RigidTransformation3D_h
38 
39 #define RigidTransformation3D_h
40 
42 // Inclusions
43 #include <iostream>
44 #include <cmath>
45 #include <climits>
46 #include <utility>
47 #include <exception>
48 #include "DGtal/base/Common.h"
49 #include <DGtal/kernel/domains/CDomain.h>
51 
52 namespace DGtal
53 {
54 namespace functors
55 {
57 // Template class ForwardRigidTransformation3D
69 template <typename TSpace>
70 class ForwardRigidTransformation3D : std::unary_function <typename TSpace::Point, typename TSpace::Point>
71 {
74  BOOST_STATIC_ASSERT(( TSpace::dimension == 3 ));
75 
76  // ----------------------- Types ------------------------------
77 public:
78  typedef typename TSpace::Point Point;
79  typedef typename TSpace::RealPoint RealPoint;
80  typedef typename TSpace::RealVector RealVector;
81 
82  // ----------------------- Interface --------------------------------------
83 public:
91  ForwardRigidTransformation3D ( const RealPoint & aOrigin, const RealVector & aAxis,
92  const double & angle, const RealVector & aTranslate )
93  : axis(aAxis.getNormalized()), origin(aOrigin), trans(aTranslate)
94 
95 
96  {
97  if ( std::isnan( axis.norm() ) )
98  throw std::runtime_error ( "Axis of rotation can not be set as a vector of length 0!" );
99  t_sin = std::sin ( angle );
100  t_cos = std::cos ( angle );
101  }
102 
108  inline
109  Point operator()( const Point& aInput ) const
110  {
111  Point p;
112 
113  p[0] = std::floor ( ( ( ( ( t_cos + ( axis[0] * axis[0] ) * ( 1. - t_cos ) ) * ( aInput[0] - origin[0] ) )
114  + ( ( axis[0] * axis[1] * ( 1. - t_cos ) - axis[2] * t_sin ) * ( aInput[1] - origin[1] ) )
115  + ( ( axis[1] * t_sin + axis[0] * axis[2] * ( 1. - t_cos ) ) * ( aInput[2] - origin[2] ) ) ) + trans[0] ) + origin[0] + 0.5 );
116 
117  p[1] = std::floor ( ( ( ( ( axis[2] * t_sin + axis[0] * axis[1] * ( 1. - t_cos ) ) * ( aInput[0] - origin[0] ) )
118  + ( ( t_cos + ( axis[1] * axis[1] ) * ( 1. - t_cos ) ) * ( aInput[1] - origin[1] ) )
119  + ( ( -axis[0] * t_sin + axis[1] * axis[2] * ( 1. - t_cos ) ) * ( aInput[2] - origin[2] ) ) ) + trans[1] ) + origin[1] + 0.5 );
120 
121  p[2] = std::floor ( ( ( ( ( -axis[1] * t_sin + axis[0] * axis[2] * ( 1. - t_cos ) ) * ( aInput[0] - origin[0] ) )
122  + ( ( axis[0] * t_sin + axis[1] * axis[2] * ( 1. - t_cos ) ) * ( aInput[1] - origin[1] ) )
123  + ( ( t_cos + ( axis[2] * axis[2] ) * ( 1. - t_cos ) ) * ( aInput[2] - origin[2] ) ) ) + trans[2] ) + origin[2] + 0.5 );
124 
125  return p;
126  }
127 
128  // ------------------------- Protected Datas ------------------------------
129 protected:
130  RealVector axis;
131  RealPoint origin;
132  double t_sin;
133  double t_cos;
134  RealVector trans;
135 };
136 
138 // Template class BackwardRigidTransformation3D
150 template <typename TSpace>
151 class BackwardRigidTransformation3D : std::unary_function <typename TSpace::Point, typename TSpace::Point>
152 {
155  BOOST_STATIC_ASSERT(( TSpace::dimension == 3 ));
156 
157  // ----------------------- Types ------------------------------
158 public:
159  typedef typename TSpace::Point Point;
160  typedef typename TSpace::RealPoint RealPoint;
161  typedef typename TSpace::RealVector RealVector;
162 
163  // ----------------------- Interface --------------------------------------
164 public:
172  BackwardRigidTransformation3D ( const RealPoint & aOrigin, const RealVector & aAxis,
173  const double & angle, const RealVector & aTranslate )
174  : axis(aAxis.getNormalized()), origin(aOrigin), trans(aTranslate)
175  {
176  if ( std::isnan( axis.norm() ) )
177  throw std::runtime_error ( "Axis of rotation can not be set as a vector of length 0!" );
178 
179  t_sin = std::sin ( angle );
180  t_cos = std::cos ( angle );
181  }
182 
188  inline
189  Point operator()( const Point& aInput ) const
190  {
191  Point p;
192 
193  p[0] = std::floor ( ( ( ( ( t_cos + ( axis[0] * axis[0] ) * ( 1. - t_cos ) ) * ( aInput[0] - trans[0] - origin[0] ) )
194  + ( ( axis[2] * t_sin + axis[0] * axis[1] * ( 1. - t_cos ) ) * ( aInput[1] - trans[1] - origin[1] ) )
195  + ( ( -axis[1] * t_sin + axis[0] * axis[2] * ( 1. - t_cos ) ) * ( aInput[2] - trans[2] - origin[2] ) ) ) ) + origin[0] + 0.5 );
196 
197  p[1] = std::floor ( ( ( ( ( axis[0] * axis[1] * ( 1. - t_cos ) - axis[2] * t_sin ) * ( aInput[0] - trans[0] - origin[0] ) )
198  + ( ( t_cos + ( axis[1] * axis[1] ) * ( 1. - t_cos ) ) * ( aInput[1] - trans[1] - origin[1] ) )
199  + ( ( axis[0] * t_sin + axis[1] * axis[2] * ( 1. - t_cos ) ) * ( aInput[2] - trans[2] - origin[2] ) ) ) ) + origin[1] + 0.5 );
200 
201  p[2] = std::floor ( ( ( ( ( axis[1] * t_sin + axis[0] * axis[2] * ( 1. - t_cos ) ) * ( aInput[0] - trans[0] - origin[0] ) )
202  + ( ( -axis[0] * t_sin + axis[1] * axis[2] * ( 1. - t_cos ) ) * ( aInput[1] - trans[1] - origin[1] ) )
203  + ( ( t_cos + ( axis[2] * axis[2] ) * ( 1. - t_cos ) ) * ( aInput[2] - trans[2] - origin[2] ) ) ) ) + origin[2] + 0.5 );
204  return p;
205  }
206 
207  // ------------------------- Protected Datas ------------------------------
208 private:
209  RealVector axis;
210  RealPoint origin;
211  double t_sin;
212  double t_cos;
213  RealVector trans;
214 };
215 
217 // Template class DomainRigidTransformation3D
227 template <typename TDomain, typename TRigidTransformFunctor >
229  std::unary_function < std::pair < typename TDomain::Point, typename TDomain::Point >, TDomain>
230 {
232  BOOST_STATIC_ASSERT(( TDomain::dimension == 3 ));
234 
235  // ----------------------- Types ------------------------------
236 public:
237  typedef std::pair < typename TDomain::Space::Point, typename TDomain::Space::Point > Bounds;
238 
239  // ----------------------- Interface --------------------------------------
240 public:
245  DomainRigidTransformation3D ( const TRigidTransformFunctor & aRigidFunctor ) : transform ( aRigidFunctor ) {}
246 
252  inline
253  Bounds operator()( const TDomain & aInput ) const
254  {
255  typedef typename TDomain::Point Point;
256 
257  Point points[8];
258  points[0] = transform ( aInput.lowerBound() );
259  points[1] = transform ( aInput.upperBound() );
260  points[2] = transform ( Point ( aInput.upperBound()[0], aInput.lowerBound()[1], aInput.lowerBound()[2] ) );
261  points[3] = transform ( Point ( aInput.lowerBound()[0], aInput.upperBound()[1], aInput.upperBound()[2] ) );
262  points[4] = transform ( Point ( aInput.upperBound()[0], aInput.lowerBound()[1], aInput.upperBound()[2] ) );
263  points[5] = transform ( Point ( aInput.lowerBound()[0], aInput.upperBound()[1], aInput.lowerBound()[2] ) );
264  points[6] = transform ( Point ( aInput.lowerBound()[0], aInput.lowerBound()[1], aInput.upperBound()[2] ) );
265  points[7] = transform ( Point ( aInput.upperBound()[0], aInput.upperBound()[1], aInput.lowerBound()[2] ) );
266 
267  typename Point::Component cmax = std::numeric_limits<typename Point::Component>::max();
268  typename Point::Component cmin = std::numeric_limits<typename Point::Component>::min();
269  Point t_min ( cmax, cmax, cmax ), t_max ( cmin, cmin, cmin );
270  for ( int i = 0; i < 8; i++ )
271  {
272  if ( points[i][0] < t_min[0] )
273  t_min[0] = points[i][0];
274  if ( points[i][1] < t_min[1] )
275  t_min[1] = points[i][1];
276  if ( points[i][2] < t_min[2] )
277  t_min[2] = points[i][2];
278 
279  if ( points[i][0] > t_max[0] )
280  t_max[0] = points[i][0];
281  if ( points[i][1] > t_max[1] )
282  t_max[1] = points[i][1];
283  if ( points[i][2] > t_max[2] )
284  t_max[2] = points[i][2];
285  }
286  Bounds bounds;
287  bounds.first = t_min;
288  bounds.second = t_max;
289  return bounds;
290  }
291 
292  // ------------------------- Protected Datas ------------------------------
293 protected:
294  const TRigidTransformFunctor & transform;
295 };
296 } // namespace DGtal::functors
297 } // namespace DGtal
298 
299 
300 #endif // !defined RigidTransformation3D_h
301 
302 #undef RigidTransformation3D_RECURSES
303 #endif // else defined(RigidTransformation3D_RECURSES)
Aim: implements forward rigid transformation of point in 3D integer space around any arbitrary axis...
DomainRigidTransformation3D(const TRigidTransformFunctor &aRigidFunctor)
ForwardRigidTransformation3D(const RealPoint &aOrigin, const RealVector &aAxis, const double &angle, const RealVector &aTranslate)
Aim: implements backward rigid transformation of point in 3D integer space around any arbitrary axis...
Aim: This concept represents a digital domain, i.e. a non mutable subset of points of the given digit...
Definition: CDomain.h:129
std::pair< typename TDomain::Space::Point, typename TDomain::Space::Point > Bounds
Aim: Defines the concept describing a digital space, ie a cartesian product of integer lines...
Definition: CSpace.h:105
Bounds operator()(const TDomain &aInput) const
DGtal is the top-level namespace which contains all DGtal functions and types.
BOOST_STATIC_ASSERT((TDomain::dimension==3))
Checking concepts.
Aim: implements bounds of transformed domain.
BOOST_CONCEPT_ASSERT((concepts::CDomain< TDomain >))
BOOST_CONCEPT_ASSERT((concepts::CSpace< TSpace >))
Checking concepts.
Point operator()(const Point &aInput) const
BOOST_CONCEPT_ASSERT((concepts::CSpace< TSpace >))
Checking concepts.
BackwardRigidTransformation3D(const RealPoint &aOrigin, const RealVector &aAxis, const double &angle, const RealVector &aTranslate)