DGtal  0.9.4.1
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>
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:
132  double t_sin;
133  double t_cos;
135 };
136 
138 // Template class BackwardRigidTransformation3D
150 template <typename TSpace>
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:
211  double t_sin;
212  double t_cos;
214 };
215 
217 // Template class DomainRigidTransformation3D
227 template <typename TDomain, typename TRigidTransformFunctor >
229 {
231  BOOST_STATIC_ASSERT(( TDomain::dimension == 3 ));
233 
234  // ----------------------- Types ------------------------------
235 public:
236  typedef std::pair < typename TDomain::Space::Point, typename TDomain::Space::Point > Bounds;
237 
238  // ----------------------- Interface --------------------------------------
239 public:
244  DomainRigidTransformation3D ( const TRigidTransformFunctor & aRigidFunctor ) : transform ( aRigidFunctor ) {}
245 
251  inline
252  Bounds operator()( const TDomain & aInput ) const
253  {
254  typedef typename TDomain::Point Point;
255 
256  Point points[8];
257  points[0] = transform ( aInput.lowerBound() );
258  points[1] = transform ( aInput.upperBound() );
259  points[2] = transform ( Point ( aInput.upperBound()[0], aInput.lowerBound()[1], aInput.lowerBound()[2] ) );
260  points[3] = transform ( Point ( aInput.lowerBound()[0], aInput.upperBound()[1], aInput.upperBound()[2] ) );
261  points[4] = transform ( Point ( aInput.upperBound()[0], aInput.lowerBound()[1], aInput.upperBound()[2] ) );
262  points[5] = transform ( Point ( aInput.lowerBound()[0], aInput.upperBound()[1], aInput.lowerBound()[2] ) );
263  points[6] = transform ( Point ( aInput.lowerBound()[0], aInput.lowerBound()[1], aInput.upperBound()[2] ) );
264  points[7] = transform ( Point ( aInput.upperBound()[0], aInput.upperBound()[1], aInput.lowerBound()[2] ) );
265 
266  typename Point::Component cmax = std::numeric_limits<typename Point::Component>::max();
267  typename Point::Component cmin = std::numeric_limits<typename Point::Component>::min();
268  Point t_min ( cmax, cmax, cmax ), t_max ( cmin, cmin, cmin );
269  for ( int i = 0; i < 8; i++ )
270  {
271  if ( points[i][0] < t_min[0] )
272  t_min[0] = points[i][0];
273  if ( points[i][1] < t_min[1] )
274  t_min[1] = points[i][1];
275  if ( points[i][2] < t_min[2] )
276  t_min[2] = points[i][2];
277 
278  if ( points[i][0] > t_max[0] )
279  t_max[0] = points[i][0];
280  if ( points[i][1] > t_max[1] )
281  t_max[1] = points[i][1];
282  if ( points[i][2] > t_max[2] )
283  t_max[2] = points[i][2];
284  }
285  Bounds bounds;
286  bounds.first = t_min;
287  bounds.second = t_max;
288  return bounds;
289  }
290 
291  // ------------------------- Protected Datas ------------------------------
292 protected:
293  const TRigidTransformFunctor & transform;
294 };
295 } // namespace DGtal::functors
296 } // namespace DGtal
297 
298 
299 #endif // !defined RigidTransformation3D_h
300 
301 #undef RigidTransformation3D_RECURSES
302 #endif // else defined(RigidTransformation3D_RECURSES)
Aim: implements forward rigid transformation of point in 3D integer space around any arbitrary axis...
Bounds operator()(const TDomain &aInput) const
DomainRigidTransformation3D(const TRigidTransformFunctor &aRigidFunctor)
ForwardRigidTransformation3D(const RealPoint &aOrigin, const RealVector &aAxis, const double &angle, const RealVector &aTranslate)
PointVector< 3, double > RealPoint
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
DGtal is the top-level namespace which contains all DGtal functions and types.
MyPointD Point
Definition: testClone2.cpp:383
int max(int a, int b)
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.
BOOST_CONCEPT_ASSERT((concepts::CSpace< TSpace >))
Checking concepts.
BackwardRigidTransformation3D(const RealPoint &aOrigin, const RealVector &aAxis, const double &angle, const RealVector &aTranslate)