OpenWalnut 1.3.1
WGridTransformOrtho.h
00001 //---------------------------------------------------------------------------
00002 //
00003 // Project: OpenWalnut ( http://www.openwalnut.org )
00004 //
00005 // Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
00006 // For more information see http://www.openwalnut.org/copying
00007 //
00008 // This file is part of OpenWalnut.
00009 //
00010 // OpenWalnut is free software: you can redistribute it and/or modify
00011 // it under the terms of the GNU Lesser General Public License as published by
00012 // the Free Software Foundation, either version 3 of the License, or
00013 // (at your option) any later version.
00014 //
00015 // OpenWalnut is distributed in the hope that it will be useful,
00016 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00017 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018 // GNU Lesser General Public License for more details.
00019 //
00020 // You should have received a copy of the GNU Lesser General Public License
00021 // along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
00022 //
00023 //---------------------------------------------------------------------------
00024 
00025 #ifndef WGRIDTRANSFORMORTHO_H
00026 #define WGRIDTRANSFORMORTHO_H
00027 
00028 #include "../common/exceptions/WPreconditionNotMet.h"
00029 #include "../common/math/WMatrix.h"
00030 #include "../common/math/linearAlgebra/WLinearAlgebra.h"
00031 
00032 
00033 
00034 /**
00035  * Implements an orthogonal grid transformation.
00036  *
00037  * \class WGridTransformOrthoTemplate
00038  */
00039 template< typename T >
00040 class WGridTransformOrthoTemplate
00041 {
00042     // this (friend) is necessary to allow casting
00043     template <class U>
00044     friend class WGridTransformOrthoTemplate;
00045 public:
00046     /**
00047      * Convenience typedef for 3d vectors of the appropriate numerical type.
00048      */
00049     typedef WMatrixFixed< T, 3, 1 > Vector3Type;
00050 
00051     /**
00052      * Constructs an identity transform.
00053      */
00054     WGridTransformOrthoTemplate();
00055 
00056     /**
00057      * Copy constructor.
00058      * Copies the data from an WGridTransformOrthoTemplate object with arbitary numerical type.
00059      *
00060      * \param rhs A WGridTransformOrthoTemplate object, which mustn't have the same numerical type.
00061      */
00062     template< typename InputType >
00063     WGridTransformOrthoTemplate( WGridTransformOrthoTemplate< InputType > const& rhs ); // NOLINT -- no explicit, this allows casts
00064     /**
00065      * Construct a transformation that scales the grid space.
00066      * \param scaleX The scale in the x-direction.
00067      * \param scaleY The scale in the y-direction.
00068      * \param scaleZ The scale in the z-direction.
00069      */
00070     template< typename InputType >
00071     WGridTransformOrthoTemplate( InputType scaleX, InputType scaleY, InputType scaleZ );
00072 
00073     /**
00074      * Construct a transformation from a transformation matrix. The provided matrix
00075      * represents the transformation from grid to world space.
00076      * \param mat The matrix.
00077      */
00078     template< typename InputType >
00079     WGridTransformOrthoTemplate( WMatrix< InputType > const& mat );  // NOLINT
00080 
00081     /**
00082      * Destructor.
00083      */
00084     ~WGridTransformOrthoTemplate();
00085 
00086 
00087     /**
00088      * Assignment operator.
00089      * Copies the data from an WGridTransformOrthoTemplate object with arbitary numerical type.
00090      *
00091      * \param rhs A WGridTransformOrthoTemplate object, which mustn't have the same numerical type.
00092      *
00093      * \return this
00094      */
00095     template< typename InputType >
00096     WGridTransformOrthoTemplate< T >& operator=( WGridTransformOrthoTemplate< InputType > const& rhs );
00097     /**
00098      * Transforms a position from grid space to world space.
00099      * \param position The position in grid space.
00100      * \return The same position in world space.
00101      */
00102     Vector3Type positionToWorldSpace( Vector3Type const& position ) const;
00103 
00104     /**
00105      * Transforms a position from world space to grid space.
00106      * \param position The position in world space.
00107      * \return The same position in grid space.
00108      */
00109     Vector3Type positionToGridSpace( Vector3Type const& position ) const;
00110 
00111     /**
00112      * Transforms a direction from grid space to world space.
00113      * \param direction The direction in grid space.
00114      * \return The same direction in world space.
00115      */
00116     Vector3Type directionToWorldSpace( Vector3Type const& direction ) const;
00117 
00118     /**
00119      * Transforms a direction from world space to grid space.
00120      * \param direction The position in world space.
00121      * \return The same position in grid space.
00122      */
00123     Vector3Type directionToGridSpace( Vector3Type const& direction ) const;
00124 
00125     /**
00126      * Returns the distance between samples in x direction.
00127      * \return The distance between samples in x direction.
00128      */
00129     T getOffsetX() const;
00130 
00131     /**
00132      * Returns the distance between samples in y direction.
00133      * \return The distance between samples in y direction.
00134      */
00135     T getOffsetY() const;
00136 
00137     /**
00138      * Returns the distance between samples in z direction.
00139      * \return The distance between samples in z direction.
00140      */
00141     T getOffsetZ() const;
00142 
00143     /**
00144      * Returns the vector determining the direction of samples in x direction.
00145      * Adding this vector to a grid position in world coordinates yields the position of the next sample
00146      * along the grids (world coordinate) x-axis.
00147      * \return The vector determining the direction of samples in x direction.
00148      */
00149     Vector3Type getDirectionX() const;
00150 
00151     /**
00152      * Returns the vector determining the direction of samples in y direction.
00153      * Adding this vector to a grid position in world coordinates yields the position of the next sample
00154      * along the grids (world coordinate) y-axis.
00155      * \return The vector determining the direction of samples in y direction.
00156      */
00157     Vector3Type getDirectionY() const;
00158 
00159     /**
00160      * Returns the vector determining the direction of samples in z direction.
00161      * Adding this vector to a grid position in world coordinates yields the position of the next sample
00162      * along the grids (world coordinate) z-axis.
00163      * \return The vector determining the direction of samples in z direction.
00164      */
00165     Vector3Type getDirectionZ() const;
00166 
00167     /**
00168      * Returns the vector determining the unit (normalized) direction of samples in x direction.
00169      * \return The vector determining the unit (normalized) direction of samples in x direction.
00170      */
00171     Vector3Type getUnitDirectionX() const;
00172 
00173     /**
00174      * Returns the vector determining the unit (normalized) direction of samples in y direction.
00175      * \return The vector determining the unit (normalized) direction of samples in y direction.
00176      */
00177     Vector3Type getUnitDirectionY() const;
00178 
00179     /**
00180      * Returns the vector determining the unit (normalized) direction of samples in z direction.
00181      * \return The vector determining the unit (normalized) direction of samples in z direction.
00182      */
00183     Vector3Type getUnitDirectionZ() const;
00184 
00185     /**
00186      * Returns the position of the origin of the grid.
00187      * \return The position of the origin of the grid.
00188      */
00189     Vector3Type getOrigin() const;
00190 
00191     /**
00192      * Returns the scaling of the grid.
00193      * \return The scaling of the grid.
00194      */
00195     const Vector3Type& getScaling() const;
00196 
00197     /**
00198      * Returns a 4x4 matrix that represents the grid's transformaion.
00199      * \return The grid's transformation.
00200      */
00201     // NOTE: this is temporary and should be removed as soon as all modules are
00202     // adapted to the grid transform object
00203     WMatrix< T > getTransformationMatrix() const;
00204 
00205     /**
00206      * Cast the transformation to the corresponding 4x4 matrix.
00207      *
00208      * \return the matrix representing the transform
00209      */
00210     operator WMatrix4d() const;
00211 
00212     /**
00213      * Check if this transform does not include a rotation.
00214      *
00215      * \return True, if this transform only scales and translates.
00216      */
00217     bool isNotRotated() const;
00218 
00219     /**
00220      * Translate by a vector.
00221      *
00222      * \param vec The vector.
00223      */
00224     template< typename VecType >
00225     void translate( VecType const& vec );
00226 
00227     /**
00228      * Scale the transform.
00229      *
00230      * \param scale A vector of scaling coeffs for the 3 directions.
00231      */
00232     template< typename VecType >
00233     void scale( VecType const& scale );
00234 
00235 private:
00236     /**
00237      * This is a helper function which copies the parameter of another instance to its own.
00238      *
00239      * \param input A WGridTransformOrthoTemplate object with the numerical type InputType.
00240      */
00241     template< typename InputType >
00242     void copyFrom( WGridTransformOrthoTemplate< InputType > const& input );
00243 
00244     //! normalized direction of the grid's x-axis in world coordinates
00245     Vector3Type m_unitDirectionX;
00246 
00247     //! normalized direction of the grid's y-axis in world coordinates
00248     Vector3Type m_unitDirectionY;
00249 
00250     //! normalized direction of the grid's z-axis in world coordinates
00251     Vector3Type m_unitDirectionZ;
00252 
00253     //! the scaling factors for the 3 axes, i.e. the distance between samples
00254     Vector3Type m_scaling;
00255 
00256     //! the origin of the grid in world coordinates
00257     Vector3Type m_origin;
00258 };
00259 
00260 typedef WGridTransformOrthoTemplate< double > WGridTransformOrtho;
00261 typedef WGridTransformOrthoTemplate< float > WGridTransformOrthoFloat;
00262 
00263 template< typename T >
00264 WGridTransformOrthoTemplate< T >::WGridTransformOrthoTemplate()
00265     : m_unitDirectionX( 1.0, 0.0, 0.0 ),
00266       m_unitDirectionY( 0.0, 1.0, 0.0 ),
00267       m_unitDirectionZ( 0.0, 0.0, 1.0 ),
00268       m_scaling( 1.0, 1.0, 1.0 ),
00269       m_origin( 0.0, 0.0, 0.0 )
00270 {
00271 }
00272 
00273 template< typename T >
00274 template< typename InputType >
00275 WGridTransformOrthoTemplate< T >::WGridTransformOrthoTemplate( WGridTransformOrthoTemplate< InputType > const& rhs  )
00276 {
00277     copyFrom( rhs );
00278 }
00279 
00280 template< typename T >
00281 template< typename InputType >
00282 WGridTransformOrthoTemplate< T >::WGridTransformOrthoTemplate( InputType scaleX, InputType scaleY, InputType scaleZ )
00283     : m_unitDirectionX( ( scaleX > 0.0 ) - ( scaleX < 0.0 ), 0.0, 0.0 ),
00284       m_unitDirectionY( 0.0, ( scaleY > 0.0 ) - ( scaleY < 0.0 ), 0.0 ),
00285       m_unitDirectionZ( 0.0, 0.0, ( scaleZ > 0.0 ) - ( scaleZ < 0.0 ) ),
00286       m_scaling( fabs( scaleX ), fabs( scaleY ), fabs( scaleZ ) ),
00287       m_origin( 0.0, 0.0, 0.0 )
00288 {
00289     WPrecond( m_scaling[ 0 ] != 0.0 && m_scaling[ 1 ] != 0.0 && m_scaling[ 2 ] != 0.0, "" );
00290 }
00291 
00292 template< typename T >
00293 template< typename InputType >
00294 WGridTransformOrthoTemplate< T >::WGridTransformOrthoTemplate( WMatrix< InputType > const& mat )
00295 {
00296     WPrecond( mat.getNbRows() == 4 && mat.getNbCols() == 4, "" );
00297     m_unitDirectionX = Vector3Type( mat( 0, 0 ), mat( 1, 0 ), mat( 2, 0 ) );
00298     m_unitDirectionY = Vector3Type( mat( 0, 1 ), mat( 1, 1 ), mat( 2, 1 ) );
00299     m_unitDirectionZ = Vector3Type( mat( 0, 2 ), mat( 1, 2 ), mat( 2, 2 ) );
00300 
00301     m_scaling = Vector3Type( length( m_unitDirectionX ), length( m_unitDirectionY ), length( m_unitDirectionZ ) );
00302 
00303     WPrecond( m_scaling[ 0 ] != 0.0 && m_scaling[ 1 ] != 0.0 && m_scaling[ 2 ] != 0.0, "" );
00304     m_unitDirectionX /= m_scaling[ 0 ];
00305     m_unitDirectionY /= m_scaling[ 1 ];
00306     m_unitDirectionZ /= m_scaling[ 2 ];
00307 
00308     WPrecondLess( fabs( dot( m_unitDirectionX, m_unitDirectionY ) ), 0.0001 );
00309     WPrecondLess( fabs( dot( m_unitDirectionX, m_unitDirectionZ ) ), 0.0001 );
00310     WPrecondLess( fabs( dot( m_unitDirectionY, m_unitDirectionZ ) ), 0.0001 );
00311     m_origin = Vector3Type( mat( 0, 3 ), mat( 1, 3 ), mat( 2, 3 ) );
00312 }
00313 
00314 template< typename T >
00315 WGridTransformOrthoTemplate< T >::~WGridTransformOrthoTemplate()
00316 {
00317 }
00318 
00319 template< typename T >
00320 template< typename InputType >
00321 WGridTransformOrthoTemplate< T >& WGridTransformOrthoTemplate< T >::operator=( WGridTransformOrthoTemplate< InputType > const& rhs )
00322 {
00323     if( this != &rhs )
00324     {
00325         copyFrom( rhs );
00326     }
00327     return *this;
00328 }
00329 
00330 template< typename T >
00331 typename WGridTransformOrthoTemplate< T >::Vector3Type WGridTransformOrthoTemplate< T >::positionToWorldSpace( Vector3Type const& position ) const
00332 {
00333     return Vector3Type( m_scaling[ 0 ] * position[ 0 ] * m_unitDirectionX[ 0 ] +
00334                         m_scaling[ 1 ] * position[ 1 ] * m_unitDirectionY[ 0 ] +
00335                         m_scaling[ 2 ] * position[ 2 ] * m_unitDirectionZ[ 0 ] +
00336                         m_origin[ 0 ],
00337                         m_scaling[ 0 ] * position[ 0 ] * m_unitDirectionX[ 1 ] +
00338                         m_scaling[ 1 ] * position[ 1 ] * m_unitDirectionY[ 1 ] +
00339                         m_scaling[ 2 ] * position[ 2 ] * m_unitDirectionZ[ 1 ] +
00340                         m_origin[ 1 ],
00341                         m_scaling[ 0 ] * position[ 0 ] * m_unitDirectionX[ 2 ] +
00342                         m_scaling[ 1 ] * position[ 1 ] * m_unitDirectionY[ 2 ] +
00343                         m_scaling[ 2 ] * position[ 2 ] * m_unitDirectionZ[ 2 ] +
00344                         m_origin[ 2 ] );
00345 }
00346 
00347 template< typename T >
00348 typename WGridTransformOrthoTemplate< T >::Vector3Type WGridTransformOrthoTemplate< T >::positionToGridSpace( Vector3Type const& position ) const
00349 {
00350     Vector3Type p = position - m_origin;
00351     p = Vector3Type( dot( p, m_unitDirectionX ), dot( p, m_unitDirectionY ), dot( p, m_unitDirectionZ ) );
00352     p[ 0 ] /= m_scaling[ 0 ];
00353     p[ 1 ] /= m_scaling[ 1 ];
00354     p[ 2 ] /= m_scaling[ 2 ];
00355     return p;
00356 }
00357 
00358 template< typename T >
00359 typename WGridTransformOrthoTemplate< T >::Vector3Type WGridTransformOrthoTemplate< T >::directionToWorldSpace( Vector3Type const& direction ) const
00360 {
00361     return Vector3Type( m_scaling[ 0 ] * direction[ 0 ] * m_unitDirectionX[ 0 ] +
00362                         m_scaling[ 1 ] * direction[ 1 ] * m_unitDirectionY[ 0 ] +
00363                         m_scaling[ 2 ] * direction[ 2 ] * m_unitDirectionZ[ 0 ],
00364 
00365                         m_scaling[ 0 ] * direction[ 0 ] * m_unitDirectionX[ 1 ] +
00366                         m_scaling[ 1 ] * direction[ 1 ] * m_unitDirectionY[ 1 ] +
00367                         m_scaling[ 2 ] * direction[ 2 ] * m_unitDirectionZ[ 1 ],
00368 
00369                         m_scaling[ 0 ] * direction[ 0 ] * m_unitDirectionX[ 2 ] +
00370                         m_scaling[ 1 ] * direction[ 1 ] * m_unitDirectionY[ 2 ] +
00371                         m_scaling[ 2 ] * direction[ 2 ] * m_unitDirectionZ[ 2 ] );
00372 }
00373 
00374 template< typename T >
00375 typename WGridTransformOrthoTemplate< T >::Vector3Type WGridTransformOrthoTemplate< T >::directionToGridSpace( Vector3Type const& direction ) const
00376 {
00377     Vector3Type p( dot( direction, m_unitDirectionX ), dot( direction, m_unitDirectionY ), dot( direction, m_unitDirectionZ ) );
00378     p[ 0 ] /= m_scaling[ 0 ];
00379     p[ 1 ] /= m_scaling[ 1 ];
00380     p[ 2 ] /= m_scaling[ 2 ];
00381     return p;
00382 }
00383 
00384 template< typename T >
00385 T WGridTransformOrthoTemplate< T >::getOffsetX() const
00386 {
00387     return m_scaling[ 0 ];
00388 }
00389 
00390 template< typename T >
00391 T WGridTransformOrthoTemplate< T >::getOffsetY() const
00392 {
00393     return m_scaling[ 1 ];
00394 }
00395 
00396 template< typename T >
00397 T WGridTransformOrthoTemplate< T >::getOffsetZ() const
00398 {
00399     return m_scaling[ 2 ];
00400 }
00401 
00402 template< typename T >
00403 typename WGridTransformOrthoTemplate< T >::Vector3Type WGridTransformOrthoTemplate< T >::getDirectionX() const
00404 {
00405     return m_unitDirectionX * m_scaling[ 0 ];
00406 }
00407 
00408 template< typename T >
00409 typename WGridTransformOrthoTemplate< T >::Vector3Type WGridTransformOrthoTemplate< T >::getDirectionY() const
00410 {
00411     return m_unitDirectionY * m_scaling[ 1 ];
00412 }
00413 
00414 template< typename T >
00415 typename WGridTransformOrthoTemplate< T >::Vector3Type WGridTransformOrthoTemplate< T >::getDirectionZ() const
00416 {
00417     return m_unitDirectionZ * m_scaling[ 2 ];
00418 }
00419 
00420 template< typename T >
00421 typename WGridTransformOrthoTemplate< T >::Vector3Type WGridTransformOrthoTemplate< T >::getUnitDirectionX() const
00422 {
00423     return m_unitDirectionX;
00424 }
00425 
00426 template< typename T >
00427 typename WGridTransformOrthoTemplate< T >::Vector3Type WGridTransformOrthoTemplate< T >::getUnitDirectionY() const
00428 {
00429     return m_unitDirectionY;
00430 }
00431 
00432 template< typename T >
00433 typename WGridTransformOrthoTemplate< T >::Vector3Type WGridTransformOrthoTemplate< T >::getUnitDirectionZ() const
00434 {
00435     return m_unitDirectionZ;
00436 }
00437 
00438 template< typename T >
00439 typename WGridTransformOrthoTemplate< T >::Vector3Type WGridTransformOrthoTemplate< T >::getOrigin() const
00440 {
00441     return m_origin;
00442 }
00443 
00444 template< typename T >
00445 inline const typename WGridTransformOrthoTemplate< T >::Vector3Type& WGridTransformOrthoTemplate< T >::getScaling() const
00446 {
00447     return m_scaling;
00448 }
00449 
00450 template< typename T >
00451 WMatrix< T > WGridTransformOrthoTemplate< T >::getTransformationMatrix() const
00452 {
00453     WMatrix< T > mat( 4, 4 );
00454     mat.makeIdentity();
00455     mat( 0, 0 ) = m_scaling[ 0 ] * m_unitDirectionX[ 0 ];
00456     mat( 1, 0 ) = m_scaling[ 0 ] * m_unitDirectionX[ 1 ];
00457     mat( 2, 0 ) = m_scaling[ 0 ] * m_unitDirectionX[ 2 ];
00458     mat( 0, 1 ) = m_scaling[ 1 ] * m_unitDirectionY[ 0 ];
00459     mat( 1, 1 ) = m_scaling[ 1 ] * m_unitDirectionY[ 1 ];
00460     mat( 2, 1 ) = m_scaling[ 1 ] * m_unitDirectionY[ 2 ];
00461     mat( 0, 2 ) = m_scaling[ 2 ] * m_unitDirectionZ[ 0 ];
00462     mat( 1, 2 ) = m_scaling[ 2 ] * m_unitDirectionZ[ 1 ];
00463     mat( 2, 2 ) = m_scaling[ 2 ] * m_unitDirectionZ[ 2 ];
00464     mat( 0, 3 ) = m_origin[ 0 ];
00465     mat( 1, 3 ) = m_origin[ 1 ];
00466     mat( 2, 3 ) = m_origin[ 2 ];
00467     return mat;
00468 }
00469 
00470 template< typename T >
00471 WGridTransformOrthoTemplate< T >::operator WMatrix4d() const
00472 {
00473     WMatrix4d mat = WMatrix4d::identity();
00474     mat( 0, 0 ) = m_scaling[ 0 ] * m_unitDirectionX[ 0 ];
00475     mat( 0, 1 ) = m_scaling[ 0 ] * m_unitDirectionX[ 1 ];
00476     mat( 0, 2 ) = m_scaling[ 0 ] * m_unitDirectionX[ 2 ];
00477     mat( 1, 0 ) = m_scaling[ 1 ] * m_unitDirectionY[ 0 ];
00478     mat( 1, 1 ) = m_scaling[ 1 ] * m_unitDirectionY[ 1 ];
00479     mat( 1, 2 ) = m_scaling[ 1 ] * m_unitDirectionY[ 2 ];
00480     mat( 2, 0 ) = m_scaling[ 2 ] * m_unitDirectionZ[ 0 ];
00481     mat( 2, 1 ) = m_scaling[ 2 ] * m_unitDirectionZ[ 1 ];
00482     mat( 2, 2 ) = m_scaling[ 2 ] * m_unitDirectionZ[ 2 ];
00483     mat( 3, 0 ) = m_origin[ 0 ];
00484     mat( 3, 1 ) = m_origin[ 1 ];
00485     mat( 3, 2 ) = m_origin[ 2 ];
00486     return mat;
00487 }
00488 
00489 template< typename T >
00490 bool WGridTransformOrthoTemplate< T >::isNotRotated() const
00491 {
00492     return m_unitDirectionX == Vector3Type( T( 1.0 ), T( 0.0 ), T( 0.0 ) )
00493         && m_unitDirectionY == Vector3Type( T( 0.0 ), T( 1.0 ), T( 0.0 ) )
00494         && m_unitDirectionZ == Vector3Type( T( 0.0 ), T( 0.0 ), T( 1.0 ) );
00495 }
00496 
00497 template< typename T >
00498 template< typename VecType >
00499 void WGridTransformOrthoTemplate< T >::translate( VecType const& vec )
00500 {
00501     m_origin[ 0 ] += vec[ 0 ];
00502     m_origin[ 1 ] += vec[ 1 ];
00503     m_origin[ 2 ] += vec[ 2 ];
00504 }
00505 
00506 template< typename T >
00507 template< typename VecType>
00508 void WGridTransformOrthoTemplate< T >::scale( VecType const& scale )
00509 {
00510     m_scaling[ 0 ] *= scale[ 0 ];
00511     m_scaling[ 1 ] *= scale[ 1 ];
00512     m_scaling[ 2 ] *= scale[ 2 ];
00513 }
00514 
00515 template< typename T >
00516 template< typename InputType >
00517 void WGridTransformOrthoTemplate< T >::copyFrom( WGridTransformOrthoTemplate< InputType > const& input )
00518 {
00519     this->m_unitDirectionX = static_cast< Vector3Type >( input.m_unitDirectionX );
00520     this->m_unitDirectionY = static_cast< Vector3Type >( input.m_unitDirectionY );
00521     this->m_unitDirectionZ = static_cast< Vector3Type >( input.m_unitDirectionZ );
00522     this->m_scaling = static_cast< Vector3Type >( input.m_scaling );
00523     this->m_origin = static_cast< Vector3Type >( input.m_origin );
00524 }
00525 
00526 #endif  // WGRIDTRANSFORMORTHO_H