MOAB: Mesh Oriented datABase  (version 5.4.1)
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
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,
00171               int i2,
00172               int i3,
00173               int i4,
00174               int i5,
00175               int i6,
00176               int i7,
00177               int i8,
00178               int i9,
00179               int i10,
00180               int i11,
00181               int i12,
00182               int i13,
00183               int i14,
00184               int i15,
00185               int i16 );
00186
00187     //! copy constructor
00188     HomXform( HomXform const& from )
00189     {
00190         std::copy( from.xForm, from.xForm + 16, xForm );
00191     }
00192
00193     //! return this.inverse
00194     inline HomXform inverse() const;
00195
00196     //! compute a transform from three points
00197     void three_pt_xform( const HomCoord& p1,
00198                          const HomCoord& q1,
00199                          const HomCoord& p2,
00200                          const HomCoord& q2,
00201                          const HomCoord& p3,
00202                          const HomCoord& q3 );
00203
00204     //! operators
00205     int operator[]( const int& count ) const;
00206     int& operator[]( const int& count );
00207     bool operator==( const HomXform& rhs ) const;
00208     bool operator!=( const HomXform& rhs ) const;
00209
00210     HomXform& operator=( const HomXform& rhs );
00211     HomXform& operator*=( const HomXform& rhs );
00212     HomXform operator*( const HomXform& rhs2 ) const;
00213 };
00214
00215 inline HomCoord::HomCoord()
00216 {
00217     homCoord[0] = 0;
00218     homCoord[1] = 0;
00219     homCoord[2] = 0;
00220     homCoord[3] = 0;
00221 }
00222
00223 inline HomCoord::HomCoord( const int coords[], const int num_coords )
00224 {
00225     for( int tmpj = 0; tmpj < num_coords; tmpj++ )
00226         homCoord[tmpj] = coords[tmpj];
00227     if( num_coords != 4 ) homCoord[3] = 1;
00228 }
00229
00230 inline HomCoord::HomCoord( const int coord0, const int coord1, const int coord2, const int coord3 )
00231 {
00232     homCoord[0] = coord0;
00233     homCoord[1] = coord1;
00234     homCoord[2] = coord2;
00235     homCoord[3] = coord3;
00236 }
00237
00238 inline HomCoord::HomCoord( const int coord0, const int coord1, const int coord2 )
00239 {
00240     homCoord[0] = coord0;
00241     homCoord[1] = coord1;
00242     homCoord[2] = coord2;
00243     homCoord[3] = 1;
00244 }
00245
00246 inline HomCoord::HomCoord( const HomCoord& coords )
00247 {
00248 #if defined( __INTEL_COMPILER ) && ( __INTEL_COMPILER < 1310 )
00249     // Hack Intel compiler 12 issues with -O2 optimization
00250     int coord0  = coords[0];
00251     int coord1  = coords[1];
00252     int coord2  = coords[2];
00253     int coord3  = coords[3];
00254     homCoord[0] = coord0;
00255     homCoord[1] = coord1;
00256     homCoord[2] = coord2;
00257     homCoord[3] = coord3;
00258 #else
00259     homCoord[0] = coords[0];
00260     homCoord[1] = coords[1];
00261     homCoord[2] = coords[2];
00262     homCoord[3] = coords[3];
00263 #endif
00264 }
00265
00266 inline void HomCoord::set( const int coords[] )
00267 {
00268     homCoord[0] = coords[0];
00269     homCoord[1] = coords[1];
00270     homCoord[2] = coords[2];
00271     homCoord[3] = coords[3];
00272 }
00273
00274 inline void HomCoord::set( const int ip, const int jp, const int kp, const int hp )
00275 {
00276     homCoord[0] = ip;
00277     homCoord[1] = jp;
00278     homCoord[2] = kp;
00279     homCoord[3] = hp;
00280 }
00281
00282 inline HomCoord& HomCoord::operator=( const HomCoord& rhs1 )
00283 {
00284     homCoord[0] = rhs1.homCoord[0];
00285     homCoord[1] = rhs1.homCoord[1];
00286     homCoord[2] = rhs1.homCoord[2];
00287     homCoord[3] = rhs1.homCoord[3];
00288     return *this;
00289 }
00290
00291 //! squared length
00292 inline int HomCoord::length_squared() const
00293 {
00294     return homCoord[0] * homCoord[0] + homCoord[1] * homCoord[1] + homCoord[2] * homCoord[2];
00295 }
00296
00297 //! length
00298 inline int HomCoord::length() const
00299 {
00300     return (int)std::sqrt( (float)length_squared() );
00301 }
00302
00303 //! normalize
00304 inline void HomCoord::normalize()
00305 {
00306     *this /= length();
00307 }
00308
00309 // dot product
00310 inline int HomCoord::operator%( const HomCoord& rhs ) const
00311 {
00312     return homCoord[0] * rhs.homCoord[0] + homCoord[1] * rhs.homCoord[1] + homCoord[2] * rhs.homCoord[2];
00313 }
00314
00315 // cross product
00316 inline HomCoord HomCoord::operator*( const HomCoord& rhs ) const
00317 {
00318     return HomCoord( homCoord[1] * rhs.homCoord[2] - homCoord[2] * rhs.homCoord[1],
00319                      homCoord[2] * rhs.homCoord[0] - homCoord[0] * rhs.homCoord[2],
00320                      homCoord[0] * rhs.homCoord[1] - homCoord[1] * rhs.homCoord[0] );
00321 }
00322
00323 inline HomCoord& HomCoord::operator*=( const HomCoord& rhs )
00324 {
00325     *this = HomCoord( homCoord[1] * rhs.homCoord[2] - homCoord[2] * rhs.homCoord[1],
00326                       homCoord[2] * rhs.homCoord[0] - homCoord[0] * rhs.homCoord[2],
00327                       homCoord[0] * rhs.homCoord[1] - homCoord[1] * rhs.homCoord[0] );
00328
00329     return *this;
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 bool HomCoord::operator>=( const HomCoord& rhs1 ) const
00345 {
00346     return ( homCoord[0] >= rhs1.homCoord[0] && homCoord[1] >= rhs1.homCoord[1] && homCoord[2] >= rhs1.homCoord[2] &&
00347              homCoord[3] == rhs1.homCoord[3] );
00348 }
00349
00350 inline bool HomCoord::operator<=( const HomCoord& rhs1 ) const
00351 {
00352     return ( homCoord[0] <= rhs1.homCoord[0] && homCoord[1] <= rhs1.homCoord[1] && homCoord[2] <= rhs1.homCoord[2] &&
00353              homCoord[3] == rhs1.homCoord[3] );
00354 }
00355
00356 inline bool HomCoord::operator<( const HomCoord& rhs1 ) const
00357 {
00358     return ( homCoord[0] < rhs1.homCoord[0] && homCoord[1] < rhs1.homCoord[1] && homCoord[2] < rhs1.homCoord[2] &&
00359              homCoord[3] == rhs1.homCoord[3] );
00360 }
00361
00362 inline bool HomCoord::operator>( const HomCoord& rhs1 ) const
00363 {
00364     return ( homCoord[0] > rhs1.homCoord[0] && homCoord[1] > rhs1.homCoord[1] && homCoord[2] > rhs1.homCoord[2] &&
00365              homCoord[3] == rhs1.homCoord[3] );
00366 }
00367
00368 inline HomCoord HomCoord::operator*( const HomXform& rhs2 ) const
00369 {
00370     return HomCoord(
00371         //    homCoord[0]*rhs2[4*0+0] + homCoord[1]*rhs2[4*1+0] +
00372         //    homCoord[2]*rhs2[4*2+0] + homCoord[3]*rhs2[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 }
00391
00392 inline HomCoord& HomCoord::operator*=( const HomXform& rhs2 )
00393 {
00394     *this = HomCoord(
00395         //    homCoord[0]*rhs2.xForm[4*0+0] + homCoord[1]*rhs2.xForm[4*1+0] +
00396         //    homCoord[2]*rhs2.xForm[4*2+0] + homCoord[3]*rhs2.xForm[4*3+0],
00397         homCoord[0] * rhs2.xForm[0] + homCoord[1] * rhs2.xForm[4] + homCoord[2] * rhs2.xForm[8] +
00398             homCoord[3] * rhs2.xForm[12],
00399
00400         //    homCoord[0]*rhs2.xForm[4*0+1] + homCoord[1]*rhs2.xForm[4*1+1] +
00401         //    homCoord[2]*rhs2.xForm[4*2+1] + homCoord[3]*rhs2.xForm[4*3+1],
00402         homCoord[0] * rhs2.xForm[1] + homCoord[1] * rhs2.xForm[5] + homCoord[2] * rhs2.xForm[9] +
00403             homCoord[3] * rhs2.xForm[13],
00404
00405         //    homCoord[0]*rhs2.xForm[4*0+2] + homCoord[1]*rhs2.xForm[4*1+2] +
00406         //    homCoord[2]*rhs2.xForm[4*2+2] + homCoord[3]*rhs2.xForm[4*3+2],
00407         homCoord[0] * rhs2.xForm[2] + homCoord[1] * rhs2.xForm[6] + homCoord[2] * rhs2.xForm[10] +
00408             homCoord[3] * rhs2.xForm[14],
00409
00410         //    homCoord[0]*rhs2.xForm[4*0+3] + homCoord[1]*rhs2.xForm[4*1+3] +
00411         //    homCoord[2]*rhs2.xForm[4*2+3] + homCoord[3]*rhs2.xForm[4*3+3]
00412         homCoord[0] * rhs2.xForm[3] + homCoord[1] * rhs2.xForm[7] + homCoord[2] * rhs2.xForm[11] +
00413             homCoord[3] * rhs2.xForm[15] );
00414     return *this;
00415 }
00416
00417 inline HomCoord HomCoord::operator*( const int mult ) const
00418 {
00419     return HomCoord( mult * homCoord[0], mult * homCoord[1], mult * homCoord[2] );
00420 }
00421
00422 inline HomCoord& HomCoord::operator*=( const int mult )
00423 {
00424     homCoord[0] *= mult;
00425     homCoord[1] *= mult;
00426     homCoord[2] *= mult;
00427     return *this;
00428 }
00429
00430 inline HomCoord HomCoord::operator/( const int div ) const
00431 {
00432     return HomCoord( homCoord[0] / div, homCoord[1] / div, homCoord[2] / div );
00433 }
00434
00435 inline HomCoord& HomCoord::operator/=( const int div )
00436 {
00437     homCoord[0] /= div;
00438     homCoord[1] /= div;
00439     homCoord[2] /= div;
00440     return *this;
00441 }
00442
00443 inline HomCoord HomCoord::operator-( const HomCoord& rhs2 ) const
00444 {
00445     return HomCoord( *this ) -= rhs2;
00446 }
00447
00448 inline HomCoord& HomCoord::operator-=( const HomCoord& rhs2 )
00449 {
00450     homCoord[0] -= rhs2[0];
00451     homCoord[1] -= rhs2[1];
00452     homCoord[2] -= rhs2[2];
00453     return *this;
00454 }
00455
00456 inline HomCoord HomCoord::operator+( const HomCoord& rhs2 ) const
00457 {
00458     return HomCoord( *this ) += rhs2;
00459 }
00460
00461 inline HomCoord& HomCoord::operator+=( const HomCoord& rhs2 )
00462 {
00463     homCoord[0] += rhs2[0];
00464     homCoord[1] += rhs2[1];
00465     homCoord[2] += rhs2[2];
00466     return *this;
00467 }
00468
00469 inline HomCoord HomCoord::operator/( const HomXform& rhs2 ) const
00470 {
00471     return HomCoord( *this ) /= rhs2;
00472 }
00473
00474 inline HomCoord& HomCoord::operator/=( const HomXform& rhs2 )
00475 {
00476     HomXform inv = rhs2.inverse();
00477     *this *= inv;
00478     return *this;
00479 }
00480
00481 inline int HomCoord::operator[]( const int& param ) const
00482 {
00483     return homCoord[param];
00484 }
00485
00486 inline int& HomCoord::operator[]( const int& param )
00487 {
00488     return homCoord[param];
00489 }
00490
00491 inline std::ostream& operator<<( std::ostream& str, const HomCoord& hc )
00492 {
00493     str << "(" << hc.i() << "," << hc.j() << "," << hc.k() << ")";
00494     return str;
00495 }
00496
00497 inline HomXform::HomXform( const int matrix[16] )
00498 {
00499     for( int i = 0; i < 16; i++ )
00500         xForm[i] = matrix[i];
00501 }
00502
00503 inline HomXform::HomXform() {}
00504
00505 inline HomXform::HomXform( const int rotate[9], const int scale[3], const int translate[3] )
00506 {
00507     int i, j;
00508     for( i = 0; i < 3; i++ )
00509     {
00510         for( j = 0; j < 3; j++ )
00511             xForm[i * 4 + j] = rotate[i * 3 + j] * scale[j];
00512
00513         xForm[12 + i] = translate[i];
00514     }
00515     xForm[3]  = 0;
00516     xForm[7]  = 0;
00517     xForm[11] = 0;
00518     xForm[15] = 1;
00519 }
00520
00521 inline HomXform::HomXform( int i1,
00522                            int i2,
00523                            int i3,
00524                            int i4,
00525                            int i5,
00526                            int i6,
00527                            int i7,
00528                            int i8,
00529                            int i9,
00530                            int i10,
00531                            int i11,
00532                            int i12,
00533                            int i13,
00534                            int i14,
00535                            int i15,
00536                            int i16 )
00537 {
00538     xForm[0]  = i1;
00539     xForm[1]  = i2;
00540     xForm[2]  = i3;
00541     xForm[3]  = i4;
00542     xForm[4]  = i5;
00543     xForm[5]  = i6;
00544     xForm[6]  = i7;
00545     xForm[7]  = i8;
00546     xForm[8]  = i9;
00547     xForm[9]  = i10;
00548     xForm[10] = i11;
00549     xForm[11] = i12;
00550     xForm[12] = i13;
00551     xForm[13] = i14;
00552     xForm[14] = i15;
00553     xForm[15] = i16;
00554 }
00555
00556 inline HomXform& HomXform::operator=( const HomXform& rhs )
00557 {
00558     for( int i = 0; i < 16; i++ )
00559         xForm[i] = rhs.xForm[i];
00560
00561     return *this;
00562 }
00563
00564 inline HomXform HomXform::operator*( const HomXform& rhs2 ) const
00565 {
00566     return HomXform(
00567         //  temp.XFORM(0,0)
00568         XFORM( 0, 0 ) * rhs2.XFORM( 0, 0 ) + XFORM( 0, 1 ) * rhs2.XFORM( 1, 0 ) + XFORM( 0, 2 ) * rhs2.XFORM( 2, 0 ) +
00569             XFORM( 0, 3 ) * rhs2.XFORM( 3, 0 ),
00570         //  temp.XFORM(0,1)
00571         XFORM( 0, 0 ) * rhs2.XFORM( 0, 1 ) + XFORM( 0, 1 ) * rhs2.XFORM( 1, 1 ) + XFORM( 0, 2 ) * rhs2.XFORM( 2, 1 ) +
00572             XFORM( 0, 3 ) * rhs2.XFORM( 3, 1 ),
00573         //  temp.XFORM(0,2)
00574         XFORM( 0, 0 ) * rhs2.XFORM( 0, 2 ) + XFORM( 0, 1 ) * rhs2.XFORM( 1, 2 ) + XFORM( 0, 2 ) * rhs2.XFORM( 2, 2 ) +
00575             XFORM( 0, 3 ) * rhs2.XFORM( 3, 2 ),
00576         //  temp.XFORM(0,3)
00577         XFORM( 0, 0 ) * rhs2.XFORM( 0, 3 ) + XFORM( 0, 1 ) * rhs2.XFORM( 1, 3 ) + XFORM( 0, 2 ) * rhs2.XFORM( 2, 3 ) +
00578             XFORM( 0, 3 ) * rhs2.XFORM( 3, 3 ),
00579
00580         //  temp.XFORM(1,0)
00581         XFORM( 1, 0 ) * rhs2.XFORM( 0, 0 ) + XFORM( 1, 1 ) * rhs2.XFORM( 1, 0 ) + XFORM( 1, 2 ) * rhs2.XFORM( 2, 0 ) +
00582             XFORM( 1, 3 ) * rhs2.XFORM( 3, 0 ),
00583         //  temp.XFORM(1,1)
00584         XFORM( 1, 0 ) * rhs2.XFORM( 0, 1 ) + XFORM( 1, 1 ) * rhs2.XFORM( 1, 1 ) + XFORM( 1, 2 ) * rhs2.XFORM( 2, 1 ) +
00585             XFORM( 1, 3 ) * rhs2.XFORM( 3, 1 ),
00586         //  temp.XFORM(1,2)
00587         XFORM( 1, 0 ) * rhs2.XFORM( 0, 2 ) + XFORM( 1, 1 ) * rhs2.XFORM( 1, 2 ) + XFORM( 1, 2 ) * rhs2.XFORM( 2, 2 ) +
00588             XFORM( 1, 3 ) * rhs2.XFORM( 3, 2 ),
00589         //  temp.XFORM(1,3)
00590         XFORM( 1, 0 ) * rhs2.XFORM( 0, 3 ) + XFORM( 1, 1 ) * rhs2.XFORM( 1, 3 ) + XFORM( 1, 2 ) * rhs2.XFORM( 2, 3 ) +
00591             XFORM( 1, 3 ) * rhs2.XFORM( 3, 3 ),
00592
00593         //  temp.XFORM(2,0)
00594         XFORM( 2, 0 ) * rhs2.XFORM( 0, 0 ) + XFORM( 2, 1 ) * rhs2.XFORM( 1, 0 ) + XFORM( 2, 2 ) * rhs2.XFORM( 2, 0 ) +
00595             XFORM( 2, 3 ) * rhs2.XFORM( 3, 0 ),
00596         //  temp.XFORM(2,1)
00597         XFORM( 2, 0 ) * rhs2.XFORM( 0, 1 ) + XFORM( 2, 1 ) * rhs2.XFORM( 1, 1 ) + XFORM( 2, 2 ) * rhs2.XFORM( 2, 1 ) +
00598             XFORM( 2, 3 ) * rhs2.XFORM( 3, 1 ),
00599         //  temp.XFORM(2,2)
00600         XFORM( 2, 0 ) * rhs2.XFORM( 0, 2 ) + XFORM( 2, 1 ) * rhs2.XFORM( 1, 2 ) + XFORM( 2, 2 ) * rhs2.XFORM( 2, 2 ) +
00601             XFORM( 2, 3 ) * rhs2.XFORM( 3, 2 ),
00602         //  temp.XFORM(2,3)
00603         XFORM( 2, 0 ) * rhs2.XFORM( 0, 3 ) + XFORM( 2, 1 ) * rhs2.XFORM( 1, 3 ) + XFORM( 2, 2 ) * rhs2.XFORM( 2, 3 ) +
00604             XFORM( 2, 3 ) * rhs2.XFORM( 3, 3 ),
00605
00606         //  temp.XFORM(3,0)
00607         //  xForm[12]*rhs2.xForm[0] + xForm[13]*rhs2.xForm[4] + xForm[14]*rhs2.xForm[8] +
00608         //  xForm[15]*rhs2.xForm[12]
00609         XFORM( 3, 0 ) * rhs2.XFORM( 0, 0 ) + XFORM( 3, 1 ) * rhs2.XFORM( 1, 0 ) + XFORM( 3, 2 ) * rhs2.XFORM( 2, 0 ) +
00610             XFORM( 3, 3 ) * rhs2.XFORM( 3, 0 ),
00611         //  temp.XFORM(3,1)
00612         //  xForm[12]*rhs2.xForm[1] + xForm[13]*rhs2.xForm[5] + xForm[14]*rhs2.xForm[9] +
00613         //  xForm[15]*rhs2.xForm[13]
00614         XFORM( 3, 0 ) * rhs2.XFORM( 0, 1 ) + XFORM( 3, 1 ) * rhs2.XFORM( 1, 1 ) + XFORM( 3, 2 ) * rhs2.XFORM( 2, 1 ) +
00615             XFORM( 3, 3 ) * rhs2.XFORM( 3, 1 ),
00616         //  temp.XFORM(3,2)
00617         //  xForm[12]*rhs2.xForm[2] + xForm[13]*rhs2.xForm[6] + xForm[14]*rhs2.xForm[10] +
00618         //  xForm[15]*rhs2.xForm[14]
00619         XFORM( 3, 0 ) * rhs2.XFORM( 0, 2 ) + XFORM( 3, 1 ) * rhs2.XFORM( 1, 2 ) + XFORM( 3, 2 ) * rhs2.XFORM( 2, 2 ) +
00620             XFORM( 3, 3 ) * rhs2.XFORM( 3, 2 ),
00621         //  temp.XFORM(3,3)
00622         //  xForm[12]*rhs2.xForm[3] + xForm[13]*rhs2.xForm[7] + xForm[14]*rhs2.xForm[11] +
00623         //  xForm[15]*rhs2.xForm[15]
00624         XFORM( 3, 0 ) * rhs2.XFORM( 0, 3 ) + XFORM( 3, 1 ) * rhs2.XFORM( 1, 3 ) + XFORM( 3, 2 ) * rhs2.XFORM( 2, 3 ) +
00625             XFORM( 3, 3 ) * rhs2.XFORM( 3, 3 ) );
00626 }
00627
00628 inline HomXform& HomXform::operator*=( const HomXform& rhs2 )
00629 {
00630     *this = HomXform(
00631         //  temp.XFORM(0,0)
00632         XFORM( 0, 0 ) * rhs2.XFORM( 0, 0 ) + XFORM( 0, 1 ) * rhs2.XFORM( 1, 0 ) + XFORM( 0, 2 ) * rhs2.XFORM( 2, 0 ) +
00633             XFORM( 0, 3 ) * rhs2.XFORM( 3, 0 ),
00634         //  temp.XFORM(0,1)
00635         XFORM( 0, 0 ) * rhs2.XFORM( 0, 1 ) + XFORM( 0, 1 ) * rhs2.XFORM( 1, 1 ) + XFORM( 0, 2 ) * rhs2.XFORM( 2, 1 ) +
00636             XFORM( 0, 3 ) * rhs2.XFORM( 3, 1 ),
00637         //  temp.XFORM(0,2)
00638         XFORM( 0, 0 ) * rhs2.XFORM( 0, 2 ) + XFORM( 0, 1 ) * rhs2.XFORM( 1, 2 ) + XFORM( 0, 2 ) * rhs2.XFORM( 2, 2 ) +
00639             XFORM( 0, 3 ) * rhs2.XFORM( 3, 2 ),
00640         //  temp.XFORM(0,3)
00641         XFORM( 0, 0 ) * rhs2.XFORM( 0, 3 ) + XFORM( 0, 1 ) * rhs2.XFORM( 1, 3 ) + XFORM( 0, 2 ) * rhs2.XFORM( 2, 3 ) +
00642             XFORM( 0, 3 ) * rhs2.XFORM( 3, 3 ),
00643
00644         //  temp.XFORM(1,0)
00645         XFORM( 1, 0 ) * rhs2.XFORM( 0, 0 ) + XFORM( 1, 1 ) * rhs2.XFORM( 1, 0 ) + XFORM( 1, 2 ) * rhs2.XFORM( 2, 0 ) +
00646             XFORM( 1, 3 ) * rhs2.XFORM( 3, 0 ),
00647         //  temp.XFORM(1,1)
00648         XFORM( 1, 0 ) * rhs2.XFORM( 0, 1 ) + XFORM( 1, 1 ) * rhs2.XFORM( 1, 1 ) + XFORM( 1, 2 ) * rhs2.XFORM( 2, 1 ) +
00649             XFORM( 1, 3 ) * rhs2.XFORM( 3, 1 ),
00650         //  temp.XFORM(1,2)
00651         XFORM( 1, 0 ) * rhs2.XFORM( 0, 2 ) + XFORM( 1, 1 ) * rhs2.XFORM( 1, 2 ) + XFORM( 1, 2 ) * rhs2.XFORM( 2, 2 ) +
00652             XFORM( 1, 3 ) * rhs2.XFORM( 3, 2 ),
00653         //  temp.XFORM(1,3)
00654         XFORM( 1, 0 ) * rhs2.XFORM( 0, 3 ) + XFORM( 1, 1 ) * rhs2.XFORM( 1, 3 ) + XFORM( 1, 2 ) * rhs2.XFORM( 2, 3 ) +
00655             XFORM( 1, 3 ) * rhs2.XFORM( 3, 3 ),
00656
00657         //  temp.XFORM(2,0)
00658         XFORM( 2, 0 ) * rhs2.XFORM( 0, 0 ) + XFORM( 2, 1 ) * rhs2.XFORM( 1, 0 ) + XFORM( 2, 2 ) * rhs2.XFORM( 2, 0 ) +
00659             XFORM( 2, 3 ) * rhs2.XFORM( 3, 0 ),
00660         //  temp.XFORM(2,1)
00661         XFORM( 2, 0 ) * rhs2.XFORM( 0, 1 ) + XFORM( 2, 1 ) * rhs2.XFORM( 1, 1 ) + XFORM( 2, 2 ) * rhs2.XFORM( 2, 1 ) +
00662             XFORM( 2, 3 ) * rhs2.XFORM( 3, 1 ),
00663         //  temp.XFORM(2,2)
00664         XFORM( 2, 0 ) * rhs2.XFORM( 0, 2 ) + XFORM( 2, 1 ) * rhs2.XFORM( 1, 2 ) + XFORM( 2, 2 ) * rhs2.XFORM( 2, 2 ) +
00665             XFORM( 2, 3 ) * rhs2.XFORM( 3, 2 ),
00666         //  temp.XFORM(2,3)
00667         XFORM( 2, 0 ) * rhs2.XFORM( 0, 3 ) + XFORM( 2, 1 ) * rhs2.XFORM( 1, 3 ) + XFORM( 2, 2 ) * rhs2.XFORM( 2, 3 ) +
00668             XFORM( 2, 3 ) * rhs2.XFORM( 3, 3 ),
00669
00670         //  temp.XFORM(3,0)
00671         XFORM( 3, 0 ) * rhs2.XFORM( 0, 0 ) + XFORM( 3, 1 ) * rhs2.XFORM( 1, 0 ) + XFORM( 3, 2 ) * rhs2.XFORM( 2, 0 ) +
00672             XFORM( 3, 3 ) * rhs2.XFORM( 3, 0 ),
00673         //  temp.XFORM(3,1)
00674         XFORM( 3, 0 ) * rhs2.XFORM( 0, 1 ) + XFORM( 3, 1 ) * rhs2.XFORM( 1, 1 ) + XFORM( 3, 2 ) * rhs2.XFORM( 2, 1 ) +
00675             XFORM( 3, 3 ) * rhs2.XFORM( 3, 1 ),
00676         //  temp.XFORM(3,2)
00677         XFORM( 3, 0 ) * rhs2.XFORM( 0, 2 ) + XFORM( 3, 1 ) * rhs2.XFORM( 1, 2 ) + XFORM( 3, 2 ) * rhs2.XFORM( 2, 2 ) +
00678             XFORM( 3, 3 ) * rhs2.XFORM( 3, 2 ),
00679         //  temp.XFORM(3,3)
00680         XFORM( 3, 0 ) * rhs2.XFORM( 0, 3 ) + XFORM( 3, 1 ) * rhs2.XFORM( 1, 3 ) + XFORM( 3, 2 ) * rhs2.XFORM( 2, 3 ) +
00681             XFORM( 3, 3 ) * rhs2.XFORM( 3, 3 ) );
00682
00683     return *this;
00684 }
00685
00686 inline int HomXform::operator[]( const int& count ) const
00687 {
00688     return xForm[count];
00689 }
00690
00691 inline int& HomXform::operator[]( const int& count )
00692 {
00693     return xForm[count];
00694 }
00695
00696 inline bool HomXform::operator==( const HomXform& rhs ) const
00697 {
00698     return ( xForm[0] == rhs.xForm[0] && xForm[1] == rhs.xForm[1] && xForm[2] == rhs.xForm[2] &&
00699              xForm[3] == rhs.xForm[3] && xForm[4] == rhs.xForm[4] && xForm[5] == rhs.xForm[5] &&
00700              xForm[6] == rhs.xForm[6] && xForm[7] == rhs.xForm[7] && xForm[8] == rhs.xForm[8] &&
00701              xForm[9] == rhs.xForm[9] && xForm[10] == rhs.xForm[10] && xForm[11] == rhs.xForm[11] &&
00702              xForm[12] == rhs.xForm[12] && xForm[13] == rhs.xForm[13] && xForm[14] == rhs.xForm[14] &&
00703              xForm[15] == rhs.xForm[15] );
00704 }
00705
00706 inline bool HomXform::operator!=( const HomXform& rhs ) const
00707 {
00708     return ( xForm[0] != rhs.xForm[0] || xForm[1] != rhs.xForm[1] || xForm[2] != rhs.xForm[2] ||
00709              xForm[3] != rhs.xForm[3] || xForm[4] != rhs.xForm[4] || xForm[5] != rhs.xForm[5] ||
00710              xForm[6] != rhs.xForm[6] || xForm[7] != rhs.xForm[7] || xForm[8] != rhs.xForm[8] ||
00711              xForm[9] != rhs.xForm[9] || xForm[10] != rhs.xForm[10] || xForm[11] != rhs.xForm[11] ||
00712              xForm[12] != rhs.xForm[12] || xForm[13] != rhs.xForm[13] || xForm[14] != rhs.xForm[14] ||
00713              xForm[15] != rhs.xForm[15] );
00714 }
00715
00716 inline HomXform HomXform::inverse() const
00717 {
00718
00719     /*
00720     // original code:
00721
00722       HomXform tmp;
00723
00724         // assign the diagonal
00725       tmp[0] = xForm[0];
00726       tmp[5] = xForm[5];
00727       tmp[10] = xForm[10];
00728       tmp[15] = xForm[15];
00729
00730         // invert the rotation matrix
00731       tmp[XFORM_INDEX(0,1)] = XFORM(1,0);
00732       tmp[XFORM_INDEX(0,2)] = XFORM(2,0);
00733       tmp[XFORM_INDEX(1,0)] = XFORM(0,1);
00734       tmp[XFORM_INDEX(1,2)] = XFORM(2,1);
00735       tmp[XFORM_INDEX(2,0)] = XFORM(0,2);
00736       tmp[XFORM_INDEX(2,1)] = XFORM(1,2);
00737
00738         // negative translate * Rinv
00739       tmp[XFORM_INDEX(3,0)] = -(XFORM(3,0)*tmp.XFORM(0,0) + XFORM(3,1)*tmp.XFORM(1,0) +
00740     XFORM(3,2)*tmp.XFORM(2,0)); tmp[XFORM_INDEX(3,1)] = -(XFORM(3,0)*tmp.XFORM(0,1) +
00741     XFORM(3,1)*tmp.XFORM(1,1) + XFORM(3,2)*tmp.XFORM(2,1)); tmp[XFORM_INDEX(3,2)] =
00742     -(XFORM(3,0)*tmp.XFORM(0,2) + XFORM(3,1)*tmp.XFORM(1,2) + XFORM(3,2)*tmp.XFORM(2,2));
00743
00744         // zero last column
00745       tmp[XFORM_INDEX(0,3)] = 0;
00746       tmp[XFORM_INDEX(1,3)] = 0;
00747       tmp[XFORM_INDEX(2,3)] = 0;
00748
00749         // h factor
00750       tmp[XFORM_INDEX(3,3)] = 1;
00751
00752       return tmp;
00753     */
00754
00755     // more efficient, but somewhat confusing (remember, column-major):
00756
00757     return HomXform(
00758         // row 0
00759         xForm[0], XFORM( 1, 0 ), XFORM( 2, 0 ), 0,
00760         // row 1
00761         XFORM( 0, 1 ), xForm[5], XFORM( 2, 1 ), 0,
00762         // row 2
00763         XFORM( 0, 2 ), XFORM( 1, 2 ), xForm[10], 0,
00764         // row 3
00765         -( XFORM( 3, 0 ) * xForm[0] + XFORM( 3, 1 ) * XFORM( 0, 1 ) + XFORM( 3, 2 ) * XFORM( 0, 2 ) ),
00766         -( XFORM( 3, 0 ) * XFORM( 1, 0 ) + XFORM( 3, 1 ) * xForm[5] + XFORM( 3, 2 ) * XFORM( 1, 2 ) ),
00767         -( XFORM( 3, 0 ) * XFORM( 2, 0 ) + XFORM( 3, 1 ) * XFORM( 2, 1 ) + XFORM( 3, 2 ) * xForm[10] ), 1 );
00768 }
00769
00770 }  // namespace moab
00771
00772 #endif