MOAB: Mesh Oriented datABase  (version 5.3.0)
HomXform.hpp
Go to the documentation of this file.
00001 /**
00002  * MOAB, a Mesh-Oriented datABase, is a software component for creating,
00003  * storing and accessing finite element mesh data.
00004  *
00005  * Copyright 2004 Sandia Corporation.  Under the terms of Contract
00006  * DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government
00007  * retains certain rights in this software.
00008  *
00009  * This library is free software; you can redistribute it and/or
00010  * modify it under the terms of the GNU Lesser General Public
00011  * License as published by the Free Software Foundation; either
00012  * version 2.1 of the License, or (at your option) any later version.
00013  *
00014  */
00015 
00016 #ifndef MOAB_HOMXFORM
00017 #define MOAB_HOMXFORM
00018 
00019 /*
00020  * \file HomXform.hpp
00021  *
00022  * \brief Representation and functions for homogeneous transforms
00023  *
00024  * A homogeneous transform is a 4x4 matrix for representing and manipulating
00025  * homogeneous coordinates, which are x' = (x/h, y/h, z/h, h).  See Mortenson,
00026  * Geometric Modeling, or other texts on geometric modeling for details of homogeneous
00027  * transforms.
00028  */
00029 
00030 #define XFORM( a, b )       xForm[4 * ( a ) + ( b )]
00031 #define XFORM_INDEX( a, b ) ( 4 * ( a ) + ( b ) )
00032 
00033 #include <cmath>
00034 #include <cmath>
00035 
00036 #include <ostream>
00037 
00038 #include "moab/win32_config.h"
00039 
00040 namespace moab
00041 {
00042 
00043 class HomXform;
00044 
00045 /** \class HomCoord
00046  * \brief Homogeneous coordinate vector
00047  */
00048 class HomCoord
00049 {
00050   private:
00051     //! coordinate data
00052 #if defined( __INTEL_COMPILER ) && ( __INTEL_COMPILER < 1310 )
00053     // Hack Intel compiler 12 issues with -O2 optimization
00054     int homCoord[5];
00055 #else
00056     int homCoord[4];
00057 #endif
00058 
00059   public:
00060     friend class HomXform;
00061 
00062     static MOAB_EXPORT HomCoord unitv[3];
00063     static MOAB_EXPORT HomCoord IDENTITY;
00064 
00065     //! constructors
00066     HomCoord();
00067     HomCoord( const int coords[], const int num_coords = 4 );
00068     HomCoord( const int coord0, const int coord1, const int coord2, const int coord3 );
00069     HomCoord( const int coord0, const int coord1, const int coord2 );
00070     HomCoord( const HomCoord& coord );
00071 
00072     //! set function
00073     void set( const int coords[] );
00074     void set( const int i, const int j, const int k, const int h = 1 );
00075 
00076     //! get function
00077     const int* hom_coord() const
00078     {
00079         return homCoord;
00080     }
00081 
00082     // Getters needed for share windows
00083     static HomCoord& getUnitv( int c );
00084 
00085     //! parameter-based access functions
00086     int i() const
00087     {
00088         return homCoord[0];
00089     }
00090     int j() const
00091     {
00092         return homCoord[1];
00093     }
00094     int k() const
00095     {
00096         return homCoord[2];
00097     }
00098     int h() const
00099     {
00100         return homCoord[3];
00101     }
00102 
00103     //! squared length
00104     int length_squared() const;
00105 
00106     //! length
00107     int length() const;
00108 
00109     //! normalize
00110     void normalize();
00111 
00112     //! operators
00113     HomCoord& operator*=( const HomXform& rhs2 );
00114     HomCoord operator*( const HomXform& rhs2 ) const;
00115     HomCoord& operator*=( const int mult );
00116     HomCoord operator*( const int mult ) const;
00117     inline HomCoord& operator/=( const HomXform& rhs2 );
00118     HomCoord operator/( const HomXform& rhs2 ) const;
00119     inline HomCoord& operator/=( const int mult );
00120     HomCoord operator/( const int mult ) const;
00121     inline HomCoord& operator+=( const HomCoord& rhs1 );
00122     HomCoord operator+( const HomCoord& rhs1 ) const;
00123     inline HomCoord& operator-=( const HomCoord& rhs1 );
00124     HomCoord operator-( const HomCoord& rhs1 ) const;
00125     HomCoord& operator=( const HomCoord& rhs );
00126 
00127     // dot product
00128     int operator%( const HomCoord& rhs ) const;
00129 
00130     // cross product
00131     HomCoord operator*( const HomCoord& rhs ) const;
00132     HomCoord& operator*=( const HomCoord& rhs );
00133 
00134     bool operator==( const HomCoord& rhs1 ) const;
00135     bool operator!=( const HomCoord& rhs1 ) const;
00136     bool operator>=( const HomCoord& rhs1 ) const;
00137     bool operator<=( const HomCoord& rhs1 ) const;
00138     bool operator>( const HomCoord& rhs1 ) const;
00139     bool operator<( const HomCoord& rhs1 ) const;
00140     inline int operator[]( const int& param ) const;
00141     int& operator[]( const int& param );
00142 };
00143 
00144 /** \class HomXform
00145  * \brief Homogeneous coordinate transformation matrix
00146  */
00147 class HomXform
00148 {
00149 
00150   private:
00151     //! the matrix; don't bother storing the last column, since we assume for now it's
00152     //! always unused
00153     int xForm[16];
00154 
00155   public:
00156     friend class HomCoord;
00157 
00158     static MOAB_EXPORT HomXform IDENTITY;
00159 
00160     //! constructor from matrix
00161     HomXform( const int matrix[16] );
00162 
00163     //! bare constructor
00164     HomXform();
00165 
00166     //! constructor from rotation, scaling, translation
00167     HomXform( const int rotate[9], const int scale[3], const int translate[3] );
00168 
00169     //! constructor taking 16 ints, useful for efficient operators
00170     HomXform( int i1, int i2, int i3, int i4, int i5, int i6, int i7, int i8, int i9, int i10, int i11, int i12,
00171               int i13, int i14, int i15, int i16 );
00172 
00173     //! return this.inverse
00174     inline HomXform inverse() const;
00175 
00176     //! compute a transform from three points
00177     void three_pt_xform( const HomCoord& p1, const HomCoord& q1, const HomCoord& p2, const HomCoord& q2,
00178                          const HomCoord& p3, const HomCoord& q3 );
00179 
00180     //! operators
00181     int operator[]( const int& count ) const;
00182     int& operator[]( const int& count );
00183     bool operator==( const HomXform& rhs ) const;
00184     bool operator!=( const HomXform& rhs ) const;
00185 
00186     HomXform& operator=( const HomXform& rhs );
00187     HomXform& operator*=( const HomXform& rhs );
00188     HomXform operator*( const HomXform& rhs2 ) const;
00189 };
00190 
00191 inline HomCoord::HomCoord()
00192 {
00193     homCoord[0] = 0;
00194     homCoord[1] = 0;
00195     homCoord[2] = 0;
00196     homCoord[3] = 0;
00197 }
00198 
00199 inline HomCoord::HomCoord( const int coords[], const int num_coords )
00200 {
00201     for( int tmpj = 0; tmpj < num_coords; tmpj++ )
00202         homCoord[tmpj] = coords[tmpj];
00203     if( num_coords != 4 ) homCoord[3] = 1;
00204 }
00205 
00206 inline HomCoord::HomCoord( const int coord0, const int coord1, const int coord2, const int coord3 )
00207 {
00208     homCoord[0] = coord0;
00209     homCoord[1] = coord1;
00210     homCoord[2] = coord2;
00211     homCoord[3] = coord3;
00212 }
00213 
00214 inline HomCoord::HomCoord( const int coord0, const int coord1, const int coord2 )
00215 {
00216     homCoord[0] = coord0;
00217     homCoord[1] = coord1;
00218     homCoord[2] = coord2;
00219     homCoord[3] = 1;
00220 }
00221 
00222 inline HomCoord::HomCoord( const HomCoord& coords )
00223 {
00224 #if defined( __INTEL_COMPILER ) && ( __INTEL_COMPILER < 1310 )
00225     // Hack Intel compiler 12 issues with -O2 optimization
00226     int coord0  = coords[0];
00227     int coord1  = coords[1];
00228     int coord2  = coords[2];
00229     int coord3  = coords[3];
00230     homCoord[0] = coord0;
00231     homCoord[1] = coord1;
00232     homCoord[2] = coord2;
00233     homCoord[3] = coord3;
00234 #else
00235     homCoord[0] = coords[0];
00236     homCoord[1] = coords[1];
00237     homCoord[2] = coords[2];
00238     homCoord[3] = coords[3];
00239 #endif
00240 }
00241 
00242 inline void HomCoord::set( const int coords[] )
00243 {
00244     homCoord[0] = coords[0];
00245     homCoord[1] = coords[1];
00246     homCoord[2] = coords[2];
00247     homCoord[3] = coords[3];
00248 }
00249 
00250 inline void HomCoord::set( const int ip, const int jp, const int kp, const int hp )
00251 {
00252     homCoord[0] = ip;
00253     homCoord[1] = jp;
00254     homCoord[2] = kp;
00255     homCoord[3] = hp;
00256 }
00257 
00258 inline HomCoord& HomCoord::operator=( const HomCoord& rhs1 )
00259 {
00260     homCoord[0] = rhs1.homCoord[0];
00261     homCoord[1] = rhs1.homCoord[1];
00262     homCoord[2] = rhs1.homCoord[2];
00263     homCoord[3] = rhs1.homCoord[3];
00264     return *this;
00265 }
00266 
00267 //! squared length
00268 inline int HomCoord::length_squared() const
00269 {
00270     return homCoord[0] * homCoord[0] + homCoord[1] * homCoord[1] + homCoord[2] * homCoord[2];
00271 }
00272 
00273 //! length
00274 inline int HomCoord::length() const
00275 {
00276     return (int)std::sqrt( (float)length_squared() );
00277 }
00278 
00279 //! normalize
00280 inline void HomCoord::normalize()
00281 {
00282     *this /= length();
00283 }
00284 
00285 // dot product
00286 inline int HomCoord::operator%( const HomCoord& rhs ) const
00287 {
00288     return homCoord[0] * rhs.homCoord[0] + homCoord[1] * rhs.homCoord[1] + homCoord[2] * rhs.homCoord[2];
00289 }
00290 
00291 // cross product
00292 inline HomCoord HomCoord::operator*( const HomCoord& rhs ) const
00293 {
00294     return HomCoord( homCoord[1] * rhs.homCoord[2] - homCoord[2] * rhs.homCoord[1],
00295                      homCoord[2] * rhs.homCoord[0] - homCoord[0] * rhs.homCoord[2],
00296                      homCoord[0] * rhs.homCoord[1] - homCoord[1] * rhs.homCoord[0] );
00297 }
00298 
00299 inline HomCoord& HomCoord::operator*=( const HomCoord& rhs )
00300 {
00301     *this = HomCoord( homCoord[1] * rhs.homCoord[2] - homCoord[2] * rhs.homCoord[1],
00302                       homCoord[2] * rhs.homCoord[0] - homCoord[0] * rhs.homCoord[2],
00303                       homCoord[0] * rhs.homCoord[1] - homCoord[1] * rhs.homCoord[0] );
00304 
00305     return *this;
00306 }
00307 
00308 inline bool HomCoord::operator==( const HomCoord& rhs1 ) const
00309 {
00310     return ( homCoord[0] == rhs1.homCoord[0] && homCoord[1] == rhs1.homCoord[1] && homCoord[2] == rhs1.homCoord[2] &&
00311              homCoord[3] == rhs1.homCoord[3] );
00312 }
00313 
00314 inline bool HomCoord::operator!=( const HomCoord& rhs1 ) const
00315 {
00316     return ( homCoord[0] != rhs1.homCoord[0] || homCoord[1] != rhs1.homCoord[1] || homCoord[2] != rhs1.homCoord[2] ||
00317              homCoord[3] != rhs1.homCoord[3] );
00318 }
00319 
00320 inline bool HomCoord::operator>=( const HomCoord& rhs1 ) const
00321 {
00322     return ( homCoord[0] >= rhs1.homCoord[0] && homCoord[1] >= rhs1.homCoord[1] && homCoord[2] >= rhs1.homCoord[2] &&
00323              homCoord[3] == rhs1.homCoord[3] );
00324 }
00325 
00326 inline bool HomCoord::operator<=( const HomCoord& rhs1 ) const
00327 {
00328     return ( homCoord[0] <= rhs1.homCoord[0] && homCoord[1] <= rhs1.homCoord[1] && homCoord[2] <= rhs1.homCoord[2] &&
00329              homCoord[3] == rhs1.homCoord[3] );
00330 }
00331 
00332 inline bool HomCoord::operator<( const HomCoord& rhs1 ) const
00333 {
00334     return ( homCoord[0] < rhs1.homCoord[0] && homCoord[1] < rhs1.homCoord[1] && homCoord[2] < rhs1.homCoord[2] &&
00335              homCoord[3] == rhs1.homCoord[3] );
00336 }
00337 
00338 inline bool HomCoord::operator>( const HomCoord& rhs1 ) const
00339 {
00340     return ( homCoord[0] > rhs1.homCoord[0] && homCoord[1] > rhs1.homCoord[1] && homCoord[2] > rhs1.homCoord[2] &&
00341              homCoord[3] == rhs1.homCoord[3] );
00342 }
00343 
00344 inline HomCoord HomCoord::operator*( const HomXform& rhs2 ) const
00345 {
00346     return HomCoord(
00347         //    homCoord[0]*rhs2[4*0+0] + homCoord[1]*rhs2[4*1+0] +
00348         //    homCoord[2]*rhs2[4*2+0] + homCoord[3]*rhs2[4*3+0],
00349         homCoord[0] * rhs2.xForm[0] + homCoord[1] * rhs2.xForm[4] + homCoord[2] * rhs2.xForm[8] +
00350             homCoord[3] * rhs2.xForm[12],
00351 
00352         //    homCoord[0]*rhs2.xForm[4*0+1] + homCoord[1]*rhs2.xForm[4*1+1] +
00353         //    homCoord[2]*rhs2.xForm[4*2+1] + homCoord[3]*rhs2.xForm[4*3+1],
00354         homCoord[0] * rhs2.xForm[1] + homCoord[1] * rhs2.xForm[5] + homCoord[2] * rhs2.xForm[9] +
00355             homCoord[3] * rhs2.xForm[13],
00356 
00357         //    homCoord[0]*rhs2.xForm[4*0+2] + homCoord[1]*rhs2.xForm[4*1+2] +
00358         //    homCoord[2]*rhs2.xForm[4*2+2] + homCoord[3]*rhs2.xForm[4*3+2],
00359         homCoord[0] * rhs2.xForm[2] + homCoord[1] * rhs2.xForm[6] + homCoord[2] * rhs2.xForm[10] +
00360             homCoord[3] * rhs2.xForm[14],
00361 
00362         //    homCoord[0]*rhs2.xForm[4*0+3] + homCoord[1]*rhs2.xForm[4*1+3] +
00363         //    homCoord[2]*rhs2.xForm[4*2+3] + homCoord[3]*rhs2.xForm[4*3+3]
00364         homCoord[0] * rhs2.xForm[3] + homCoord[1] * rhs2.xForm[7] + homCoord[2] * rhs2.xForm[11] +
00365             homCoord[3] * rhs2.xForm[15] );
00366 }
00367 
00368 inline HomCoord& HomCoord::operator*=( const HomXform& rhs2 )
00369 {
00370     *this = HomCoord(
00371         //    homCoord[0]*rhs2.xForm[4*0+0] + homCoord[1]*rhs2.xForm[4*1+0] +
00372         //    homCoord[2]*rhs2.xForm[4*2+0] + homCoord[3]*rhs2.xForm[4*3+0],
00373         homCoord[0] * rhs2.xForm[0] + homCoord[1] * rhs2.xForm[4] + homCoord[2] * rhs2.xForm[8] +
00374             homCoord[3] * rhs2.xForm[12],
00375 
00376         //    homCoord[0]*rhs2.xForm[4*0+1] + homCoord[1]*rhs2.xForm[4*1+1] +
00377         //    homCoord[2]*rhs2.xForm[4*2+1] + homCoord[3]*rhs2.xForm[4*3+1],
00378         homCoord[0] * rhs2.xForm[1] + homCoord[1] * rhs2.xForm[5] + homCoord[2] * rhs2.xForm[9] +
00379             homCoord[3] * rhs2.xForm[13],
00380 
00381         //    homCoord[0]*rhs2.xForm[4*0+2] + homCoord[1]*rhs2.xForm[4*1+2] +
00382         //    homCoord[2]*rhs2.xForm[4*2+2] + homCoord[3]*rhs2.xForm[4*3+2],
00383         homCoord[0] * rhs2.xForm[2] + homCoord[1] * rhs2.xForm[6] + homCoord[2] * rhs2.xForm[10] +
00384             homCoord[3] * rhs2.xForm[14],
00385 
00386         //    homCoord[0]*rhs2.xForm[4*0+3] + homCoord[1]*rhs2.xForm[4*1+3] +
00387         //    homCoord[2]*rhs2.xForm[4*2+3] + homCoord[3]*rhs2.xForm[4*3+3]
00388         homCoord[0] * rhs2.xForm[3] + homCoord[1] * rhs2.xForm[7] + homCoord[2] * rhs2.xForm[11] +
00389             homCoord[3] * rhs2.xForm[15] );
00390     return *this;
00391 }
00392 
00393 inline HomCoord HomCoord::operator*( const int mult ) const
00394 {
00395     return HomCoord( mult * homCoord[0], mult * homCoord[1], mult * homCoord[2] );
00396 }
00397 
00398 inline HomCoord& HomCoord::operator*=( const int mult )
00399 {
00400     homCoord[0] *= mult;
00401     homCoord[1] *= mult;
00402     homCoord[2] *= mult;
00403     return *this;
00404 }
00405 
00406 inline HomCoord HomCoord::operator/( const int div ) const
00407 {
00408     return HomCoord( homCoord[0] / div, homCoord[1] / div, homCoord[2] / div );
00409 }
00410 
00411 inline HomCoord& HomCoord::operator/=( const int div )
00412 {
00413     homCoord[0] /= div;
00414     homCoord[1] /= div;
00415     homCoord[2] /= div;
00416     return *this;
00417 }
00418 
00419 inline HomCoord HomCoord::operator-( const HomCoord& rhs2 ) const
00420 {
00421     return HomCoord( *this ) -= rhs2;
00422 }
00423 
00424 inline HomCoord& HomCoord::operator-=( const HomCoord& rhs2 )
00425 {
00426     homCoord[0] -= rhs2[0];
00427     homCoord[1] -= rhs2[1];
00428     homCoord[2] -= rhs2[2];
00429     return *this;
00430 }
00431 
00432 inline HomCoord HomCoord::operator+( const HomCoord& rhs2 ) const
00433 {
00434     return HomCoord( *this ) += rhs2;
00435 }
00436 
00437 inline HomCoord& HomCoord::operator+=( const HomCoord& rhs2 )
00438 {
00439     homCoord[0] += rhs2[0];
00440     homCoord[1] += rhs2[1];
00441     homCoord[2] += rhs2[2];
00442     return *this;
00443 }
00444 
00445 inline HomCoord HomCoord::operator/( const HomXform& rhs2 ) const
00446 {
00447     return HomCoord( *this ) /= rhs2;
00448 }
00449 
00450 inline HomCoord& HomCoord::operator/=( const HomXform& rhs2 )
00451 {
00452     HomXform inv = rhs2.inverse();
00453     *this *= inv;
00454     return *this;
00455 }
00456 
00457 inline int HomCoord::operator[]( const int& param ) const
00458 {
00459     return homCoord[param];
00460 }
00461 
00462 inline int& HomCoord::operator[]( const int& param )
00463 {
00464     return homCoord[param];
00465 }
00466 
00467 inline std::ostream& operator<<( std::ostream& str, const HomCoord& hc )
00468 {
00469     str << "(" << hc.i() << "," << hc.j() << "," << hc.k() << ")";
00470     return str;
00471 }
00472 
00473 inline HomXform::HomXform( const int matrix[16] )
00474 {
00475     for( int i = 0; i < 16; i++ )
00476         xForm[i] = matrix[i];
00477 }
00478 
00479 inline HomXform::HomXform() {}
00480 
00481 inline HomXform::HomXform( const int rotate[9], const int scale[3], const int translate[3] )
00482 {
00483     int i, j;
00484     for( i = 0; i < 3; i++ )
00485     {
00486         for( j = 0; j < 3; j++ )
00487             xForm[i * 4 + j] = rotate[i * 3 + j] * scale[j];
00488 
00489         xForm[12 + i] = translate[i];
00490     }
00491     xForm[3]  = 0;
00492     xForm[7]  = 0;
00493     xForm[11] = 0;
00494     xForm[15] = 1;
00495 }
00496 
00497 inline HomXform::HomXform( int i1, int i2, int i3, int i4, int i5, int i6, int i7, int i8, int i9, int i10, int i11,
00498                            int i12, int i13, int i14, int i15, int i16 )
00499 {
00500     xForm[0]  = i1;
00501     xForm[1]  = i2;
00502     xForm[2]  = i3;
00503     xForm[3]  = i4;
00504     xForm[4]  = i5;
00505     xForm[5]  = i6;
00506     xForm[6]  = i7;
00507     xForm[7]  = i8;
00508     xForm[8]  = i9;
00509     xForm[9]  = i10;
00510     xForm[10] = i11;
00511     xForm[11] = i12;
00512     xForm[12] = i13;
00513     xForm[13] = i14;
00514     xForm[14] = i15;
00515     xForm[15] = i16;
00516 }
00517 
00518 inline HomXform& HomXform::operator=( const HomXform& rhs )
00519 {
00520     for( int i = 0; i < 16; i++ )
00521         xForm[i] = rhs.xForm[i];
00522 
00523     return *this;
00524 }
00525 
00526 inline HomXform HomXform::operator*( const HomXform& rhs2 ) const
00527 {
00528     return HomXform(
00529         //  temp.XFORM(0,0)
00530         XFORM( 0, 0 ) * rhs2.XFORM( 0, 0 ) + XFORM( 0, 1 ) * rhs2.XFORM( 1, 0 ) + XFORM( 0, 2 ) * rhs2.XFORM( 2, 0 ) +
00531             XFORM( 0, 3 ) * rhs2.XFORM( 3, 0 ),
00532         //  temp.XFORM(0,1)
00533         XFORM( 0, 0 ) * rhs2.XFORM( 0, 1 ) + XFORM( 0, 1 ) * rhs2.XFORM( 1, 1 ) + XFORM( 0, 2 ) * rhs2.XFORM( 2, 1 ) +
00534             XFORM( 0, 3 ) * rhs2.XFORM( 3, 1 ),
00535         //  temp.XFORM(0,2)
00536         XFORM( 0, 0 ) * rhs2.XFORM( 0, 2 ) + XFORM( 0, 1 ) * rhs2.XFORM( 1, 2 ) + XFORM( 0, 2 ) * rhs2.XFORM( 2, 2 ) +
00537             XFORM( 0, 3 ) * rhs2.XFORM( 3, 2 ),
00538         //  temp.XFORM(0,3)
00539         XFORM( 0, 0 ) * rhs2.XFORM( 0, 3 ) + XFORM( 0, 1 ) * rhs2.XFORM( 1, 3 ) + XFORM( 0, 2 ) * rhs2.XFORM( 2, 3 ) +
00540             XFORM( 0, 3 ) * rhs2.XFORM( 3, 3 ),
00541 
00542         //  temp.XFORM(1,0)
00543         XFORM( 1, 0 ) * rhs2.XFORM( 0, 0 ) + XFORM( 1, 1 ) * rhs2.XFORM( 1, 0 ) + XFORM( 1, 2 ) * rhs2.XFORM( 2, 0 ) +
00544             XFORM( 1, 3 ) * rhs2.XFORM( 3, 0 ),
00545         //  temp.XFORM(1,1)
00546         XFORM( 1, 0 ) * rhs2.XFORM( 0, 1 ) + XFORM( 1, 1 ) * rhs2.XFORM( 1, 1 ) + XFORM( 1, 2 ) * rhs2.XFORM( 2, 1 ) +
00547             XFORM( 1, 3 ) * rhs2.XFORM( 3, 1 ),
00548         //  temp.XFORM(1,2)
00549         XFORM( 1, 0 ) * rhs2.XFORM( 0, 2 ) + XFORM( 1, 1 ) * rhs2.XFORM( 1, 2 ) + XFORM( 1, 2 ) * rhs2.XFORM( 2, 2 ) +
00550             XFORM( 1, 3 ) * rhs2.XFORM( 3, 2 ),
00551         //  temp.XFORM(1,3)
00552         XFORM( 1, 0 ) * rhs2.XFORM( 0, 3 ) + XFORM( 1, 1 ) * rhs2.XFORM( 1, 3 ) + XFORM( 1, 2 ) * rhs2.XFORM( 2, 3 ) +
00553             XFORM( 1, 3 ) * rhs2.XFORM( 3, 3 ),
00554 
00555         //  temp.XFORM(2,0)
00556         XFORM( 2, 0 ) * rhs2.XFORM( 0, 0 ) + XFORM( 2, 1 ) * rhs2.XFORM( 1, 0 ) + XFORM( 2, 2 ) * rhs2.XFORM( 2, 0 ) +
00557             XFORM( 2, 3 ) * rhs2.XFORM( 3, 0 ),
00558         //  temp.XFORM(2,1)
00559         XFORM( 2, 0 ) * rhs2.XFORM( 0, 1 ) + XFORM( 2, 1 ) * rhs2.XFORM( 1, 1 ) + XFORM( 2, 2 ) * rhs2.XFORM( 2, 1 ) +
00560             XFORM( 2, 3 ) * rhs2.XFORM( 3, 1 ),
00561         //  temp.XFORM(2,2)
00562         XFORM( 2, 0 ) * rhs2.XFORM( 0, 2 ) + XFORM( 2, 1 ) * rhs2.XFORM( 1, 2 ) + XFORM( 2, 2 ) * rhs2.XFORM( 2, 2 ) +
00563             XFORM( 2, 3 ) * rhs2.XFORM( 3, 2 ),
00564         //  temp.XFORM(2,3)
00565         XFORM( 2, 0 ) * rhs2.XFORM( 0, 3 ) + XFORM( 2, 1 ) * rhs2.XFORM( 1, 3 ) + XFORM( 2, 2 ) * rhs2.XFORM( 2, 3 ) +
00566             XFORM( 2, 3 ) * rhs2.XFORM( 3, 3 ),
00567 
00568         //  temp.XFORM(3,0)
00569         //  xForm[12]*rhs2.xForm[0] + xForm[13]*rhs2.xForm[4] + xForm[14]*rhs2.xForm[8] +
00570         //  xForm[15]*rhs2.xForm[12]
00571         XFORM( 3, 0 ) * rhs2.XFORM( 0, 0 ) + XFORM( 3, 1 ) * rhs2.XFORM( 1, 0 ) + XFORM( 3, 2 ) * rhs2.XFORM( 2, 0 ) +
00572             XFORM( 3, 3 ) * rhs2.XFORM( 3, 0 ),
00573         //  temp.XFORM(3,1)
00574         //  xForm[12]*rhs2.xForm[1] + xForm[13]*rhs2.xForm[5] + xForm[14]*rhs2.xForm[9] +
00575         //  xForm[15]*rhs2.xForm[13]
00576         XFORM( 3, 0 ) * rhs2.XFORM( 0, 1 ) + XFORM( 3, 1 ) * rhs2.XFORM( 1, 1 ) + XFORM( 3, 2 ) * rhs2.XFORM( 2, 1 ) +
00577             XFORM( 3, 3 ) * rhs2.XFORM( 3, 1 ),
00578         //  temp.XFORM(3,2)
00579         //  xForm[12]*rhs2.xForm[2] + xForm[13]*rhs2.xForm[6] + xForm[14]*rhs2.xForm[10] +
00580         //  xForm[15]*rhs2.xForm[14]
00581         XFORM( 3, 0 ) * rhs2.XFORM( 0, 2 ) + XFORM( 3, 1 ) * rhs2.XFORM( 1, 2 ) + XFORM( 3, 2 ) * rhs2.XFORM( 2, 2 ) +
00582             XFORM( 3, 3 ) * rhs2.XFORM( 3, 2 ),
00583         //  temp.XFORM(3,3)
00584         //  xForm[12]*rhs2.xForm[3] + xForm[13]*rhs2.xForm[7] + xForm[14]*rhs2.xForm[11] +
00585         //  xForm[15]*rhs2.xForm[15]
00586         XFORM( 3, 0 ) * rhs2.XFORM( 0, 3 ) + XFORM( 3, 1 ) * rhs2.XFORM( 1, 3 ) + XFORM( 3, 2 ) * rhs2.XFORM( 2, 3 ) +
00587             XFORM( 3, 3 ) * rhs2.XFORM( 3, 3 ) );
00588 }
00589 
00590 inline HomXform& HomXform::operator*=( const HomXform& rhs2 )
00591 {
00592     *this = HomXform(
00593         //  temp.XFORM(0,0)
00594         XFORM( 0, 0 ) * rhs2.XFORM( 0, 0 ) + XFORM( 0, 1 ) * rhs2.XFORM( 1, 0 ) + XFORM( 0, 2 ) * rhs2.XFORM( 2, 0 ) +
00595             XFORM( 0, 3 ) * rhs2.XFORM( 3, 0 ),
00596         //  temp.XFORM(0,1)
00597         XFORM( 0, 0 ) * rhs2.XFORM( 0, 1 ) + XFORM( 0, 1 ) * rhs2.XFORM( 1, 1 ) + XFORM( 0, 2 ) * rhs2.XFORM( 2, 1 ) +
00598             XFORM( 0, 3 ) * rhs2.XFORM( 3, 1 ),
00599         //  temp.XFORM(0,2)
00600         XFORM( 0, 0 ) * rhs2.XFORM( 0, 2 ) + XFORM( 0, 1 ) * rhs2.XFORM( 1, 2 ) + XFORM( 0, 2 ) * rhs2.XFORM( 2, 2 ) +
00601             XFORM( 0, 3 ) * rhs2.XFORM( 3, 2 ),
00602         //  temp.XFORM(0,3)
00603         XFORM( 0, 0 ) * rhs2.XFORM( 0, 3 ) + XFORM( 0, 1 ) * rhs2.XFORM( 1, 3 ) + XFORM( 0, 2 ) * rhs2.XFORM( 2, 3 ) +
00604             XFORM( 0, 3 ) * rhs2.XFORM( 3, 3 ),
00605 
00606         //  temp.XFORM(1,0)
00607         XFORM( 1, 0 ) * rhs2.XFORM( 0, 0 ) + XFORM( 1, 1 ) * rhs2.XFORM( 1, 0 ) + XFORM( 1, 2 ) * rhs2.XFORM( 2, 0 ) +
00608             XFORM( 1, 3 ) * rhs2.XFORM( 3, 0 ),
00609         //  temp.XFORM(1,1)
00610         XFORM( 1, 0 ) * rhs2.XFORM( 0, 1 ) + XFORM( 1, 1 ) * rhs2.XFORM( 1, 1 ) + XFORM( 1, 2 ) * rhs2.XFORM( 2, 1 ) +
00611             XFORM( 1, 3 ) * rhs2.XFORM( 3, 1 ),
00612         //  temp.XFORM(1,2)
00613         XFORM( 1, 0 ) * rhs2.XFORM( 0, 2 ) + XFORM( 1, 1 ) * rhs2.XFORM( 1, 2 ) + XFORM( 1, 2 ) * rhs2.XFORM( 2, 2 ) +
00614             XFORM( 1, 3 ) * rhs2.XFORM( 3, 2 ),
00615         //  temp.XFORM(1,3)
00616         XFORM( 1, 0 ) * rhs2.XFORM( 0, 3 ) + XFORM( 1, 1 ) * rhs2.XFORM( 1, 3 ) + XFORM( 1, 2 ) * rhs2.XFORM( 2, 3 ) +
00617             XFORM( 1, 3 ) * rhs2.XFORM( 3, 3 ),
00618 
00619         //  temp.XFORM(2,0)
00620         XFORM( 2, 0 ) * rhs2.XFORM( 0, 0 ) + XFORM( 2, 1 ) * rhs2.XFORM( 1, 0 ) + XFORM( 2, 2 ) * rhs2.XFORM( 2, 0 ) +
00621             XFORM( 2, 3 ) * rhs2.XFORM( 3, 0 ),
00622         //  temp.XFORM(2,1)
00623         XFORM( 2, 0 ) * rhs2.XFORM( 0, 1 ) + XFORM( 2, 1 ) * rhs2.XFORM( 1, 1 ) + XFORM( 2, 2 ) * rhs2.XFORM( 2, 1 ) +
00624             XFORM( 2, 3 ) * rhs2.XFORM( 3, 1 ),
00625         //  temp.XFORM(2,2)
00626         XFORM( 2, 0 ) * rhs2.XFORM( 0, 2 ) + XFORM( 2, 1 ) * rhs2.XFORM( 1, 2 ) + XFORM( 2, 2 ) * rhs2.XFORM( 2, 2 ) +
00627             XFORM( 2, 3 ) * rhs2.XFORM( 3, 2 ),
00628         //  temp.XFORM(2,3)
00629         XFORM( 2, 0 ) * rhs2.XFORM( 0, 3 ) + XFORM( 2, 1 ) * rhs2.XFORM( 1, 3 ) + XFORM( 2, 2 ) * rhs2.XFORM( 2, 3 ) +
00630             XFORM( 2, 3 ) * rhs2.XFORM( 3, 3 ),
00631 
00632         //  temp.XFORM(3,0)
00633         XFORM( 3, 0 ) * rhs2.XFORM( 0, 0 ) + XFORM( 3, 1 ) * rhs2.XFORM( 1, 0 ) + XFORM( 3, 2 ) * rhs2.XFORM( 2, 0 ) +
00634             XFORM( 3, 3 ) * rhs2.XFORM( 3, 0 ),
00635         //  temp.XFORM(3,1)
00636         XFORM( 3, 0 ) * rhs2.XFORM( 0, 1 ) + XFORM( 3, 1 ) * rhs2.XFORM( 1, 1 ) + XFORM( 3, 2 ) * rhs2.XFORM( 2, 1 ) +
00637             XFORM( 3, 3 ) * rhs2.XFORM( 3, 1 ),
00638         //  temp.XFORM(3,2)
00639         XFORM( 3, 0 ) * rhs2.XFORM( 0, 2 ) + XFORM( 3, 1 ) * rhs2.XFORM( 1, 2 ) + XFORM( 3, 2 ) * rhs2.XFORM( 2, 2 ) +
00640             XFORM( 3, 3 ) * rhs2.XFORM( 3, 2 ),
00641         //  temp.XFORM(3,3)
00642         XFORM( 3, 0 ) * rhs2.XFORM( 0, 3 ) + XFORM( 3, 1 ) * rhs2.XFORM( 1, 3 ) + XFORM( 3, 2 ) * rhs2.XFORM( 2, 3 ) +
00643             XFORM( 3, 3 ) * rhs2.XFORM( 3, 3 ) );
00644 
00645     return *this;
00646 }
00647 
00648 inline int HomXform::operator[]( const int& count ) const
00649 {
00650     return xForm[count];
00651 }
00652 
00653 inline int& HomXform::operator[]( const int& count )
00654 {
00655     return xForm[count];
00656 }
00657 
00658 inline bool HomXform::operator==( const HomXform& rhs ) const
00659 {
00660     return ( xForm[0] == rhs.xForm[0] && xForm[1] == rhs.xForm[1] && xForm[2] == rhs.xForm[2] &&
00661              xForm[3] == rhs.xForm[3] && xForm[4] == rhs.xForm[4] && xForm[5] == rhs.xForm[5] &&
00662              xForm[6] == rhs.xForm[6] && xForm[7] == rhs.xForm[7] && xForm[8] == rhs.xForm[8] &&
00663              xForm[9] == rhs.xForm[9] && xForm[10] == rhs.xForm[10] && xForm[11] == rhs.xForm[11] &&
00664              xForm[12] == rhs.xForm[12] && xForm[13] == rhs.xForm[13] && xForm[14] == rhs.xForm[14] &&
00665              xForm[15] == rhs.xForm[15] );
00666 }
00667 
00668 inline bool HomXform::operator!=( const HomXform& rhs ) const
00669 {
00670     return ( xForm[0] != rhs.xForm[0] || xForm[1] != rhs.xForm[1] || xForm[2] != rhs.xForm[2] ||
00671              xForm[3] != rhs.xForm[3] || xForm[4] != rhs.xForm[4] || xForm[5] != rhs.xForm[5] ||
00672              xForm[6] != rhs.xForm[6] || xForm[7] != rhs.xForm[7] || xForm[8] != rhs.xForm[8] ||
00673              xForm[9] != rhs.xForm[9] || xForm[10] != rhs.xForm[10] || xForm[11] != rhs.xForm[11] ||
00674              xForm[12] != rhs.xForm[12] || xForm[13] != rhs.xForm[13] || xForm[14] != rhs.xForm[14] ||
00675              xForm[15] != rhs.xForm[15] );
00676 }
00677 
00678 inline HomXform HomXform::inverse() const
00679 {
00680 
00681     /*
00682     // original code:
00683 
00684       HomXform tmp;
00685 
00686         // assign the diagonal
00687       tmp[0] = xForm[0];
00688       tmp[5] = xForm[5];
00689       tmp[10] = xForm[10];
00690       tmp[15] = xForm[15];
00691 
00692         // invert the rotation matrix
00693       tmp[XFORM_INDEX(0,1)] = XFORM(1,0);
00694       tmp[XFORM_INDEX(0,2)] = XFORM(2,0);
00695       tmp[XFORM_INDEX(1,0)] = XFORM(0,1);
00696       tmp[XFORM_INDEX(1,2)] = XFORM(2,1);
00697       tmp[XFORM_INDEX(2,0)] = XFORM(0,2);
00698       tmp[XFORM_INDEX(2,1)] = XFORM(1,2);
00699 
00700         // negative translate * Rinv
00701       tmp[XFORM_INDEX(3,0)] = -(XFORM(3,0)*tmp.XFORM(0,0) + XFORM(3,1)*tmp.XFORM(1,0) +
00702     XFORM(3,2)*tmp.XFORM(2,0)); tmp[XFORM_INDEX(3,1)] = -(XFORM(3,0)*tmp.XFORM(0,1) +
00703     XFORM(3,1)*tmp.XFORM(1,1) + XFORM(3,2)*tmp.XFORM(2,1)); tmp[XFORM_INDEX(3,2)] =
00704     -(XFORM(3,0)*tmp.XFORM(0,2) + XFORM(3,1)*tmp.XFORM(1,2) + XFORM(3,2)*tmp.XFORM(2,2));
00705 
00706         // zero last column
00707       tmp[XFORM_INDEX(0,3)] = 0;
00708       tmp[XFORM_INDEX(1,3)] = 0;
00709       tmp[XFORM_INDEX(2,3)] = 0;
00710 
00711         // h factor
00712       tmp[XFORM_INDEX(3,3)] = 1;
00713 
00714       return tmp;
00715     */
00716 
00717     // more efficient, but somewhat confusing (remember, column-major):
00718 
00719     return HomXform(
00720         // row 0
00721         xForm[0], XFORM( 1, 0 ), XFORM( 2, 0 ), 0,
00722         // row 1
00723         XFORM( 0, 1 ), xForm[5], XFORM( 2, 1 ), 0,
00724         // row 2
00725         XFORM( 0, 2 ), XFORM( 1, 2 ), xForm[10], 0,
00726         // row 3
00727         -( XFORM( 3, 0 ) * xForm[0] + XFORM( 3, 1 ) * XFORM( 0, 1 ) + XFORM( 3, 2 ) * XFORM( 0, 2 ) ),
00728         -( XFORM( 3, 0 ) * XFORM( 1, 0 ) + XFORM( 3, 1 ) * xForm[5] + XFORM( 3, 2 ) * XFORM( 1, 2 ) ),
00729         -( XFORM( 3, 0 ) * XFORM( 2, 0 ) + XFORM( 3, 1 ) * XFORM( 2, 1 ) + XFORM( 3, 2 ) * xForm[10] ), 1 );
00730 }
00731 
00732 }  // namespace moab
00733 
00734 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines