OpenWalnut  1.3.1
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/WLinearAlgebra.h"
31 
32 
33 
34 /**
35  * Implements an orthogonal grid transformation.
36  *
37  * \class WGridTransformOrthoTemplate
38  */
39 template< typename T >
41 {
42  // this (friend) is necessary to allow casting
43  template <class U>
44  friend class WGridTransformOrthoTemplate;
45 public:
46  /**
47  * Convenience typedef for 3d vectors of the appropriate numerical type.
48  */
50 
51  /**
52  * Constructs an identity transform.
53  */
55 
56  /**
57  * Copy constructor.
58  * Copies the data from an WGridTransformOrthoTemplate object with arbitary numerical type.
59  *
60  * \param rhs A WGridTransformOrthoTemplate object, which mustn't have the same numerical type.
61  */
62  template< typename InputType >
63  WGridTransformOrthoTemplate( WGridTransformOrthoTemplate< InputType > const& rhs ); // NOLINT -- no explicit, this allows casts
64  /**
65  * Construct a transformation that scales the grid space.
66  * \param scaleX The scale in the x-direction.
67  * \param scaleY The scale in the y-direction.
68  * \param scaleZ The scale in the z-direction.
69  */
70  template< typename InputType >
71  WGridTransformOrthoTemplate( InputType scaleX, InputType scaleY, InputType scaleZ );
72 
73  /**
74  * Construct a transformation from a transformation matrix. The provided matrix
75  * represents the transformation from grid to world space.
76  * \param mat The matrix.
77  */
78  template< typename InputType >
79  WGridTransformOrthoTemplate( WMatrix< InputType > const& mat ); // NOLINT
80 
81  /**
82  * Destructor.
83  */
85 
86 
87  /**
88  * Assignment operator.
89  * Copies the data from an WGridTransformOrthoTemplate object with arbitary numerical type.
90  *
91  * \param rhs A WGridTransformOrthoTemplate object, which mustn't have the same numerical type.
92  *
93  * \return this
94  */
95  template< typename InputType >
97  /**
98  * Transforms a position from grid space to world space.
99  * \param position The position in grid space.
100  * \return The same position in world space.
101  */
102  Vector3Type positionToWorldSpace( Vector3Type const& position ) const;
103 
104  /**
105  * Transforms a position from world space to grid space.
106  * \param position The position in world space.
107  * \return The same position in grid space.
108  */
109  Vector3Type positionToGridSpace( Vector3Type const& position ) const;
110 
111  /**
112  * Transforms a direction from grid space to world space.
113  * \param direction The direction in grid space.
114  * \return The same direction in world space.
115  */
116  Vector3Type directionToWorldSpace( Vector3Type const& direction ) const;
117 
118  /**
119  * Transforms a direction from world space to grid space.
120  * \param direction The position in world space.
121  * \return The same position in grid space.
122  */
123  Vector3Type directionToGridSpace( Vector3Type const& direction ) const;
124 
125  /**
126  * Returns the distance between samples in x direction.
127  * \return The distance between samples in x direction.
128  */
129  T getOffsetX() const;
130 
131  /**
132  * Returns the distance between samples in y direction.
133  * \return The distance between samples in y direction.
134  */
135  T getOffsetY() const;
136 
137  /**
138  * Returns the distance between samples in z direction.
139  * \return The distance between samples in z direction.
140  */
141  T getOffsetZ() const;
142 
143  /**
144  * Returns the vector determining the direction of samples in x direction.
145  * Adding this vector to a grid position in world coordinates yields the position of the next sample
146  * along the grids (world coordinate) x-axis.
147  * \return The vector determining the direction of samples in x direction.
148  */
149  Vector3Type getDirectionX() const;
150 
151  /**
152  * Returns the vector determining the direction of samples in y direction.
153  * Adding this vector to a grid position in world coordinates yields the position of the next sample
154  * along the grids (world coordinate) y-axis.
155  * \return The vector determining the direction of samples in y direction.
156  */
157  Vector3Type getDirectionY() const;
158 
159  /**
160  * Returns the vector determining the direction of samples in z direction.
161  * Adding this vector to a grid position in world coordinates yields the position of the next sample
162  * along the grids (world coordinate) z-axis.
163  * \return The vector determining the direction of samples in z direction.
164  */
165  Vector3Type getDirectionZ() const;
166 
167  /**
168  * Returns the vector determining the unit (normalized) direction of samples in x direction.
169  * \return The vector determining the unit (normalized) direction of samples in x direction.
170  */
172 
173  /**
174  * Returns the vector determining the unit (normalized) direction of samples in y direction.
175  * \return The vector determining the unit (normalized) direction of samples in y direction.
176  */
178 
179  /**
180  * Returns the vector determining the unit (normalized) direction of samples in z direction.
181  * \return The vector determining the unit (normalized) direction of samples in z direction.
182  */
184 
185  /**
186  * Returns the position of the origin of the grid.
187  * \return The position of the origin of the grid.
188  */
189  Vector3Type getOrigin() const;
190 
191  /**
192  * Returns the scaling of the grid.
193  * \return The scaling of the grid.
194  */
195  const Vector3Type& getScaling() const;
196 
197  /**
198  * Returns a 4x4 matrix that represents the grid's transformaion.
199  * \return The grid's transformation.
200  */
201  // NOTE: this is temporary and should be removed as soon as all modules are
202  // adapted to the grid transform object
204 
205  /**
206  * Cast the transformation to the corresponding 4x4 matrix.
207  *
208  * \return the matrix representing the transform
209  */
210  operator WMatrix4d() const;
211 
212  /**
213  * Check if this transform does not include a rotation.
214  *
215  * \return True, if this transform only scales and translates.
216  */
217  bool isNotRotated() const;
218 
219  /**
220  * Translate by a vector.
221  *
222  * \param vec The vector.
223  */
224  template< typename VecType >
225  void translate( VecType const& vec );
226 
227  /**
228  * Scale the transform.
229  *
230  * \param scale A vector of scaling coeffs for the 3 directions.
231  */
232  template< typename VecType >
233  void scale( VecType const& scale );
234 
235 private:
236  /**
237  * This is a helper function which copies the parameter of another instance to its own.
238  *
239  * \param input A WGridTransformOrthoTemplate object with the numerical type InputType.
240  */
241  template< typename InputType >
243 
244  //! normalized direction of the grid's x-axis in world coordinates
246 
247  //! normalized direction of the grid's y-axis in world coordinates
249 
250  //! normalized direction of the grid's z-axis in world coordinates
252 
253  //! the scaling factors for the 3 axes, i.e. the distance between samples
255 
256  //! the origin of the grid in world coordinates
258 };
259 
262 
263 template< typename T >
265  : m_unitDirectionX( 1.0, 0.0, 0.0 ),
266  m_unitDirectionY( 0.0, 1.0, 0.0 ),
267  m_unitDirectionZ( 0.0, 0.0, 1.0 ),
268  m_scaling( 1.0, 1.0, 1.0 ),
269  m_origin( 0.0, 0.0, 0.0 )
270 {
271 }
272 
273 template< typename T >
274 template< typename InputType >
276 {
277  copyFrom( rhs );
278 }
279 
280 template< typename T >
281 template< typename InputType >
282 WGridTransformOrthoTemplate< T >::WGridTransformOrthoTemplate( InputType scaleX, InputType scaleY, InputType scaleZ )
283  : m_unitDirectionX( ( scaleX > 0.0 ) - ( scaleX < 0.0 ), 0.0, 0.0 ),
284  m_unitDirectionY( 0.0, ( scaleY > 0.0 ) - ( scaleY < 0.0 ), 0.0 ),
285  m_unitDirectionZ( 0.0, 0.0, ( scaleZ > 0.0 ) - ( scaleZ < 0.0 ) ),
286  m_scaling( fabs( scaleX ), fabs( scaleY ), fabs( scaleZ ) ),
287  m_origin( 0.0, 0.0, 0.0 )
288 {
289  WPrecond( m_scaling[ 0 ] != 0.0 && m_scaling[ 1 ] != 0.0 && m_scaling[ 2 ] != 0.0, "" );
290 }
291 
292 template< typename T >
293 template< typename InputType >
295 {
296  WPrecond( mat.getNbRows() == 4 && mat.getNbCols() == 4, "" );
297  m_unitDirectionX = Vector3Type( mat( 0, 0 ), mat( 1, 0 ), mat( 2, 0 ) );
298  m_unitDirectionY = Vector3Type( mat( 0, 1 ), mat( 1, 1 ), mat( 2, 1 ) );
299  m_unitDirectionZ = Vector3Type( mat( 0, 2 ), mat( 1, 2 ), mat( 2, 2 ) );
300 
301  m_scaling = Vector3Type( length( m_unitDirectionX ), length( m_unitDirectionY ), length( m_unitDirectionZ ) );
302 
303  WPrecond( m_scaling[ 0 ] != 0.0 && m_scaling[ 1 ] != 0.0 && m_scaling[ 2 ] != 0.0, "" );
304  m_unitDirectionX /= m_scaling[ 0 ];
305  m_unitDirectionY /= m_scaling[ 1 ];
306  m_unitDirectionZ /= m_scaling[ 2 ];
307 
308  WPrecondLess( fabs( dot( m_unitDirectionX, m_unitDirectionY ) ), 0.0001 );
309  WPrecondLess( fabs( dot( m_unitDirectionX, m_unitDirectionZ ) ), 0.0001 );
310  WPrecondLess( fabs( dot( m_unitDirectionY, m_unitDirectionZ ) ), 0.0001 );
311  m_origin = Vector3Type( mat( 0, 3 ), mat( 1, 3 ), mat( 2, 3 ) );
312 }
313 
314 template< typename T >
316 {
317 }
318 
319 template< typename T >
320 template< typename InputType >
322 {
323  if( this != &rhs )
324  {
325  copyFrom( rhs );
326  }
327  return *this;
328 }
329 
330 template< typename T >
332 {
333  return Vector3Type( m_scaling[ 0 ] * position[ 0 ] * m_unitDirectionX[ 0 ] +
334  m_scaling[ 1 ] * position[ 1 ] * m_unitDirectionY[ 0 ] +
335  m_scaling[ 2 ] * position[ 2 ] * m_unitDirectionZ[ 0 ] +
336  m_origin[ 0 ],
337  m_scaling[ 0 ] * position[ 0 ] * m_unitDirectionX[ 1 ] +
338  m_scaling[ 1 ] * position[ 1 ] * m_unitDirectionY[ 1 ] +
339  m_scaling[ 2 ] * position[ 2 ] * m_unitDirectionZ[ 1 ] +
340  m_origin[ 1 ],
341  m_scaling[ 0 ] * position[ 0 ] * m_unitDirectionX[ 2 ] +
342  m_scaling[ 1 ] * position[ 1 ] * m_unitDirectionY[ 2 ] +
343  m_scaling[ 2 ] * position[ 2 ] * m_unitDirectionZ[ 2 ] +
344  m_origin[ 2 ] );
345 }
346 
347 template< typename T >
349 {
350  Vector3Type p = position - m_origin;
351  p = Vector3Type( dot( p, m_unitDirectionX ), dot( p, m_unitDirectionY ), dot( p, m_unitDirectionZ ) );
352  p[ 0 ] /= m_scaling[ 0 ];
353  p[ 1 ] /= m_scaling[ 1 ];
354  p[ 2 ] /= m_scaling[ 2 ];
355  return p;
356 }
357 
358 template< typename T >
360 {
361  return Vector3Type( m_scaling[ 0 ] * direction[ 0 ] * m_unitDirectionX[ 0 ] +
362  m_scaling[ 1 ] * direction[ 1 ] * m_unitDirectionY[ 0 ] +
363  m_scaling[ 2 ] * direction[ 2 ] * m_unitDirectionZ[ 0 ],
364 
365  m_scaling[ 0 ] * direction[ 0 ] * m_unitDirectionX[ 1 ] +
366  m_scaling[ 1 ] * direction[ 1 ] * m_unitDirectionY[ 1 ] +
367  m_scaling[ 2 ] * direction[ 2 ] * m_unitDirectionZ[ 1 ],
368 
369  m_scaling[ 0 ] * direction[ 0 ] * m_unitDirectionX[ 2 ] +
370  m_scaling[ 1 ] * direction[ 1 ] * m_unitDirectionY[ 2 ] +
371  m_scaling[ 2 ] * direction[ 2 ] * m_unitDirectionZ[ 2 ] );
372 }
373 
374 template< typename T >
376 {
377  Vector3Type p( dot( direction, m_unitDirectionX ), dot( direction, m_unitDirectionY ), dot( direction, m_unitDirectionZ ) );
378  p[ 0 ] /= m_scaling[ 0 ];
379  p[ 1 ] /= m_scaling[ 1 ];
380  p[ 2 ] /= m_scaling[ 2 ];
381  return p;
382 }
383 
384 template< typename T >
386 {
387  return m_scaling[ 0 ];
388 }
389 
390 template< typename T >
392 {
393  return m_scaling[ 1 ];
394 }
395 
396 template< typename T >
398 {
399  return m_scaling[ 2 ];
400 }
401 
402 template< typename T >
404 {
405  return m_unitDirectionX * m_scaling[ 0 ];
406 }
407 
408 template< typename T >
410 {
411  return m_unitDirectionY * m_scaling[ 1 ];
412 }
413 
414 template< typename T >
416 {
417  return m_unitDirectionZ * m_scaling[ 2 ];
418 }
419 
420 template< typename T >
422 {
423  return m_unitDirectionX;
424 }
425 
426 template< typename T >
428 {
429  return m_unitDirectionY;
430 }
431 
432 template< typename T >
434 {
435  return m_unitDirectionZ;
436 }
437 
438 template< typename T >
440 {
441  return m_origin;
442 }
443 
444 template< typename T >
446 {
447  return m_scaling;
448 }
449 
450 template< typename T >
452 {
453  WMatrix< T > mat( 4, 4 );
454  mat.makeIdentity();
455  mat( 0, 0 ) = m_scaling[ 0 ] * m_unitDirectionX[ 0 ];
456  mat( 1, 0 ) = m_scaling[ 0 ] * m_unitDirectionX[ 1 ];
457  mat( 2, 0 ) = m_scaling[ 0 ] * m_unitDirectionX[ 2 ];
458  mat( 0, 1 ) = m_scaling[ 1 ] * m_unitDirectionY[ 0 ];
459  mat( 1, 1 ) = m_scaling[ 1 ] * m_unitDirectionY[ 1 ];
460  mat( 2, 1 ) = m_scaling[ 1 ] * m_unitDirectionY[ 2 ];
461  mat( 0, 2 ) = m_scaling[ 2 ] * m_unitDirectionZ[ 0 ];
462  mat( 1, 2 ) = m_scaling[ 2 ] * m_unitDirectionZ[ 1 ];
463  mat( 2, 2 ) = m_scaling[ 2 ] * m_unitDirectionZ[ 2 ];
464  mat( 0, 3 ) = m_origin[ 0 ];
465  mat( 1, 3 ) = m_origin[ 1 ];
466  mat( 2, 3 ) = m_origin[ 2 ];
467  return mat;
468 }
469 
470 template< typename T >
472 {
474  mat( 0, 0 ) = m_scaling[ 0 ] * m_unitDirectionX[ 0 ];
475  mat( 0, 1 ) = m_scaling[ 0 ] * m_unitDirectionX[ 1 ];
476  mat( 0, 2 ) = m_scaling[ 0 ] * m_unitDirectionX[ 2 ];
477  mat( 1, 0 ) = m_scaling[ 1 ] * m_unitDirectionY[ 0 ];
478  mat( 1, 1 ) = m_scaling[ 1 ] * m_unitDirectionY[ 1 ];
479  mat( 1, 2 ) = m_scaling[ 1 ] * m_unitDirectionY[ 2 ];
480  mat( 2, 0 ) = m_scaling[ 2 ] * m_unitDirectionZ[ 0 ];
481  mat( 2, 1 ) = m_scaling[ 2 ] * m_unitDirectionZ[ 1 ];
482  mat( 2, 2 ) = m_scaling[ 2 ] * m_unitDirectionZ[ 2 ];
483  mat( 3, 0 ) = m_origin[ 0 ];
484  mat( 3, 1 ) = m_origin[ 1 ];
485  mat( 3, 2 ) = m_origin[ 2 ];
486  return mat;
487 }
488 
489 template< typename T >
491 {
492  return m_unitDirectionX == Vector3Type( T( 1.0 ), T( 0.0 ), T( 0.0 ) )
493  && m_unitDirectionY == Vector3Type( T( 0.0 ), T( 1.0 ), T( 0.0 ) )
494  && m_unitDirectionZ == Vector3Type( T( 0.0 ), T( 0.0 ), T( 1.0 ) );
495 }
496 
497 template< typename T >
498 template< typename VecType >
500 {
501  m_origin[ 0 ] += vec[ 0 ];
502  m_origin[ 1 ] += vec[ 1 ];
503  m_origin[ 2 ] += vec[ 2 ];
504 }
505 
506 template< typename T >
507 template< typename VecType>
509 {
510  m_scaling[ 0 ] *= scale[ 0 ];
511  m_scaling[ 1 ] *= scale[ 1 ];
512  m_scaling[ 2 ] *= scale[ 2 ];
513 }
514 
515 template< typename T >
516 template< typename InputType >
518 {
519  this->m_unitDirectionX = static_cast< Vector3Type >( input.m_unitDirectionX );
520  this->m_unitDirectionY = static_cast< Vector3Type >( input.m_unitDirectionY );
521  this->m_unitDirectionZ = static_cast< Vector3Type >( input.m_unitDirectionZ );
522  this->m_scaling = static_cast< Vector3Type >( input.m_scaling );
523  this->m_origin = static_cast< Vector3Type >( input.m_origin );
524 }
525 
526 #endif // WGRIDTRANSFORMORTHO_H