OpenWalnut 1.3.1
|
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