Loading [MathJax]/extensions/tex2jax.js
Mesh Oriented datABase  (version 5.5.1)
An array-based unstructured mesh library
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
HomXform.hpp
Go to the documentation of this file.
1 /** 2  * MOAB, a Mesh-Oriented datABase, is a software component for creating, 3  * storing and accessing finite element mesh data. 4  * 5  * Copyright 2004 Sandia Corporation. Under the terms of Contract 6  * DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government 7  * retains certain rights in this software. 8  * 9  * This library is free software; you can redistribute it and/or 10  * modify it under the terms of the GNU Lesser General Public 11  * License as published by the Free Software Foundation; either 12  * version 2.1 of the License, or (at your option) any later version. 13  * 14  */ 15  16 #ifndef MOAB_HOMXFORM 17 #define MOAB_HOMXFORM 18  19 /* 20  * \file HomXform.hpp 21  * 22  * \brief Representation and functions for homogeneous transforms 23  * 24  * A homogeneous transform is a 4x4 matrix for representing and manipulating 25  * homogeneous coordinates, which are x' = (x/h, y/h, z/h, h). See Mortenson, 26  * Geometric Modeling, or other texts on geometric modeling for details of homogeneous 27  * transforms. 28  */ 29  30 #define XFORM( a, b ) xForm[4 * ( a ) + ( b )] 31 #define XFORM_INDEX( a, b ) ( 4 * ( a ) + ( b ) ) 32  33 #include <cmath> 34 #include <cmath> 35  36 #include <ostream> 37  38 #include "moab/win32_config.h" 39  40 namespace moab 41 { 42  43 class HomXform; 44  45 /** \class HomCoord 46  * \brief Homogeneous coordinate vector 47  */ 48 class HomCoord 49 { 50  private: 51  //! coordinate data 52 #if defined( __INTEL_COMPILER ) && ( __INTEL_COMPILER < 1310 ) 53  // Hack Intel compiler 12 issues with -O2 optimization 54  int homCoord[5]; 55 #else 56  int homCoord[4]; 57 #endif 58  59  public: 60  friend class HomXform; 61  62  static MOAB_EXPORT HomCoord unitv[3]; 63  static MOAB_EXPORT HomCoord IDENTITY; 64  65  //! constructors 66  HomCoord(); 67  HomCoord( const int coords[], const int num_coords = 4 ); 68  HomCoord( const int coord0, const int coord1, const int coord2, const int coord3 ); 69  HomCoord( const int coord0, const int coord1, const int coord2 ); 70  HomCoord( const HomCoord& coord ); 71  72  //! set function 73  void set( const int coords[] ); 74  void set( const int i, const int j, const int k, const int h = 1 ); 75  76  //! get function 77  const int* hom_coord() const 78  { 79  return homCoord; 80  } 81  82  // Getters needed for share windows 83  static HomCoord& getUnitv( int c ); 84  85  //! parameter-based access functions 86  int i() const 87  { 88  return homCoord[0]; 89  } 90  int j() const 91  { 92  return homCoord[1]; 93  } 94  int k() const 95  { 96  return homCoord[2]; 97  } 98  int h() const 99  { 100  return homCoord[3]; 101  } 102  103  //! squared length 104  int length_squared() const; 105  106  //! length 107  int length() const; 108  109  //! normalize 110  void normalize(); 111  112  //! operators 113  HomCoord& operator*=( const HomXform& rhs2 ); 114  HomCoord operator*( const HomXform& rhs2 ) const; 115  HomCoord& operator*=( const int mult ); 116  HomCoord operator*( const int mult ) const; 117  inline HomCoord& operator/=( const HomXform& rhs2 ); 118  HomCoord operator/( const HomXform& rhs2 ) const; 119  inline HomCoord& operator/=( const int mult ); 120  HomCoord operator/( const int mult ) const; 121  inline HomCoord& operator+=( const HomCoord& rhs1 ); 122  HomCoord operator+( const HomCoord& rhs1 ) const; 123  inline HomCoord& operator-=( const HomCoord& rhs1 ); 124  HomCoord operator-( const HomCoord& rhs1 ) const; 125  HomCoord& operator=( const HomCoord& rhs ); 126  127  // dot product 128  int operator%( const HomCoord& rhs ) const; 129  130  // cross product 131  HomCoord operator*( const HomCoord& rhs ) const; 132  HomCoord& operator*=( const HomCoord& rhs ); 133  134  bool operator==( const HomCoord& rhs1 ) const; 135  bool operator!=( const HomCoord& rhs1 ) const; 136  bool operator>=( const HomCoord& rhs1 ) const; 137  bool operator<=( const HomCoord& rhs1 ) const; 138  bool operator>( const HomCoord& rhs1 ) const; 139  bool operator<( const HomCoord& rhs1 ) const; 140  inline int operator[]( const int& param ) const; 141  int& operator[]( const int& param ); 142 }; 143  144 /** \class HomXform 145  * \brief Homogeneous coordinate transformation matrix 146  */ 147 class HomXform 148 { 149  150  private: 151  //! the matrix; don't bother storing the last column, since we assume for now it's 152  //! always unused 153  int xForm[16]; 154  155  public: 156  friend class HomCoord; 157  158  static MOAB_EXPORT HomXform IDENTITY; 159  160  //! constructor from matrix 161  HomXform( const int matrix[16] ); 162  163  //! bare constructor 164  HomXform(); 165  166  //! constructor from rotation, scaling, translation 167  HomXform( const int rotate[9], const int scale[3], const int translate[3] ); 168  169  //! constructor taking 16 ints, useful for efficient operators 170  HomXform( int i1, 171  int i2, 172  int i3, 173  int i4, 174  int i5, 175  int i6, 176  int i7, 177  int i8, 178  int i9, 179  int i10, 180  int i11, 181  int i12, 182  int i13, 183  int i14, 184  int i15, 185  int i16 ); 186  187  //! copy constructor 188  HomXform( HomXform const& from ) 189  { 190  std::copy( from.xForm, from.xForm + 16, xForm ); 191  } 192  193  //! return this.inverse 194  inline HomXform inverse() const; 195  196  //! compute a transform from three points 197  void three_pt_xform( const HomCoord& p1, 198  const HomCoord& q1, 199  const HomCoord& p2, 200  const HomCoord& q2, 201  const HomCoord& p3, 202  const HomCoord& q3 ); 203  204  //! operators 205  int operator[]( const int& count ) const; 206  int& operator[]( const int& count ); 207  bool operator==( const HomXform& rhs ) const; 208  bool operator!=( const HomXform& rhs ) const; 209  210  HomXform& operator=( const HomXform& rhs ); 211  HomXform& operator*=( const HomXform& rhs ); 212  HomXform operator*( const HomXform& rhs2 ) const; 213 }; 214  215 inline HomCoord::HomCoord() 216 { 217  homCoord[0] = 0; 218  homCoord[1] = 0; 219  homCoord[2] = 0; 220  homCoord[3] = 0; 221 } 222  223 inline HomCoord::HomCoord( const int coords[], const int num_coords ) 224 { 225  for( int tmpj = 0; tmpj < num_coords; tmpj++ ) 226  homCoord[tmpj] = coords[tmpj]; 227  if( num_coords != 4 ) homCoord[3] = 1; 228 } 229  230 inline HomCoord::HomCoord( const int coord0, const int coord1, const int coord2, const int coord3 ) 231 { 232  homCoord[0] = coord0; 233  homCoord[1] = coord1; 234  homCoord[2] = coord2; 235  homCoord[3] = coord3; 236 } 237  238 inline HomCoord::HomCoord( const int coord0, const int coord1, const int coord2 ) 239 { 240  homCoord[0] = coord0; 241  homCoord[1] = coord1; 242  homCoord[2] = coord2; 243  homCoord[3] = 1; 244 } 245  246 inline HomCoord::HomCoord( const HomCoord& coords ) 247 { 248 #if defined( __INTEL_COMPILER ) && ( __INTEL_COMPILER < 1310 ) 249  // Hack Intel compiler 12 issues with -O2 optimization 250  int coord0 = coords[0]; 251  int coord1 = coords[1]; 252  int coord2 = coords[2]; 253  int coord3 = coords[3]; 254  homCoord[0] = coord0; 255  homCoord[1] = coord1; 256  homCoord[2] = coord2; 257  homCoord[3] = coord3; 258 #else 259  homCoord[0] = coords[0]; 260  homCoord[1] = coords[1]; 261  homCoord[2] = coords[2]; 262  homCoord[3] = coords[3]; 263 #endif 264 } 265  266 inline void HomCoord::set( const int coords[] ) 267 { 268  homCoord[0] = coords[0]; 269  homCoord[1] = coords[1]; 270  homCoord[2] = coords[2]; 271  homCoord[3] = coords[3]; 272 } 273  274 inline void HomCoord::set( const int ip, const int jp, const int kp, const int hp ) 275 { 276  homCoord[0] = ip; 277  homCoord[1] = jp; 278  homCoord[2] = kp; 279  homCoord[3] = hp; 280 } 281  282 inline HomCoord& HomCoord::operator=( const HomCoord& rhs1 ) 283 { 284  homCoord[0] = rhs1.homCoord[0]; 285  homCoord[1] = rhs1.homCoord[1]; 286  homCoord[2] = rhs1.homCoord[2]; 287  homCoord[3] = rhs1.homCoord[3]; 288  return *this; 289 } 290  291 //! squared length 292 inline int HomCoord::length_squared() const 293 { 294  return homCoord[0] * homCoord[0] + homCoord[1] * homCoord[1] + homCoord[2] * homCoord[2]; 295 } 296  297 //! length 298 inline int HomCoord::length() const 299 { 300  return (int)std::sqrt( (float)length_squared() ); 301 } 302  303 //! normalize 304 inline void HomCoord::normalize() 305 { 306  *this /= length(); 307 } 308  309 // dot product 310 inline int HomCoord::operator%( const HomCoord& rhs ) const 311 { 312  return homCoord[0] * rhs.homCoord[0] + homCoord[1] * rhs.homCoord[1] + homCoord[2] * rhs.homCoord[2]; 313 } 314  315 // cross product 316 inline HomCoord HomCoord::operator*( const HomCoord& rhs ) const 317 { 318  return HomCoord( homCoord[1] * rhs.homCoord[2] - homCoord[2] * rhs.homCoord[1], 319  homCoord[2] * rhs.homCoord[0] - homCoord[0] * rhs.homCoord[2], 320  homCoord[0] * rhs.homCoord[1] - homCoord[1] * rhs.homCoord[0] ); 321 } 322  323 inline HomCoord& HomCoord::operator*=( const HomCoord& rhs ) 324 { 325  *this = HomCoord( homCoord[1] * rhs.homCoord[2] - homCoord[2] * rhs.homCoord[1], 326  homCoord[2] * rhs.homCoord[0] - homCoord[0] * rhs.homCoord[2], 327  homCoord[0] * rhs.homCoord[1] - homCoord[1] * rhs.homCoord[0] ); 328  329  return *this; 330 } 331  332 inline bool HomCoord::operator==( const HomCoord& rhs1 ) const 333 { 334  return ( homCoord[0] == rhs1.homCoord[0] && homCoord[1] == rhs1.homCoord[1] && homCoord[2] == rhs1.homCoord[2] && 335  homCoord[3] == rhs1.homCoord[3] ); 336 } 337  338 inline bool HomCoord::operator!=( const HomCoord& rhs1 ) const 339 { 340  return ( homCoord[0] != rhs1.homCoord[0] || homCoord[1] != rhs1.homCoord[1] || homCoord[2] != rhs1.homCoord[2] || 341  homCoord[3] != rhs1.homCoord[3] ); 342 } 343  344 inline bool HomCoord::operator>=( const HomCoord& rhs1 ) const 345 { 346  return ( homCoord[0] >= rhs1.homCoord[0] && homCoord[1] >= rhs1.homCoord[1] && homCoord[2] >= rhs1.homCoord[2] && 347  homCoord[3] == rhs1.homCoord[3] ); 348 } 349  350 inline bool HomCoord::operator<=( const HomCoord& rhs1 ) const 351 { 352  return ( homCoord[0] <= rhs1.homCoord[0] && homCoord[1] <= rhs1.homCoord[1] && homCoord[2] <= rhs1.homCoord[2] && 353  homCoord[3] == rhs1.homCoord[3] ); 354 } 355  356 inline bool HomCoord::operator<( const HomCoord& rhs1 ) const 357 { 358  return ( homCoord[0] < rhs1.homCoord[0] && homCoord[1] < rhs1.homCoord[1] && homCoord[2] < rhs1.homCoord[2] && 359  homCoord[3] == rhs1.homCoord[3] ); 360 } 361  362 inline bool HomCoord::operator>( const HomCoord& rhs1 ) const 363 { 364  return ( homCoord[0] > rhs1.homCoord[0] && homCoord[1] > rhs1.homCoord[1] && homCoord[2] > rhs1.homCoord[2] && 365  homCoord[3] == rhs1.homCoord[3] ); 366 } 367  368 inline HomCoord HomCoord::operator*( const HomXform& rhs2 ) const 369 { 370  return HomCoord( 371  // homCoord[0]*rhs2[4*0+0] + homCoord[1]*rhs2[4*1+0] + 372  // homCoord[2]*rhs2[4*2+0] + homCoord[3]*rhs2[4*3+0], 373  homCoord[0] * rhs2.xForm[0] + homCoord[1] * rhs2.xForm[4] + homCoord[2] * rhs2.xForm[8] + 374  homCoord[3] * rhs2.xForm[12], 375  376  // homCoord[0]*rhs2.xForm[4*0+1] + homCoord[1]*rhs2.xForm[4*1+1] + 377  // homCoord[2]*rhs2.xForm[4*2+1] + homCoord[3]*rhs2.xForm[4*3+1], 378  homCoord[0] * rhs2.xForm[1] + homCoord[1] * rhs2.xForm[5] + homCoord[2] * rhs2.xForm[9] + 379  homCoord[3] * rhs2.xForm[13], 380  381  // homCoord[0]*rhs2.xForm[4*0+2] + homCoord[1]*rhs2.xForm[4*1+2] + 382  // homCoord[2]*rhs2.xForm[4*2+2] + homCoord[3]*rhs2.xForm[4*3+2], 383  homCoord[0] * rhs2.xForm[2] + homCoord[1] * rhs2.xForm[6] + homCoord[2] * rhs2.xForm[10] + 384  homCoord[3] * rhs2.xForm[14], 385  386  // homCoord[0]*rhs2.xForm[4*0+3] + homCoord[1]*rhs2.xForm[4*1+3] + 387  // homCoord[2]*rhs2.xForm[4*2+3] + homCoord[3]*rhs2.xForm[4*3+3] 388  homCoord[0] * rhs2.xForm[3] + homCoord[1] * rhs2.xForm[7] + homCoord[2] * rhs2.xForm[11] + 389  homCoord[3] * rhs2.xForm[15] ); 390 } 391  392 inline HomCoord& HomCoord::operator*=( const HomXform& rhs2 ) 393 { 394  *this = HomCoord( 395  // homCoord[0]*rhs2.xForm[4*0+0] + homCoord[1]*rhs2.xForm[4*1+0] + 396  // homCoord[2]*rhs2.xForm[4*2+0] + homCoord[3]*rhs2.xForm[4*3+0], 397  homCoord[0] * rhs2.xForm[0] + homCoord[1] * rhs2.xForm[4] + homCoord[2] * rhs2.xForm[8] + 398  homCoord[3] * rhs2.xForm[12], 399  400  // homCoord[0]*rhs2.xForm[4*0+1] + homCoord[1]*rhs2.xForm[4*1+1] + 401  // homCoord[2]*rhs2.xForm[4*2+1] + homCoord[3]*rhs2.xForm[4*3+1], 402  homCoord[0] * rhs2.xForm[1] + homCoord[1] * rhs2.xForm[5] + homCoord[2] * rhs2.xForm[9] + 403  homCoord[3] * rhs2.xForm[13], 404  405  // homCoord[0]*rhs2.xForm[4*0+2] + homCoord[1]*rhs2.xForm[4*1+2] + 406  // homCoord[2]*rhs2.xForm[4*2+2] + homCoord[3]*rhs2.xForm[4*3+2], 407  homCoord[0] * rhs2.xForm[2] + homCoord[1] * rhs2.xForm[6] + homCoord[2] * rhs2.xForm[10] + 408  homCoord[3] * rhs2.xForm[14], 409  410  // homCoord[0]*rhs2.xForm[4*0+3] + homCoord[1]*rhs2.xForm[4*1+3] + 411  // homCoord[2]*rhs2.xForm[4*2+3] + homCoord[3]*rhs2.xForm[4*3+3] 412  homCoord[0] * rhs2.xForm[3] + homCoord[1] * rhs2.xForm[7] + homCoord[2] * rhs2.xForm[11] + 413  homCoord[3] * rhs2.xForm[15] ); 414  return *this; 415 } 416  417 inline HomCoord HomCoord::operator*( const int mult ) const 418 { 419  return HomCoord( mult * homCoord[0], mult * homCoord[1], mult * homCoord[2] ); 420 } 421  422 inline HomCoord& HomCoord::operator*=( const int mult ) 423 { 424  homCoord[0] *= mult; 425  homCoord[1] *= mult; 426  homCoord[2] *= mult; 427  return *this; 428 } 429  430 inline HomCoord HomCoord::operator/( const int div ) const 431 { 432  return HomCoord( homCoord[0] / div, homCoord[1] / div, homCoord[2] / div ); 433 } 434  435 inline HomCoord& HomCoord::operator/=( const int div ) 436 { 437  homCoord[0] /= div; 438  homCoord[1] /= div; 439  homCoord[2] /= div; 440  return *this; 441 } 442  443 inline HomCoord HomCoord::operator-( const HomCoord& rhs2 ) const 444 { 445  return HomCoord( *this ) -= rhs2; 446 } 447  448 inline HomCoord& HomCoord::operator-=( const HomCoord& rhs2 ) 449 { 450  homCoord[0] -= rhs2[0]; 451  homCoord[1] -= rhs2[1]; 452  homCoord[2] -= rhs2[2]; 453  return *this; 454 } 455  456 inline HomCoord HomCoord::operator+( const HomCoord& rhs2 ) const 457 { 458  return HomCoord( *this ) += rhs2; 459 } 460  461 inline HomCoord& HomCoord::operator+=( const HomCoord& rhs2 ) 462 { 463  homCoord[0] += rhs2[0]; 464  homCoord[1] += rhs2[1]; 465  homCoord[2] += rhs2[2]; 466  return *this; 467 } 468  469 inline HomCoord HomCoord::operator/( const HomXform& rhs2 ) const 470 { 471  return HomCoord( *this ) /= rhs2; 472 } 473  474 inline HomCoord& HomCoord::operator/=( const HomXform& rhs2 ) 475 { 476  HomXform inv = rhs2.inverse(); 477  *this *= inv; 478  return *this; 479 } 480  481 inline int HomCoord::operator[]( const int& param ) const 482 { 483  return homCoord[param]; 484 } 485  486 inline int& HomCoord::operator[]( const int& param ) 487 { 488  return homCoord[param]; 489 } 490  491 inline std::ostream& operator<<( std::ostream& str, const HomCoord& hc ) 492 { 493  str << "(" << hc.i() << "," << hc.j() << "," << hc.k() << ")"; 494  return str; 495 } 496  497 inline HomXform::HomXform( const int matrix[16] ) 498 { 499  for( int i = 0; i < 16; i++ ) 500  xForm[i] = matrix[i]; 501 } 502  503 inline HomXform::HomXform() {} 504  505 inline HomXform::HomXform( const int rotate[9], const int scale[3], const int translate[3] ) 506 { 507  int i, j; 508  for( i = 0; i < 3; i++ ) 509  { 510  for( j = 0; j < 3; j++ ) 511  xForm[i * 4 + j] = rotate[i * 3 + j] * scale[j]; 512  513  xForm[12 + i] = translate[i]; 514  } 515  xForm[3] = 0; 516  xForm[7] = 0; 517  xForm[11] = 0; 518  xForm[15] = 1; 519 } 520  521 inline HomXform::HomXform( int i1, 522  int i2, 523  int i3, 524  int i4, 525  int i5, 526  int i6, 527  int i7, 528  int i8, 529  int i9, 530  int i10, 531  int i11, 532  int i12, 533  int i13, 534  int i14, 535  int i15, 536  int i16 ) 537 { 538  xForm[0] = i1; 539  xForm[1] = i2; 540  xForm[2] = i3; 541  xForm[3] = i4; 542  xForm[4] = i5; 543  xForm[5] = i6; 544  xForm[6] = i7; 545  xForm[7] = i8; 546  xForm[8] = i9; 547  xForm[9] = i10; 548  xForm[10] = i11; 549  xForm[11] = i12; 550  xForm[12] = i13; 551  xForm[13] = i14; 552  xForm[14] = i15; 553  xForm[15] = i16; 554 } 555  556 inline HomXform& HomXform::operator=( const HomXform& rhs ) 557 { 558  for( int i = 0; i < 16; i++ ) 559  xForm[i] = rhs.xForm[i]; 560  561  return *this; 562 } 563  564 inline HomXform HomXform::operator*( const HomXform& rhs2 ) const 565 { 566  return HomXform( 567  // temp.XFORM(0,0) 568  XFORM( 0, 0 ) * rhs2.XFORM( 0, 0 ) + XFORM( 0, 1 ) * rhs2.XFORM( 1, 0 ) + XFORM( 0, 2 ) * rhs2.XFORM( 2, 0 ) + 569  XFORM( 0, 3 ) * rhs2.XFORM( 3, 0 ), 570  // temp.XFORM(0,1) 571  XFORM( 0, 0 ) * rhs2.XFORM( 0, 1 ) + XFORM( 0, 1 ) * rhs2.XFORM( 1, 1 ) + XFORM( 0, 2 ) * rhs2.XFORM( 2, 1 ) + 572  XFORM( 0, 3 ) * rhs2.XFORM( 3, 1 ), 573  // temp.XFORM(0,2) 574  XFORM( 0, 0 ) * rhs2.XFORM( 0, 2 ) + XFORM( 0, 1 ) * rhs2.XFORM( 1, 2 ) + XFORM( 0, 2 ) * rhs2.XFORM( 2, 2 ) + 575  XFORM( 0, 3 ) * rhs2.XFORM( 3, 2 ), 576  // temp.XFORM(0,3) 577  XFORM( 0, 0 ) * rhs2.XFORM( 0, 3 ) + XFORM( 0, 1 ) * rhs2.XFORM( 1, 3 ) + XFORM( 0, 2 ) * rhs2.XFORM( 2, 3 ) + 578  XFORM( 0, 3 ) * rhs2.XFORM( 3, 3 ), 579  580  // temp.XFORM(1,0) 581  XFORM( 1, 0 ) * rhs2.XFORM( 0, 0 ) + XFORM( 1, 1 ) * rhs2.XFORM( 1, 0 ) + XFORM( 1, 2 ) * rhs2.XFORM( 2, 0 ) + 582  XFORM( 1, 3 ) * rhs2.XFORM( 3, 0 ), 583  // temp.XFORM(1,1) 584  XFORM( 1, 0 ) * rhs2.XFORM( 0, 1 ) + XFORM( 1, 1 ) * rhs2.XFORM( 1, 1 ) + XFORM( 1, 2 ) * rhs2.XFORM( 2, 1 ) + 585  XFORM( 1, 3 ) * rhs2.XFORM( 3, 1 ), 586  // temp.XFORM(1,2) 587  XFORM( 1, 0 ) * rhs2.XFORM( 0, 2 ) + XFORM( 1, 1 ) * rhs2.XFORM( 1, 2 ) + XFORM( 1, 2 ) * rhs2.XFORM( 2, 2 ) + 588  XFORM( 1, 3 ) * rhs2.XFORM( 3, 2 ), 589  // temp.XFORM(1,3) 590  XFORM( 1, 0 ) * rhs2.XFORM( 0, 3 ) + XFORM( 1, 1 ) * rhs2.XFORM( 1, 3 ) + XFORM( 1, 2 ) * rhs2.XFORM( 2, 3 ) + 591  XFORM( 1, 3 ) * rhs2.XFORM( 3, 3 ), 592  593  // temp.XFORM(2,0) 594  XFORM( 2, 0 ) * rhs2.XFORM( 0, 0 ) + XFORM( 2, 1 ) * rhs2.XFORM( 1, 0 ) + XFORM( 2, 2 ) * rhs2.XFORM( 2, 0 ) + 595  XFORM( 2, 3 ) * rhs2.XFORM( 3, 0 ), 596  // temp.XFORM(2,1) 597  XFORM( 2, 0 ) * rhs2.XFORM( 0, 1 ) + XFORM( 2, 1 ) * rhs2.XFORM( 1, 1 ) + XFORM( 2, 2 ) * rhs2.XFORM( 2, 1 ) + 598  XFORM( 2, 3 ) * rhs2.XFORM( 3, 1 ), 599  // temp.XFORM(2,2) 600  XFORM( 2, 0 ) * rhs2.XFORM( 0, 2 ) + XFORM( 2, 1 ) * rhs2.XFORM( 1, 2 ) + XFORM( 2, 2 ) * rhs2.XFORM( 2, 2 ) + 601  XFORM( 2, 3 ) * rhs2.XFORM( 3, 2 ), 602  // temp.XFORM(2,3) 603  XFORM( 2, 0 ) * rhs2.XFORM( 0, 3 ) + XFORM( 2, 1 ) * rhs2.XFORM( 1, 3 ) + XFORM( 2, 2 ) * rhs2.XFORM( 2, 3 ) + 604  XFORM( 2, 3 ) * rhs2.XFORM( 3, 3 ), 605  606  // temp.XFORM(3,0) 607  // xForm[12]*rhs2.xForm[0] + xForm[13]*rhs2.xForm[4] + xForm[14]*rhs2.xForm[8] + 608  // xForm[15]*rhs2.xForm[12] 609  XFORM( 3, 0 ) * rhs2.XFORM( 0, 0 ) + XFORM( 3, 1 ) * rhs2.XFORM( 1, 0 ) + XFORM( 3, 2 ) * rhs2.XFORM( 2, 0 ) + 610  XFORM( 3, 3 ) * rhs2.XFORM( 3, 0 ), 611  // temp.XFORM(3,1) 612  // xForm[12]*rhs2.xForm[1] + xForm[13]*rhs2.xForm[5] + xForm[14]*rhs2.xForm[9] + 613  // xForm[15]*rhs2.xForm[13] 614  XFORM( 3, 0 ) * rhs2.XFORM( 0, 1 ) + XFORM( 3, 1 ) * rhs2.XFORM( 1, 1 ) + XFORM( 3, 2 ) * rhs2.XFORM( 2, 1 ) + 615  XFORM( 3, 3 ) * rhs2.XFORM( 3, 1 ), 616  // temp.XFORM(3,2) 617  // xForm[12]*rhs2.xForm[2] + xForm[13]*rhs2.xForm[6] + xForm[14]*rhs2.xForm[10] + 618  // xForm[15]*rhs2.xForm[14] 619  XFORM( 3, 0 ) * rhs2.XFORM( 0, 2 ) + XFORM( 3, 1 ) * rhs2.XFORM( 1, 2 ) + XFORM( 3, 2 ) * rhs2.XFORM( 2, 2 ) + 620  XFORM( 3, 3 ) * rhs2.XFORM( 3, 2 ), 621  // temp.XFORM(3,3) 622  // xForm[12]*rhs2.xForm[3] + xForm[13]*rhs2.xForm[7] + xForm[14]*rhs2.xForm[11] + 623  // xForm[15]*rhs2.xForm[15] 624  XFORM( 3, 0 ) * rhs2.XFORM( 0, 3 ) + XFORM( 3, 1 ) * rhs2.XFORM( 1, 3 ) + XFORM( 3, 2 ) * rhs2.XFORM( 2, 3 ) + 625  XFORM( 3, 3 ) * rhs2.XFORM( 3, 3 ) ); 626 } 627  628 inline HomXform& HomXform::operator*=( const HomXform& rhs2 ) 629 { 630  *this = HomXform( 631  // temp.XFORM(0,0) 632  XFORM( 0, 0 ) * rhs2.XFORM( 0, 0 ) + XFORM( 0, 1 ) * rhs2.XFORM( 1, 0 ) + XFORM( 0, 2 ) * rhs2.XFORM( 2, 0 ) + 633  XFORM( 0, 3 ) * rhs2.XFORM( 3, 0 ), 634  // temp.XFORM(0,1) 635  XFORM( 0, 0 ) * rhs2.XFORM( 0, 1 ) + XFORM( 0, 1 ) * rhs2.XFORM( 1, 1 ) + XFORM( 0, 2 ) * rhs2.XFORM( 2, 1 ) + 636  XFORM( 0, 3 ) * rhs2.XFORM( 3, 1 ), 637  // temp.XFORM(0,2) 638  XFORM( 0, 0 ) * rhs2.XFORM( 0, 2 ) + XFORM( 0, 1 ) * rhs2.XFORM( 1, 2 ) + XFORM( 0, 2 ) * rhs2.XFORM( 2, 2 ) + 639  XFORM( 0, 3 ) * rhs2.XFORM( 3, 2 ), 640  // temp.XFORM(0,3) 641  XFORM( 0, 0 ) * rhs2.XFORM( 0, 3 ) + XFORM( 0, 1 ) * rhs2.XFORM( 1, 3 ) + XFORM( 0, 2 ) * rhs2.XFORM( 2, 3 ) + 642  XFORM( 0, 3 ) * rhs2.XFORM( 3, 3 ), 643  644  // temp.XFORM(1,0) 645  XFORM( 1, 0 ) * rhs2.XFORM( 0, 0 ) + XFORM( 1, 1 ) * rhs2.XFORM( 1, 0 ) + XFORM( 1, 2 ) * rhs2.XFORM( 2, 0 ) + 646  XFORM( 1, 3 ) * rhs2.XFORM( 3, 0 ), 647  // temp.XFORM(1,1) 648  XFORM( 1, 0 ) * rhs2.XFORM( 0, 1 ) + XFORM( 1, 1 ) * rhs2.XFORM( 1, 1 ) + XFORM( 1, 2 ) * rhs2.XFORM( 2, 1 ) + 649  XFORM( 1, 3 ) * rhs2.XFORM( 3, 1 ), 650  // temp.XFORM(1,2) 651  XFORM( 1, 0 ) * rhs2.XFORM( 0, 2 ) + XFORM( 1, 1 ) * rhs2.XFORM( 1, 2 ) + XFORM( 1, 2 ) * rhs2.XFORM( 2, 2 ) + 652  XFORM( 1, 3 ) * rhs2.XFORM( 3, 2 ), 653  // temp.XFORM(1,3) 654  XFORM( 1, 0 ) * rhs2.XFORM( 0, 3 ) + XFORM( 1, 1 ) * rhs2.XFORM( 1, 3 ) + XFORM( 1, 2 ) * rhs2.XFORM( 2, 3 ) + 655  XFORM( 1, 3 ) * rhs2.XFORM( 3, 3 ), 656  657  // temp.XFORM(2,0) 658  XFORM( 2, 0 ) * rhs2.XFORM( 0, 0 ) + XFORM( 2, 1 ) * rhs2.XFORM( 1, 0 ) + XFORM( 2, 2 ) * rhs2.XFORM( 2, 0 ) + 659  XFORM( 2, 3 ) * rhs2.XFORM( 3, 0 ), 660  // temp.XFORM(2,1) 661  XFORM( 2, 0 ) * rhs2.XFORM( 0, 1 ) + XFORM( 2, 1 ) * rhs2.XFORM( 1, 1 ) + XFORM( 2, 2 ) * rhs2.XFORM( 2, 1 ) + 662  XFORM( 2, 3 ) * rhs2.XFORM( 3, 1 ), 663  // temp.XFORM(2,2) 664  XFORM( 2, 0 ) * rhs2.XFORM( 0, 2 ) + XFORM( 2, 1 ) * rhs2.XFORM( 1, 2 ) + XFORM( 2, 2 ) * rhs2.XFORM( 2, 2 ) + 665  XFORM( 2, 3 ) * rhs2.XFORM( 3, 2 ), 666  // temp.XFORM(2,3) 667  XFORM( 2, 0 ) * rhs2.XFORM( 0, 3 ) + XFORM( 2, 1 ) * rhs2.XFORM( 1, 3 ) + XFORM( 2, 2 ) * rhs2.XFORM( 2, 3 ) + 668  XFORM( 2, 3 ) * rhs2.XFORM( 3, 3 ), 669  670  // temp.XFORM(3,0) 671  XFORM( 3, 0 ) * rhs2.XFORM( 0, 0 ) + XFORM( 3, 1 ) * rhs2.XFORM( 1, 0 ) + XFORM( 3, 2 ) * rhs2.XFORM( 2, 0 ) + 672  XFORM( 3, 3 ) * rhs2.XFORM( 3, 0 ), 673  // temp.XFORM(3,1) 674  XFORM( 3, 0 ) * rhs2.XFORM( 0, 1 ) + XFORM( 3, 1 ) * rhs2.XFORM( 1, 1 ) + XFORM( 3, 2 ) * rhs2.XFORM( 2, 1 ) + 675  XFORM( 3, 3 ) * rhs2.XFORM( 3, 1 ), 676  // temp.XFORM(3,2) 677  XFORM( 3, 0 ) * rhs2.XFORM( 0, 2 ) + XFORM( 3, 1 ) * rhs2.XFORM( 1, 2 ) + XFORM( 3, 2 ) * rhs2.XFORM( 2, 2 ) + 678  XFORM( 3, 3 ) * rhs2.XFORM( 3, 2 ), 679  // temp.XFORM(3,3) 680  XFORM( 3, 0 ) * rhs2.XFORM( 0, 3 ) + XFORM( 3, 1 ) * rhs2.XFORM( 1, 3 ) + XFORM( 3, 2 ) * rhs2.XFORM( 2, 3 ) + 681  XFORM( 3, 3 ) * rhs2.XFORM( 3, 3 ) ); 682  683  return *this; 684 } 685  686 inline int HomXform::operator[]( const int& count ) const 687 { 688  return xForm[count]; 689 } 690  691 inline int& HomXform::operator[]( const int& count ) 692 { 693  return xForm[count]; 694 } 695  696 inline bool HomXform::operator==( const HomXform& rhs ) const 697 { 698  return ( xForm[0] == rhs.xForm[0] && xForm[1] == rhs.xForm[1] && xForm[2] == rhs.xForm[2] && 699  xForm[3] == rhs.xForm[3] && xForm[4] == rhs.xForm[4] && xForm[5] == rhs.xForm[5] && 700  xForm[6] == rhs.xForm[6] && xForm[7] == rhs.xForm[7] && xForm[8] == rhs.xForm[8] && 701  xForm[9] == rhs.xForm[9] && xForm[10] == rhs.xForm[10] && xForm[11] == rhs.xForm[11] && 702  xForm[12] == rhs.xForm[12] && xForm[13] == rhs.xForm[13] && xForm[14] == rhs.xForm[14] && 703  xForm[15] == rhs.xForm[15] ); 704 } 705  706 inline bool HomXform::operator!=( const HomXform& rhs ) const 707 { 708  return ( xForm[0] != rhs.xForm[0] || xForm[1] != rhs.xForm[1] || xForm[2] != rhs.xForm[2] || 709  xForm[3] != rhs.xForm[3] || xForm[4] != rhs.xForm[4] || xForm[5] != rhs.xForm[5] || 710  xForm[6] != rhs.xForm[6] || xForm[7] != rhs.xForm[7] || xForm[8] != rhs.xForm[8] || 711  xForm[9] != rhs.xForm[9] || xForm[10] != rhs.xForm[10] || xForm[11] != rhs.xForm[11] || 712  xForm[12] != rhs.xForm[12] || xForm[13] != rhs.xForm[13] || xForm[14] != rhs.xForm[14] || 713  xForm[15] != rhs.xForm[15] ); 714 } 715  716 inline HomXform HomXform::inverse() const 717 { 718  719  /* 720  // original code: 721  722  HomXform tmp; 723  724  // assign the diagonal 725  tmp[0] = xForm[0]; 726  tmp[5] = xForm[5]; 727  tmp[10] = xForm[10]; 728  tmp[15] = xForm[15]; 729  730  // invert the rotation matrix 731  tmp[XFORM_INDEX(0,1)] = XFORM(1,0); 732  tmp[XFORM_INDEX(0,2)] = XFORM(2,0); 733  tmp[XFORM_INDEX(1,0)] = XFORM(0,1); 734  tmp[XFORM_INDEX(1,2)] = XFORM(2,1); 735  tmp[XFORM_INDEX(2,0)] = XFORM(0,2); 736  tmp[XFORM_INDEX(2,1)] = XFORM(1,2); 737  738  // negative translate * Rinv 739  tmp[XFORM_INDEX(3,0)] = -(XFORM(3,0)*tmp.XFORM(0,0) + XFORM(3,1)*tmp.XFORM(1,0) + 740  XFORM(3,2)*tmp.XFORM(2,0)); tmp[XFORM_INDEX(3,1)] = -(XFORM(3,0)*tmp.XFORM(0,1) + 741  XFORM(3,1)*tmp.XFORM(1,1) + XFORM(3,2)*tmp.XFORM(2,1)); tmp[XFORM_INDEX(3,2)] = 742  -(XFORM(3,0)*tmp.XFORM(0,2) + XFORM(3,1)*tmp.XFORM(1,2) + XFORM(3,2)*tmp.XFORM(2,2)); 743  744  // zero last column 745  tmp[XFORM_INDEX(0,3)] = 0; 746  tmp[XFORM_INDEX(1,3)] = 0; 747  tmp[XFORM_INDEX(2,3)] = 0; 748  749  // h factor 750  tmp[XFORM_INDEX(3,3)] = 1; 751  752  return tmp; 753  */ 754  755  // more efficient, but somewhat confusing (remember, column-major): 756  757  return HomXform( 758  // row 0 759  xForm[0], XFORM( 1, 0 ), XFORM( 2, 0 ), 0, 760  // row 1 761  XFORM( 0, 1 ), xForm[5], XFORM( 2, 1 ), 0, 762  // row 2 763  XFORM( 0, 2 ), XFORM( 1, 2 ), xForm[10], 0, 764  // row 3 765  -( XFORM( 3, 0 ) * xForm[0] + XFORM( 3, 1 ) * XFORM( 0, 1 ) + XFORM( 3, 2 ) * XFORM( 0, 2 ) ), 766  -( XFORM( 3, 0 ) * XFORM( 1, 0 ) + XFORM( 3, 1 ) * xForm[5] + XFORM( 3, 2 ) * XFORM( 1, 2 ) ), 767  -( XFORM( 3, 0 ) * XFORM( 2, 0 ) + XFORM( 3, 1 ) * XFORM( 2, 1 ) + XFORM( 3, 2 ) * xForm[10] ), 1 ); 768 } 769  770 } // namespace moab 771  772 #endif