DGtal  1.0.0
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/kernel/BasicPointFunctors.h"
49 #include "DGtal/base/Common.h"
50 #include "DGtal/kernel/domains/CDomain.h"
51 #include "DGtal/kernel/CSpace.h"
53 
54 namespace DGtal
55 {
56 namespace functors
57 {
59 // Template class ForwardRigidTransformation3D
74 template < typename TSpace, typename TInputValue = typename TSpace::RealPoint, typename TOutputValue = typename TSpace::Point,
75  typename TFunctor = VectorRounding < TInputValue, TOutputValue > >
77 {
80  BOOST_STATIC_ASSERT(( TSpace::dimension == 3 ));
81  BOOST_STATIC_ASSERT(( TOutputValue::dimension == 3 ));
82  BOOST_STATIC_ASSERT(( TInputValue::dimension == 3 ));
83 
84  // ----------------------- Types ------------------------------
85 public:
86  typedef typename TSpace::RealPoint RealPoint;
87  typedef typename TSpace::RealVector RealVector;
88 
89  // ----------------------- Interface --------------------------------------
90 public:
98  ForwardRigidTransformation3D ( const RealPoint & aOrigin, const RealVector & aAxis,
99  const double & angle, const RealVector & aTranslate )
100  : axis(aAxis.getNormalized()), origin(aOrigin), trans(aTranslate)
101 
102 
103  {
104  if ( std::isnan( axis.norm() ) )
105  throw std::runtime_error ( "Axis of rotation can not be set as a vector of length 0!" );
106  t_sin = std::sin ( angle );
107  t_cos = std::cos ( angle );
108  }
109 
115  inline
116  TOutputValue operator()( const TInputValue & aInput ) const
117  {
118  RealPoint p;
119 
120  p[0] = ( ( ( ( t_cos + ( axis[0] * axis[0] ) * ( 1. - t_cos ) ) * ( aInput[0] - origin[0] ) )
121  + ( ( axis[0] * axis[1] * ( 1. - t_cos ) - axis[2] * t_sin ) * ( aInput[1] - origin[1] ) )
122  + ( ( axis[1] * t_sin + axis[0] * axis[2] * ( 1. - t_cos ) ) * ( aInput[2] - origin[2] ) ) ) + trans[0] ) + origin[0];
123 
124  p[1] = ( ( ( ( axis[2] * t_sin + axis[0] * axis[1] * ( 1. - t_cos ) ) * ( aInput[0] - origin[0] ) )
125  + ( ( t_cos + ( axis[1] * axis[1] ) * ( 1. - t_cos ) ) * ( aInput[1] - origin[1] ) )
126  + ( ( -axis[0] * t_sin + axis[1] * axis[2] * ( 1. - t_cos ) ) * ( aInput[2] - origin[2] ) ) ) + trans[1] ) + origin[1];
127 
128  p[2] = ( ( ( ( -axis[1] * t_sin + axis[0] * axis[2] * ( 1. - t_cos ) ) * ( aInput[0] - origin[0] ) )
129  + ( ( axis[0] * t_sin + axis[1] * axis[2] * ( 1. - t_cos ) ) * ( aInput[1] - origin[1] ) )
130  + ( ( t_cos + ( axis[2] * axis[2] ) * ( 1. - t_cos ) ) * ( aInput[2] - origin[2] ) ) ) + trans[2] ) + origin[2];
131 
132  return functor ( p );
133  }
134 
135  // ------------------------- Protected Datas ------------------------------
136 protected:
139  double t_sin;
140  double t_cos;
142  TFunctor functor;
143 };
144 
145 
147 // Template class BackwardRigidTransformation3D
162 template < typename TSpace, typename TInputValue = typename TSpace::RealPoint, typename TOutputValue = typename TSpace::Point,
165 {
168  BOOST_STATIC_ASSERT(( TSpace::dimension == 3 ));
169  BOOST_STATIC_ASSERT(( TOutputValue::dimension == 3 ));
170  BOOST_STATIC_ASSERT(( TInputValue::dimension == 3 ));
171 
172  // ----------------------- Types ------------------------------
173 public:
174  typedef typename TSpace::RealPoint RealPoint;
175  typedef typename TSpace::RealVector RealVector;
176 
177  // ----------------------- Interface --------------------------------------
178 public:
186  BackwardRigidTransformation3D ( const RealPoint & aOrigin, const RealVector & aAxis,
187  const double & angle, const RealVector & aTranslate )
188  : axis(aAxis.getNormalized()), origin(aOrigin), trans(aTranslate)
189  {
190  if ( std::isnan( axis.norm() ) )
191  throw std::runtime_error ( "Axis of rotation can not be set as a vector of length 0!" );
192 
193  t_sin = std::sin ( angle );
194  t_cos = std::cos ( angle );
195  }
196 
202  inline
203  TOutputValue operator()( const TInputValue & aInput ) const
204  {
205  RealPoint p;
206 
207  p[0] = ( ( ( ( t_cos + ( axis[0] * axis[0] ) * ( 1. - t_cos ) ) * ( aInput[0] - trans[0] - origin[0] ) )
208  + ( ( axis[2] * t_sin + axis[0] * axis[1] * ( 1. - t_cos ) ) * ( aInput[1] - trans[1] - origin[1] ) )
209  + ( ( -axis[1] * t_sin + axis[0] * axis[2] * ( 1. - t_cos ) ) * ( aInput[2] - trans[2] - origin[2] ) ) ) ) + origin[0];
210 
211  p[1] = ( ( ( ( axis[0] * axis[1] * ( 1. - t_cos ) - axis[2] * t_sin ) * ( aInput[0] - trans[0] - origin[0] ) )
212  + ( ( t_cos + ( axis[1] * axis[1] ) * ( 1. - t_cos ) ) * ( aInput[1] - trans[1] - origin[1] ) )
213  + ( ( axis[0] * t_sin + axis[1] * axis[2] * ( 1. - t_cos ) ) * ( aInput[2] - trans[2] - origin[2] ) ) ) ) + origin[1];
214 
215  p[2] = ( ( ( ( axis[1] * t_sin + axis[0] * axis[2] * ( 1. - t_cos ) ) * ( aInput[0] - trans[0] - origin[0] ) )
216  + ( ( -axis[0] * t_sin + axis[1] * axis[2] * ( 1. - t_cos ) ) * ( aInput[1] - trans[1] - origin[1] ) )
217  + ( ( t_cos + ( axis[2] * axis[2] ) * ( 1. - t_cos ) ) * ( aInput[2] - trans[2] - origin[2] ) ) ) ) + origin[2];
218  return functor ( p );
219  }
220 
221  // ------------------------- Protected Datas ------------------------------
222 private:
225  double t_sin;
226  double t_cos;
228  TFunctor functor;
229 };
230 
232 // Template class DomainRigidTransformation3D
242 template <typename TDomain, typename TRigidTransformFunctor >
244 {
246  BOOST_STATIC_ASSERT(( TDomain::dimension == 3 ));
248 
249  // ----------------------- Types ------------------------------
250 public:
251  typedef std::pair < typename TDomain::Space::Point, typename TDomain::Space::Point > Bounds;
252 
253  // ----------------------- Interface --------------------------------------
254 public:
259  DomainRigidTransformation3D ( const TRigidTransformFunctor & aRigidFunctor ) : transform ( aRigidFunctor ) {}
260 
266  inline
267  Bounds operator()( const TDomain & aInput ) const
268  {
269  typedef typename TDomain::Point Point;
270 
271  Point points[8];
272  points[0] = transform ( aInput.lowerBound() );
273  points[1] = transform ( aInput.upperBound() );
274  points[2] = transform ( Point ( aInput.upperBound()[0], aInput.lowerBound()[1], aInput.lowerBound()[2] ) );
275  points[3] = transform ( Point ( aInput.lowerBound()[0], aInput.upperBound()[1], aInput.upperBound()[2] ) );
276  points[4] = transform ( Point ( aInput.upperBound()[0], aInput.lowerBound()[1], aInput.upperBound()[2] ) );
277  points[5] = transform ( Point ( aInput.lowerBound()[0], aInput.upperBound()[1], aInput.lowerBound()[2] ) );
278  points[6] = transform ( Point ( aInput.lowerBound()[0], aInput.lowerBound()[1], aInput.upperBound()[2] ) );
279  points[7] = transform ( Point ( aInput.upperBound()[0], aInput.upperBound()[1], aInput.lowerBound()[2] ) );
280 
281  Point t_min ( INT_MAX, INT_MAX, INT_MAX ), t_max ( INT_MIN, INT_MIN, INT_MIN );
282  for ( int i = 0; i < 8; i++ )
283  {
284  if ( points[i][0] < t_min[0] )
285  t_min[0] = points[i][0];
286  if ( points[i][1] < t_min[1] )
287  t_min[1] = points[i][1];
288  if ( points[i][2] < t_min[2] )
289  t_min[2] = points[i][2];
290 
291  if ( points[i][0] > t_max[0] )
292  t_max[0] = points[i][0];
293  if ( points[i][1] > t_max[1] )
294  t_max[1] = points[i][1];
295  if ( points[i][2] > t_max[2] )
296  t_max[2] = points[i][2];
297  }
298  Bounds bounds;
299  bounds.first = t_min;
300  bounds.second = t_max;
301  return bounds;
302  }
303 
304  // ------------------------- Protected Datas ------------------------------
305 protected:
306  const TRigidTransformFunctor & transform;
307 };
308 } // namespace DGtal::functors
309 } // namespace DGtal
310 
311 
312 #endif // !defined RigidTransformation3D_h
313 
314 #undef RigidTransformation3D_RECURSES
315 #endif // else defined(RigidTransformation3D_RECURSES)
Aim: implements forward rigid transformation of point in 3D integer space around any arbitrary axis....
BOOST_CONCEPT_ASSERT((concepts::CSpace< TSpace >))
Checking concepts.
Bounds operator()(const TDomain &aInput) const
Z3i::RealVector RealVector
DomainRigidTransformation3D(const TRigidTransformFunctor &aRigidFunctor)
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
TOutputValue operator()(const TInputValue &aInput) const
ForwardRigidTransformation3D(const RealPoint &aOrigin, const RealVector &aAxis, const double &angle, const RealVector &aTranslate)
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
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.
BackwardRigidTransformation3D(const RealPoint &aOrigin, const RealVector &aAxis, const double &angle, const RealVector &aTranslate)
TOutputValue operator()(const TInputValue &aInput) const