Mesh Oriented datABase  (version 5.5.0)
An array-based unstructured mesh library
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 
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 
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 
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 
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 
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 
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