OpenWalnut  1.5.0dev
WGridTransformOrtho.h
1 //---------------------------------------------------------------------------
2 //
3 // Project: OpenWalnut ( http://www.openwalnut.org )
4 //
5 // Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
6 // For more information see http://www.openwalnut.org/copying
7 //
8 // This file is part of OpenWalnut.
9 //
10 // OpenWalnut is free software: you can redistribute it and/or modify
11 // it under the terms of the GNU Lesser General Public License as published by
12 // the Free Software Foundation, either version 3 of the License, or
13 // (at your option) any later version.
14 //
15 // OpenWalnut is distributed in the hope that it will be useful,
16 // but WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 // GNU Lesser General Public License for more details.
19 //
20 // You should have received a copy of the GNU Lesser General Public License
21 // along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
22 //
23 //---------------------------------------------------------------------------
24 
25 #ifndef WGRIDTRANSFORMORTHO_H
26 #define WGRIDTRANSFORMORTHO_H
27 
28 #include "../common/exceptions/WPreconditionNotMet.h"
29 #include "../common/math/WMatrix.h"
30 #include "../common/math/linearAlgebra/WPosition.h"
31 #include "../common/math/linearAlgebra/WMatrixFixed.h"
32 
33 /**
34  * Implements an orthogonal grid transformation.
35  *
36  * \class WGridTransformOrthoTemplate
37  */
38 template< typename T >
40 {
41  //! this (friend) is necessary to allow casting
42  template <class U>
44 public:
45  /**
46  * Convenience typedef for 3d vectors of the appropriate numerical type.
47  */
49 
50  /**
51  * Constructs an identity transform.
52  */
54 
55  /**
56  * Copy constructor.
57  * Copies the data from an WGridTransformOrthoTemplate object with arbitary numerical type.
58  *
59  * \param rhs A WGridTransformOrthoTemplate object, which mustn't have the same numerical type.
60  */
61  template< typename InputType >
62  WGridTransformOrthoTemplate( WGridTransformOrthoTemplate< InputType > const& rhs ); // NOLINT -- no explicit, this allows casts
63  /**
64  * Construct a transformation that scales the grid space.
65  * \param scaleX The scale in the x-direction.
66  * \param scaleY The scale in the y-direction.
67  * \param scaleZ The scale in the z-direction.
68  */
69  template< typename InputType >
70  WGridTransformOrthoTemplate( InputType scaleX, InputType scaleY, InputType scaleZ );
71 
72  /**
73  * Construct a transformation from a transformation matrix. The provided matrix
74  * represents the transformation from grid to world space.
75  * \param mat The matrix.
76  */
77  template< typename InputType >
78  WGridTransformOrthoTemplate( WMatrix< InputType > const& mat ); // NOLINT
79 
80  /**
81  * Destructor.
82  */
84 
85 
86  /**
87  * Assignment operator.
88  * Copies the data from an WGridTransformOrthoTemplate object with arbitary numerical type.
89  *
90  * \param rhs A WGridTransformOrthoTemplate object, which mustn't have the same numerical type.
91  *
92  * \return this
93  */
94  template< typename InputType >
96  /**
97  * Transforms a position from grid space to world space.
98  * \param position The position in grid space.
99  * \return The same position in world space.
100  */
101  Vector3Type positionToWorldSpace( Vector3Type const& position ) const;
102 
103  /**
104  * Transforms a position from world space to grid space.
105  * \param position The position in world space.
106  * \return The same position in grid space.
107  */
108  Vector3Type positionToGridSpace( Vector3Type const& position ) const;
109 
110  /**
111  * Transforms a direction from grid space to world space.
112  * \param direction The direction in grid space.
113  * \return The same direction in world space.
114  */
115  Vector3Type directionToWorldSpace( Vector3Type const& direction ) const;
116 
117  /**
118  * Transforms a direction from world space to grid space.
119  * \param direction The position in world space.
120  * \return The same position in grid space.
121  */
122  Vector3Type directionToGridSpace( Vector3Type const& direction ) const;
123 
124  /**
125  * Returns the distance between samples in x direction.
126  * \return The distance between samples in x direction.
127  */
128  T getOffsetX() const;
129 
130  /**
131  * Returns the distance between samples in y direction.
132  * \return The distance between samples in y direction.
133  */
134  T getOffsetY() const;
135 
136  /**
137  * Returns the distance between samples in z direction.
138  * \return The distance between samples in z direction.
139  */
140  T getOffsetZ() const;
141 
142  /**
143  * Returns the vector determining the direction of samples in x direction.
144  * Adding this vector to a grid position in world coordinates yields the position of the next sample
145  * along the grids (world coordinate) x-axis.
146  * \return The vector determining the direction of samples in x direction.
147  */
148  Vector3Type getDirectionX() const;
149 
150  /**
151  * Returns the vector determining the direction of samples in y direction.
152  * Adding this vector to a grid position in world coordinates yields the position of the next sample
153  * along the grids (world coordinate) y-axis.
154  * \return The vector determining the direction of samples in y direction.
155  */
156  Vector3Type getDirectionY() const;
157 
158  /**
159  * Returns the vector determining the direction of samples in z direction.
160  * Adding this vector to a grid position in world coordinates yields the position of the next sample
161  * along the grids (world coordinate) z-axis.
162  * \return The vector determining the direction of samples in z direction.
163  */
164  Vector3Type getDirectionZ() const;
165 
166  /**
167  * Returns the vector determining the unit (normalized) direction of samples in x direction.
168  * \return The vector determining the unit (normalized) direction of samples in x direction.
169  */
171 
172  /**
173  * Returns the vector determining the unit (normalized) direction of samples in y direction.
174  * \return The vector determining the unit (normalized) direction of samples in y direction.
175  */
177 
178  /**
179  * Returns the vector determining the unit (normalized) direction of samples in z direction.
180  * \return The vector determining the unit (normalized) direction of samples in z direction.
181  */
183 
184  /**
185  * Returns the position of the origin of the grid.
186  * \return The position of the origin of the grid.
187  */
188  Vector3Type getOrigin() const;
189 
190  /**
191  * Returns the scaling of the grid.
192  * \return The scaling of the grid.
193  */
194  const Vector3Type& getScaling() const;
195 
196  /**
197  * Returns a 4x4 matrix that represents the grid's transformaion.
198  * \return The grid's transformation.
199  */
200  // NOTE: this is temporary and should be removed as soon as all modules are
201  // adapted to the grid transform object
203 
204  /**
205  * Cast the transformation to the corresponding 4x4 matrix.
206  *
207  * \return the matrix representing the transform
208  */
209  operator WMatrix4d() const;
210 
211  /**
212  * Check if this transform does not include a rotation.
213  *
214  * \return True, if this transform only scales and translates.
215  */
216  bool isNotRotated() const;
217 
218  /**
219  * Translate by a vector.
220  *
221  * \param vec The vector.
222  */
223  template< typename VecType >
224  void translate( VecType const& vec );
225 
226  /**
227  * Scale the transform.
228  *
229  * \param scale A vector of scaling coeffs for the 3 directions.
230  */
231  template< typename VecType >
232  void scale( VecType const& scale );
233 
234  /**
235  * Scale the transform.
236  *
237  * \param scale scaling coeffitient for the 3 directions.
238  */
239  void scale( T const& scale );
240 
241  /**
242  * Compares two grid transforms.
243  *
244  * \param other the one to compare against
245  *
246  * \return true if transform matches
247  */
248  bool operator==( const WGridTransformOrthoTemplate< T >& other ) const;
249 
250 private:
251  /**
252  * This is a helper function which copies the parameter of another instance to its own.
253  *
254  * \param input A WGridTransformOrthoTemplate object with the numerical type InputType.
255  */
256  template< typename InputType >
258 
259  //! normalized direction of the grid's x-axis in world coordinates
261 
262  //! normalized direction of the grid's y-axis in world coordinates
264 
265  //! normalized direction of the grid's z-axis in world coordinates
267 
268  //! the scaling factors for the 3 axes, i.e. the distance between samples
270 
271  //! the origin of the grid in world coordinates
273 };
274 
277 
278 template< typename T >
280  : m_unitDirectionX( 1.0, 0.0, 0.0 ),
281  m_unitDirectionY( 0.0, 1.0, 0.0 ),
282  m_unitDirectionZ( 0.0, 0.0, 1.0 ),
283  m_scaling( 1.0, 1.0, 1.0 ),
284  m_origin( 0.0, 0.0, 0.0 )
285 {
286 }
287 
288 template< typename T >
289 template< typename InputType >
291 {
292  copyFrom( rhs );
293 }
294 
295 template< typename T >
296 template< typename InputType >
297 WGridTransformOrthoTemplate< T >::WGridTransformOrthoTemplate( InputType scaleX, InputType scaleY, InputType scaleZ )
298  : m_unitDirectionX( ( scaleX > 0.0 ) - ( scaleX < 0.0 ), 0.0, 0.0 ),
299  m_unitDirectionY( 0.0, ( scaleY > 0.0 ) - ( scaleY < 0.0 ), 0.0 ),
300  m_unitDirectionZ( 0.0, 0.0, ( scaleZ > 0.0 ) - ( scaleZ < 0.0 ) ),
301  m_scaling( fabs( scaleX ), fabs( scaleY ), fabs( scaleZ ) ),
302  m_origin( 0.0, 0.0, 0.0 )
303 {
304  WPrecond( m_scaling[ 0 ] != 0.0 && m_scaling[ 1 ] != 0.0 && m_scaling[ 2 ] != 0.0, "" );
305 }
306 
307 template< typename T >
308 template< typename InputType >
310 {
311  WPrecond( mat.getNbRows() == 4 && mat.getNbCols() == 4, "" );
312  m_unitDirectionX = Vector3Type( mat( 0, 0 ), mat( 1, 0 ), mat( 2, 0 ) );
313  m_unitDirectionY = Vector3Type( mat( 0, 1 ), mat( 1, 1 ), mat( 2, 1 ) );
314  m_unitDirectionZ = Vector3Type( mat( 0, 2 ), mat( 1, 2 ), mat( 2, 2 ) );
315 
316  m_scaling = Vector3Type( length( m_unitDirectionX ), length( m_unitDirectionY ), length( m_unitDirectionZ ) );
317 
318  WPrecond( m_scaling[ 0 ] != 0.0 && m_scaling[ 1 ] != 0.0 && m_scaling[ 2 ] != 0.0, "" );
319  m_unitDirectionX /= m_scaling[ 0 ];
320  m_unitDirectionY /= m_scaling[ 1 ];
321  m_unitDirectionZ /= m_scaling[ 2 ];
322 
323  WPrecondLess( fabs( dot( m_unitDirectionX, m_unitDirectionY ) ), 0.0001 );
324  WPrecondLess( fabs( dot( m_unitDirectionX, m_unitDirectionZ ) ), 0.0001 );
325  WPrecondLess( fabs( dot( m_unitDirectionY, m_unitDirectionZ ) ), 0.0001 );
326  m_origin = Vector3Type( mat( 0, 3 ), mat( 1, 3 ), mat( 2, 3 ) );
327 }
328 
329 template< typename T >
331 {
332 }
333 
334 template< typename T >
335 template< typename InputType >
337 {
338  if( this != &rhs )
339  {
340  copyFrom( rhs );
341  }
342  return *this;
343 }
344 
345 template< typename T >
347 {
348  return Vector3Type( m_scaling[ 0 ] * position[ 0 ] * m_unitDirectionX[ 0 ] +
349  m_scaling[ 1 ] * position[ 1 ] * m_unitDirectionY[ 0 ] +
350  m_scaling[ 2 ] * position[ 2 ] * m_unitDirectionZ[ 0 ] +
351  m_origin[ 0 ],
352  m_scaling[ 0 ] * position[ 0 ] * m_unitDirectionX[ 1 ] +
353  m_scaling[ 1 ] * position[ 1 ] * m_unitDirectionY[ 1 ] +
354  m_scaling[ 2 ] * position[ 2 ] * m_unitDirectionZ[ 1 ] +
355  m_origin[ 1 ],
356  m_scaling[ 0 ] * position[ 0 ] * m_unitDirectionX[ 2 ] +
357  m_scaling[ 1 ] * position[ 1 ] * m_unitDirectionY[ 2 ] +
358  m_scaling[ 2 ] * position[ 2 ] * m_unitDirectionZ[ 2 ] +
359  m_origin[ 2 ] );
360 }
361 
362 template< typename T >
364 {
365  Vector3Type p = position - m_origin;
366  p = Vector3Type( dot( p, m_unitDirectionX ), dot( p, m_unitDirectionY ), dot( p, m_unitDirectionZ ) );
367  p[ 0 ] /= m_scaling[ 0 ];
368  p[ 1 ] /= m_scaling[ 1 ];
369  p[ 2 ] /= m_scaling[ 2 ];
370  return p;
371 }
372 
373 template< typename T >
375 {
376  return Vector3Type( m_scaling[ 0 ] * direction[ 0 ] * m_unitDirectionX[ 0 ] +
377  m_scaling[ 1 ] * direction[ 1 ] * m_unitDirectionY[ 0 ] +
378  m_scaling[ 2 ] * direction[ 2 ] * m_unitDirectionZ[ 0 ],
379 
380  m_scaling[ 0 ] * direction[ 0 ] * m_unitDirectionX[ 1 ] +
381  m_scaling[ 1 ] * direction[ 1 ] * m_unitDirectionY[ 1 ] +
382  m_scaling[ 2 ] * direction[ 2 ] * m_unitDirectionZ[ 1 ],
383 
384  m_scaling[ 0 ] * direction[ 0 ] * m_unitDirectionX[ 2 ] +
385  m_scaling[ 1 ] * direction[ 1 ] * m_unitDirectionY[ 2 ] +
386  m_scaling[ 2 ] * direction[ 2 ] * m_unitDirectionZ[ 2 ] );
387 }
388 
389 template< typename T >
391 {
392  Vector3Type p( dot( direction, m_unitDirectionX ), dot( direction, m_unitDirectionY ), dot( direction, m_unitDirectionZ ) );
393  p[ 0 ] /= m_scaling[ 0 ];
394  p[ 1 ] /= m_scaling[ 1 ];
395  p[ 2 ] /= m_scaling[ 2 ];
396  return p;
397 }
398 
399 template< typename T >
401 {
402  return m_scaling[ 0 ];
403 }
404 
405 template< typename T >
407 {
408  return m_scaling[ 1 ];
409 }
410 
411 template< typename T >
413 {
414  return m_scaling[ 2 ];
415 }
416 
417 template< typename T >
419 {
420  return m_unitDirectionX * m_scaling[ 0 ];
421 }
422 
423 template< typename T >
425 {
426  return m_unitDirectionY * m_scaling[ 1 ];
427 }
428 
429 template< typename T >
431 {
432  return m_unitDirectionZ * m_scaling[ 2 ];
433 }
434 
435 template< typename T >
437 {
438  return m_unitDirectionX;
439 }
440 
441 template< typename T >
443 {
444  return m_unitDirectionY;
445 }
446 
447 template< typename T >
449 {
450  return m_unitDirectionZ;
451 }
452 
453 template< typename T >
455 {
456  return m_origin;
457 }
458 
459 template< typename T >
461 {
462  return m_scaling;
463 }
464 
465 template< typename T >
467 {
468  WMatrix< T > mat( 4, 4 );
469  mat.makeIdentity();
470  mat( 0, 0 ) = m_scaling[ 0 ] * m_unitDirectionX[ 0 ];
471  mat( 1, 0 ) = m_scaling[ 0 ] * m_unitDirectionX[ 1 ];
472  mat( 2, 0 ) = m_scaling[ 0 ] * m_unitDirectionX[ 2 ];
473  mat( 0, 1 ) = m_scaling[ 1 ] * m_unitDirectionY[ 0 ];
474  mat( 1, 1 ) = m_scaling[ 1 ] * m_unitDirectionY[ 1 ];
475  mat( 2, 1 ) = m_scaling[ 1 ] * m_unitDirectionY[ 2 ];
476  mat( 0, 2 ) = m_scaling[ 2 ] * m_unitDirectionZ[ 0 ];
477  mat( 1, 2 ) = m_scaling[ 2 ] * m_unitDirectionZ[ 1 ];
478  mat( 2, 2 ) = m_scaling[ 2 ] * m_unitDirectionZ[ 2 ];
479  mat( 0, 3 ) = m_origin[ 0 ];
480  mat( 1, 3 ) = m_origin[ 1 ];
481  mat( 2, 3 ) = m_origin[ 2 ];
482  return mat;
483 }
484 
485 template< typename T >
487 {
489  mat( 0, 0 ) = m_scaling[ 0 ] * m_unitDirectionX[ 0 ];
490  mat( 0, 1 ) = m_scaling[ 0 ] * m_unitDirectionX[ 1 ];
491  mat( 0, 2 ) = m_scaling[ 0 ] * m_unitDirectionX[ 2 ];
492  mat( 1, 0 ) = m_scaling[ 1 ] * m_unitDirectionY[ 0 ];
493  mat( 1, 1 ) = m_scaling[ 1 ] * m_unitDirectionY[ 1 ];
494  mat( 1, 2 ) = m_scaling[ 1 ] * m_unitDirectionY[ 2 ];
495  mat( 2, 0 ) = m_scaling[ 2 ] * m_unitDirectionZ[ 0 ];
496  mat( 2, 1 ) = m_scaling[ 2 ] * m_unitDirectionZ[ 1 ];
497  mat( 2, 2 ) = m_scaling[ 2 ] * m_unitDirectionZ[ 2 ];
498  mat( 3, 0 ) = m_origin[ 0 ];
499  mat( 3, 1 ) = m_origin[ 1 ];
500  mat( 3, 2 ) = m_origin[ 2 ];
501  return mat;
502 }
503 
504 template< typename T >
506 {
507  return m_unitDirectionX == Vector3Type( T( 1.0 ), T( 0.0 ), T( 0.0 ) )
508  && m_unitDirectionY == Vector3Type( T( 0.0 ), T( 1.0 ), T( 0.0 ) )
509  && m_unitDirectionZ == Vector3Type( T( 0.0 ), T( 0.0 ), T( 1.0 ) );
510 }
511 
512 template< typename T >
513 template< typename VecType >
515 {
516  m_origin[ 0 ] += vec[ 0 ];
517  m_origin[ 1 ] += vec[ 1 ];
518  m_origin[ 2 ] += vec[ 2 ];
519 }
520 
521 template< typename T >
522 template< typename VecType>
524 {
525  m_scaling[ 0 ] *= scale[ 0 ];
526  m_scaling[ 1 ] *= scale[ 1 ];
527  m_scaling[ 2 ] *= scale[ 2 ];
528 }
529 
530 template< typename T >
532 {
533  m_scaling[ 0 ] *= scale;
534  m_scaling[ 1 ] *= scale;
535  m_scaling[ 2 ] *= scale;
536 }
537 
538 template< typename T >
539 template< typename InputType >
541 {
542  this->m_unitDirectionX = static_cast< Vector3Type >( input.m_unitDirectionX );
543  this->m_unitDirectionY = static_cast< Vector3Type >( input.m_unitDirectionY );
544  this->m_unitDirectionZ = static_cast< Vector3Type >( input.m_unitDirectionZ );
545  this->m_scaling = static_cast< Vector3Type >( input.m_scaling );
546  this->m_origin = static_cast< Vector3Type >( input.m_origin );
547 }
548 
549 template< typename T >
551 {
552  return ( m_unitDirectionX == other.m_unitDirectionX ) &&
553  ( m_unitDirectionY == other.m_unitDirectionY ) &&
554  ( m_unitDirectionZ == other.m_unitDirectionZ ) &&
555  ( m_scaling == other.m_scaling ) &&
556  ( m_origin == other.m_origin );
557 }
558 
559 #endif // WGRIDTRANSFORMORTHO_H
Implements an orthogonal grid transformation.
Vector3Type directionToWorldSpace(Vector3Type const &direction) const
Transforms a direction from grid space to world space.
void copyFrom(WGridTransformOrthoTemplate< InputType > const &input)
This is a helper function which copies the parameter of another instance to its own.
void scale(VecType const &scale)
Scale the transform.
WMatrix< T > getTransformationMatrix() const
Returns a 4x4 matrix that represents the grid's transformaion.
void translate(VecType const &vec)
Translate by a vector.
const Vector3Type & getScaling() const
Returns the scaling of the grid.
bool isNotRotated() const
Check if this transform does not include a rotation.
WMatrixFixed< T, 3, 1 > Vector3Type
Convenience typedef for 3d vectors of the appropriate numerical type.
Vector3Type getUnitDirectionZ() const
Returns the vector determining the unit (normalized) direction of samples in z direction.
T getOffsetZ() const
Returns the distance between samples in z direction.
Vector3Type m_unitDirectionY
normalized direction of the grid's y-axis in world coordinates
T getOffsetY() const
Returns the distance between samples in y direction.
Vector3Type positionToWorldSpace(Vector3Type const &position) const
Transforms a position from grid space to world space.
WGridTransformOrthoTemplate< T > & operator=(WGridTransformOrthoTemplate< InputType > const &rhs)
Assignment operator.
Vector3Type getUnitDirectionY() const
Returns the vector determining the unit (normalized) direction of samples in y direction.
Vector3Type getDirectionY() const
Returns the vector determining the direction of samples in y direction.
Vector3Type m_unitDirectionZ
normalized direction of the grid's z-axis in world coordinates
T getOffsetX() const
Returns the distance between samples in x direction.
Vector3Type m_unitDirectionX
normalized direction of the grid's x-axis in world coordinates
Vector3Type getDirectionX() const
Returns the vector determining the direction of samples in x direction.
Vector3Type positionToGridSpace(Vector3Type const &position) const
Transforms a position from world space to grid space.
Vector3Type m_origin
the origin of the grid in world coordinates
bool operator==(const WGridTransformOrthoTemplate< T > &other) const
Compares two grid transforms.
Vector3Type m_scaling
the scaling factors for the 3 axes, i.e. the distance between samples
friend class WGridTransformOrthoTemplate
this (friend) is necessary to allow casting
Vector3Type getOrigin() const
Returns the position of the origin of the grid.
Vector3Type directionToGridSpace(Vector3Type const &direction) const
Transforms a direction from world space to grid space.
Vector3Type getDirectionZ() const
Returns the vector determining the direction of samples in z direction.
Vector3Type getUnitDirectionX() const
Returns the vector determining the unit (normalized) direction of samples in x direction.
static MatrixType identity()
Returns an identity matrix.
Definition: WMatrixFixed.h:310
Matrix template class with variable number of rows and columns.
Definition: WMatrix.h:44
size_t getNbRows() const
Get number of rows.
Definition: WMatrix.h:375
size_t getNbCols() const
Get number of columns.
Definition: WMatrix.h:383
WMatrix & makeIdentity()
Makes the matrix contain the identity matrix, i.e.
Definition: WMatrix.h:352