moab
moab::HomXform Class Reference

Homogeneous coordinate transformation matrix. More...

#include <HomXform.hpp>

List of all members.

Public Member Functions

 HomXform (const int matrix[16])
 constructor from matrix
 HomXform ()
 bare constructor
 HomXform (const int rotate[9], const int scale[3], const int translate[3])
 constructor from rotation, scaling, translation
 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, int i13, int i14, int i15, int i16)
 constructor taking 16 ints, useful for efficient operators
HomXform inverse () const
 return this.inverse
void three_pt_xform (const HomCoord &p1, const HomCoord &q1, const HomCoord &p2, const HomCoord &q2, const HomCoord &p3, const HomCoord &q3)
 compute a transform from three points
int operator[] (const int &count) const
 operators
int & operator[] (const int &count)
bool operator== (const HomXform &rhs) const
bool operator!= (const HomXform &rhs) const
HomXformoperator= (const HomXform &rhs)
HomXformoperator*= (const HomXform &rhs)
HomXform operator* (const HomXform &rhs2) const

Static Public Attributes

static HomXform IDENTITY

Private Attributes

int xForm [16]

Friends

class HomCoord

Detailed Description

Homogeneous coordinate transformation matrix.

Definition at line 129 of file HomXform.hpp.


Constructor & Destructor Documentation

moab::HomXform::HomXform ( const int  matrix[16]) [inline]

constructor from matrix

Definition at line 483 of file HomXform.hpp.

{
  for (int i = 0; i < 16; i++)
    xForm[i] = matrix[i];
}

bare constructor

Definition at line 489 of file HomXform.hpp.

{
}
moab::HomXform::HomXform ( const int  rotate[9],
const int  scale[3],
const int  translate[3] 
) [inline]

constructor from rotation, scaling, translation

Definition at line 493 of file HomXform.hpp.

{
  int i, j;
  for (i = 0; i < 3; i++) {
    for (j = 0; j < 3; j++)
      xForm[i*4+j] = rotate[i*3+j]*scale[j];

    xForm[12+i] = translate[i];
  }
  xForm[3] = 0;
  xForm[7] = 0;
  xForm[11] = 0;
  xForm[15] = 1;
  
}
moab::HomXform::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,
int  i13,
int  i14,
int  i15,
int  i16 
) [inline]

constructor taking 16 ints, useful for efficient operators

Definition at line 510 of file HomXform.hpp.

{
  xForm[0] = i1; xForm[1] = i2; xForm[2] = i3; xForm[3] = i4;
  xForm[4] = i5; xForm[5] = i6; xForm[6] = i7; xForm[7] = i8;
  xForm[8] = i9; xForm[9] = i10; xForm[10] = i11; xForm[11] = i12;
  xForm[12] = i13; xForm[13] = i14; xForm[14] = i15; xForm[15] = i16;
}

Member Function Documentation

HomXform moab::HomXform::inverse ( ) const [inline]

return this.inverse

Definition at line 683 of file HomXform.hpp.

{

/*
// original code:

  HomXform tmp;
  
    // assign the diagonal
  tmp[0] = xForm[0];
  tmp[5] = xForm[5];
  tmp[10] = xForm[10];
  tmp[15] = xForm[15];
  
    // invert the rotation matrix
  tmp[XFORM_INDEX(0,1)] = XFORM(1,0);
  tmp[XFORM_INDEX(0,2)] = XFORM(2,0);
  tmp[XFORM_INDEX(1,0)] = XFORM(0,1);
  tmp[XFORM_INDEX(1,2)] = XFORM(2,1);
  tmp[XFORM_INDEX(2,0)] = XFORM(0,2);
  tmp[XFORM_INDEX(2,1)] = XFORM(1,2);

    // negative translate * Rinv
  tmp[XFORM_INDEX(3,0)] = -(XFORM(3,0)*tmp.XFORM(0,0) + XFORM(3,1)*tmp.XFORM(1,0) + XFORM(3,2)*tmp.XFORM(2,0));
  tmp[XFORM_INDEX(3,1)] = -(XFORM(3,0)*tmp.XFORM(0,1) + XFORM(3,1)*tmp.XFORM(1,1) + XFORM(3,2)*tmp.XFORM(2,1));
  tmp[XFORM_INDEX(3,2)] = -(XFORM(3,0)*tmp.XFORM(0,2) + XFORM(3,1)*tmp.XFORM(1,2) + XFORM(3,2)*tmp.XFORM(2,2));
  
    // zero last column
  tmp[XFORM_INDEX(0,3)] = 0;
  tmp[XFORM_INDEX(1,3)] = 0;
  tmp[XFORM_INDEX(2,3)] = 0;

    // h factor
  tmp[XFORM_INDEX(3,3)] = 1;

  return tmp;
*/

// more efficient, but somewhat confusing (remember, column-major):

  return HomXform(
      // row 0
    xForm[0], XFORM(1,0), XFORM(2,0), 0,
      // row 1
    XFORM(0,1), xForm[5], XFORM(2,1), 0,
      // row 2
    XFORM(0,2), XFORM(1,2), xForm[10], 0,
      // row 3
    -(XFORM(3,0)*xForm[0] + XFORM(3,1)*XFORM(0,1) + XFORM(3,2)*XFORM(0,2)),
    -(XFORM(3,0)*XFORM(1,0) + XFORM(3,1)*xForm[5] + XFORM(3,2)*XFORM(1,2)),
    -(XFORM(3,0)*XFORM(2,0) + XFORM(3,1)*XFORM(2,1) + XFORM(3,2)*xForm[10]),
    1);
}
bool moab::HomXform::operator!= ( const HomXform rhs) const [inline]

Definition at line 670 of file HomXform.hpp.

{
  return (
    xForm[0] != rhs.xForm[0] || xForm[1] != rhs.xForm[1] ||
    xForm[2] != rhs.xForm[2] || xForm[3] != rhs.xForm[3] ||
    xForm[4] != rhs.xForm[4] || xForm[5] != rhs.xForm[5] ||
    xForm[6] != rhs.xForm[6] || xForm[7] != rhs.xForm[7] ||
    xForm[8] != rhs.xForm[8] || xForm[9] != rhs.xForm[9] ||
    xForm[10] != rhs.xForm[10] || xForm[11] != rhs.xForm[11] ||
    xForm[12] != rhs.xForm[12] || xForm[13] != rhs.xForm[13] ||
    xForm[14] != rhs.xForm[14] || xForm[15] != rhs.xForm[15]);
}
HomXform moab::HomXform::operator* ( const HomXform rhs2) const [inline]

Definition at line 529 of file HomXform.hpp.

{
  return HomXform(
//  temp.XFORM(0,0)
    XFORM(0,0)*rhs2.XFORM(0,0) + XFORM(0,1)*rhs2.XFORM(1,0) + 
    XFORM(0,2)*rhs2.XFORM(2,0) + XFORM(0,3)*rhs2.XFORM(3,0),
//  temp.XFORM(0,1)  
    XFORM(0,0)*rhs2.XFORM(0,1) + XFORM(0,1)*rhs2.XFORM(1,1) + 
    XFORM(0,2)*rhs2.XFORM(2,1) + XFORM(0,3)*rhs2.XFORM(3,1),
//  temp.XFORM(0,2)  
    XFORM(0,0)*rhs2.XFORM(0,2) + XFORM(0,1)*rhs2.XFORM(1,2) + 
    XFORM(0,2)*rhs2.XFORM(2,2) + XFORM(0,3)*rhs2.XFORM(3,2),
//  temp.XFORM(0,3)  
    XFORM(0,0)*rhs2.XFORM(0,3) + XFORM(0,1)*rhs2.XFORM(1,3) + 
    XFORM(0,2)*rhs2.XFORM(2,3) + XFORM(0,3)*rhs2.XFORM(3,3),

//  temp.XFORM(1,0)  
    XFORM(1,0)*rhs2.XFORM(0,0) + XFORM(1,1)*rhs2.XFORM(1,0) + 
    XFORM(1,2)*rhs2.XFORM(2,0) + XFORM(1,3)*rhs2.XFORM(3,0),
//  temp.XFORM(1,1)  
    XFORM(1,0)*rhs2.XFORM(0,1) + XFORM(1,1)*rhs2.XFORM(1,1) + 
    XFORM(1,2)*rhs2.XFORM(2,1) + XFORM(1,3)*rhs2.XFORM(3,1),
//  temp.XFORM(1,2)  
    XFORM(1,0)*rhs2.XFORM(0,2) + XFORM(1,1)*rhs2.XFORM(1,2) + 
    XFORM(1,2)*rhs2.XFORM(2,2) + XFORM(1,3)*rhs2.XFORM(3,2),
//  temp.XFORM(1,3)  
    XFORM(1,0)*rhs2.XFORM(0,3) + XFORM(1,1)*rhs2.XFORM(1,3) + 
    XFORM(1,2)*rhs2.XFORM(2,3) + XFORM(1,3)*rhs2.XFORM(3,3),

//  temp.XFORM(2,0)  
    XFORM(2,0)*rhs2.XFORM(0,0) + XFORM(2,1)*rhs2.XFORM(1,0) + 
    XFORM(2,2)*rhs2.XFORM(2,0) + XFORM(2,3)*rhs2.XFORM(3,0),
//  temp.XFORM(2,1)  
    XFORM(2,0)*rhs2.XFORM(0,1) + XFORM(2,1)*rhs2.XFORM(1,1) + 
    XFORM(2,2)*rhs2.XFORM(2,1) + XFORM(2,3)*rhs2.XFORM(3,1),
//  temp.XFORM(2,2)  
    XFORM(2,0)*rhs2.XFORM(0,2) + XFORM(2,1)*rhs2.XFORM(1,2) + 
    XFORM(2,2)*rhs2.XFORM(2,2) + XFORM(2,3)*rhs2.XFORM(3,2),
//  temp.XFORM(2,3)  
    XFORM(2,0)*rhs2.XFORM(0,3) + XFORM(2,1)*rhs2.XFORM(1,3) + 
    XFORM(2,2)*rhs2.XFORM(2,3) + XFORM(2,3)*rhs2.XFORM(3,3),

//  temp.XFORM(3,0)  
//  xForm[12]*rhs2.xForm[0] + xForm[13]*rhs2.xForm[4] + xForm[14]*rhs2.xForm[8] + xForm[15]*rhs2.xForm[12]
    XFORM(3,0)*rhs2.XFORM(0,0) + XFORM(3,1)*rhs2.XFORM(1,0) + 
    XFORM(3,2)*rhs2.XFORM(2,0) + XFORM(3,3)*rhs2.XFORM(3,0),
//  temp.XFORM(3,1)  
//  xForm[12]*rhs2.xForm[1] + xForm[13]*rhs2.xForm[5] + xForm[14]*rhs2.xForm[9] + xForm[15]*rhs2.xForm[13]
    XFORM(3,0)*rhs2.XFORM(0,1) + XFORM(3,1)*rhs2.XFORM(1,1) + 
    XFORM(3,2)*rhs2.XFORM(2,1) + XFORM(3,3)*rhs2.XFORM(3,1),
//  temp.XFORM(3,2)  
//  xForm[12]*rhs2.xForm[2] + xForm[13]*rhs2.xForm[6] + xForm[14]*rhs2.xForm[10] + xForm[15]*rhs2.xForm[14]
    XFORM(3,0)*rhs2.XFORM(0,2) + XFORM(3,1)*rhs2.XFORM(1,2) + 
    XFORM(3,2)*rhs2.XFORM(2,2) + XFORM(3,3)*rhs2.XFORM(3,2),
//  temp.XFORM(3,3)  
//  xForm[12]*rhs2.xForm[3] + xForm[13]*rhs2.xForm[7] + xForm[14]*rhs2.xForm[11] + xForm[15]*rhs2.xForm[15]
    XFORM(3,0)*rhs2.XFORM(0,3) + XFORM(3,1)*rhs2.XFORM(1,3) + 
    XFORM(3,2)*rhs2.XFORM(2,3) + XFORM(3,3)*rhs2.XFORM(3,3));
}
HomXform & moab::HomXform::operator*= ( const HomXform rhs) [inline]

Definition at line 589 of file HomXform.hpp.

{
  *this =  HomXform(
//  temp.XFORM(0,0)
    XFORM(0,0)*rhs2.XFORM(0,0) + XFORM(0,1)*rhs2.XFORM(1,0) + 
    XFORM(0,2)*rhs2.XFORM(2,0) + XFORM(0,3)*rhs2.XFORM(3,0),
//  temp.XFORM(0,1)  
    XFORM(0,0)*rhs2.XFORM(0,1) + XFORM(0,1)*rhs2.XFORM(1,1) + 
    XFORM(0,2)*rhs2.XFORM(2,1) + XFORM(0,3)*rhs2.XFORM(3,1),
//  temp.XFORM(0,2)  
    XFORM(0,0)*rhs2.XFORM(0,2) + XFORM(0,1)*rhs2.XFORM(1,2) + 
    XFORM(0,2)*rhs2.XFORM(2,2) + XFORM(0,3)*rhs2.XFORM(3,2),
//  temp.XFORM(0,3)  
    XFORM(0,0)*rhs2.XFORM(0,3) + XFORM(0,1)*rhs2.XFORM(1,3) + 
    XFORM(0,2)*rhs2.XFORM(2,3) + XFORM(0,3)*rhs2.XFORM(3,3),

//  temp.XFORM(1,0)  
    XFORM(1,0)*rhs2.XFORM(0,0) + XFORM(1,1)*rhs2.XFORM(1,0) + 
    XFORM(1,2)*rhs2.XFORM(2,0) + XFORM(1,3)*rhs2.XFORM(3,0),
//  temp.XFORM(1,1)  
    XFORM(1,0)*rhs2.XFORM(0,1) + XFORM(1,1)*rhs2.XFORM(1,1) + 
    XFORM(1,2)*rhs2.XFORM(2,1) + XFORM(1,3)*rhs2.XFORM(3,1),
//  temp.XFORM(1,2)  
    XFORM(1,0)*rhs2.XFORM(0,2) + XFORM(1,1)*rhs2.XFORM(1,2) + 
    XFORM(1,2)*rhs2.XFORM(2,2) + XFORM(1,3)*rhs2.XFORM(3,2),
//  temp.XFORM(1,3)  
    XFORM(1,0)*rhs2.XFORM(0,3) + XFORM(1,1)*rhs2.XFORM(1,3) + 
    XFORM(1,2)*rhs2.XFORM(2,3) + XFORM(1,3)*rhs2.XFORM(3,3),

//  temp.XFORM(2,0)  
    XFORM(2,0)*rhs2.XFORM(0,0) + XFORM(2,1)*rhs2.XFORM(1,0) + 
    XFORM(2,2)*rhs2.XFORM(2,0) + XFORM(2,3)*rhs2.XFORM(3,0),
//  temp.XFORM(2,1)  
    XFORM(2,0)*rhs2.XFORM(0,1) + XFORM(2,1)*rhs2.XFORM(1,1) + 
    XFORM(2,2)*rhs2.XFORM(2,1) + XFORM(2,3)*rhs2.XFORM(3,1),
//  temp.XFORM(2,2)  
    XFORM(2,0)*rhs2.XFORM(0,2) + XFORM(2,1)*rhs2.XFORM(1,2) + 
    XFORM(2,2)*rhs2.XFORM(2,2) + XFORM(2,3)*rhs2.XFORM(3,2),
//  temp.XFORM(2,3)  
    XFORM(2,0)*rhs2.XFORM(0,3) + XFORM(2,1)*rhs2.XFORM(1,3) + 
    XFORM(2,2)*rhs2.XFORM(2,3) + XFORM(2,3)*rhs2.XFORM(3,3),

//  temp.XFORM(3,0)  
    XFORM(3,0)*rhs2.XFORM(0,0) + XFORM(3,1)*rhs2.XFORM(1,0) + 
    XFORM(3,2)*rhs2.XFORM(2,0) + XFORM(3,3)*rhs2.XFORM(3,0),
//  temp.XFORM(3,1)  
    XFORM(3,0)*rhs2.XFORM(0,1) + XFORM(3,1)*rhs2.XFORM(1,1) + 
    XFORM(3,2)*rhs2.XFORM(2,1) + XFORM(3,3)*rhs2.XFORM(3,1),
//  temp.XFORM(3,2)  
    XFORM(3,0)*rhs2.XFORM(0,2) + XFORM(3,1)*rhs2.XFORM(1,2) + 
    XFORM(3,2)*rhs2.XFORM(2,2) + XFORM(3,3)*rhs2.XFORM(3,2),
//  temp.XFORM(3,3)  
    XFORM(3,0)*rhs2.XFORM(0,3) + XFORM(3,1)*rhs2.XFORM(1,3) + 
    XFORM(3,2)*rhs2.XFORM(2,3) + XFORM(3,3)*rhs2.XFORM(3,3));

  return *this;
}
HomXform & moab::HomXform::operator= ( const HomXform rhs) [inline]

Definition at line 521 of file HomXform.hpp.

{
  for (int i = 0; i < 16; i++)
    xForm[i] = rhs.xForm[i];

  return *this;
}
bool moab::HomXform::operator== ( const HomXform rhs) const [inline]

Definition at line 657 of file HomXform.hpp.

{
  return (
    xForm[0] == rhs.xForm[0] && xForm[1] == rhs.xForm[1] &&
    xForm[2] == rhs.xForm[2] && xForm[3] == rhs.xForm[3] &&
    xForm[4] == rhs.xForm[4] && xForm[5] == rhs.xForm[5] &&
    xForm[6] == rhs.xForm[6] && xForm[7] == rhs.xForm[7] &&
    xForm[8] == rhs.xForm[8] && xForm[9] == rhs.xForm[9] &&
    xForm[10] == rhs.xForm[10] && xForm[11] == rhs.xForm[11] &&
    xForm[12] == rhs.xForm[12] && xForm[13] == rhs.xForm[13] &&
    xForm[14] == rhs.xForm[14] && xForm[15] == rhs.xForm[15]);
}
int moab::HomXform::operator[] ( const int &  count) const [inline]

operators

Definition at line 647 of file HomXform.hpp.

{
  return xForm[count];
}
int & moab::HomXform::operator[] ( const int &  count) [inline]

Definition at line 652 of file HomXform.hpp.

{
  return xForm[count];
}
void moab::HomXform::three_pt_xform ( const HomCoord p1,
const HomCoord q1,
const HomCoord p2,
const HomCoord q2,
const HomCoord p3,
const HomCoord q3 
)

compute a transform from three points

Definition at line 30 of file HomXform.cpp.

{
    // pmin and pmax are min and max bounding box corners which are mapped to
    // qmin and qmax, resp.  qmin and qmax are not necessarily min/max corners,
    // since the mapping can change the orientation of the box in the q reference
    // frame.  Re-interpreting the min/max bounding box corners does not change
    // the mapping.

    // change that: base on three points for now (figure out whether we can
    // just use two later); three points are assumed to define an orthogonal
    // system such that (p2-p1)%(p3-p1) = 0
  
    // use the three point rule to compute the mapping, from Mortensen, 
    // "Geometric Modeling".  If p1, p2, p3 and q1, q2, q3 are three points in
    // the two coordinate systems, the three pt rule is:
    //
    // v1 = p2 - p1
    // v2 = p3 - p1
    // v3 = v1 x v2
    // w1-w3 similar, with q1-q3
    // V = matrix with v1-v3 as rows
    // W similar, with w1-w3
    // R = V^-1 * W
    // t = q1 - p1 * W
    // Form transform matrix M from R, t

    // check to see whether unity transform applies
  if (p1 == q1 && p2 == q2 && p3 == q3) {
    *this = HomXform::IDENTITY;
    return;
  }

    // first, construct 3 pts from input
  HomCoord v1 = p2 - p1;
  assert(v1.i() != 0 || v1.j() != 0 || v1.k() != 0);
  HomCoord v2 = p3 - p1;
  HomCoord v3 = v1 * v2;
  
  if (v3.length_squared() == 0) {
      // 1d coordinate system; set one of v2's coordinates such that
      // it's orthogonal to v1
    if (v1.i() == 0) v2.set(1,0,0);
    else if (v1.j() == 0) v2.set(0,1,0);
    else if (v1.k() == 0) v2.set(0,0,1);
    else assert(false);
    v3 = v1 * v2;
    assert(v3.length_squared() != 0);
  }
    // assert to make sure they're each orthogonal
  assert(v1%v2 == 0 && v1%v3 == 0 && v2%v3 == 0);
  v1.normalize(); v2.normalize(); v3.normalize();
    // Make sure h is set to zero here, since it'll mess up things if it's one
  v1.homCoord[3] = v2.homCoord[3] = v3.homCoord[3] = 0;

  HomCoord w1 = q2 - q1;
  assert(w1.i() != 0 || w1.j() != 0 || w1.k() != 0);
  HomCoord w2 = q3 - q1;
  HomCoord w3 = w1 * w2;
  
  if (w3.length_squared() == 0) {
      // 1d coordinate system; set one of w2's coordinates such that
      // it's orthogonal to w1
    if (w1.i() == 0) w2.set(1,0,0);
    else if (w1.j() == 0) w2.set(0,1,0);
    else if (w1.k() == 0) w2.set(0,0,1);
    else assert(false);
    w3 = w1 * w2;
    assert(w3.length_squared() != 0);
  }
    // assert to make sure they're each orthogonal
  assert(w1%w2 == 0 && w1%w3 == 0 && w2%w3 == 0);
  w1.normalize(); w2.normalize(); w3.normalize();
    // Make sure h is set to zero here, since it'll mess up things if it's one
  w1.homCoord[3] = w2.homCoord[3] = w3.homCoord[3] = 0;
  
    // form v^-1 as transpose (ok for orthogonal vectors); put directly into
    // transform matrix, since it's eventually going to become R
  *this = HomXform(v1.i(), v2.i(), v3.i(), 0,
                   v1.j(), v2.j(), v3.j(), 0,
                   v1.k(), v2.k(), v3.k(), 0,
                   0, 0, 0, 1);

    // multiply by w to get R
  *this *= HomXform(w1.i(), w1.j(), w1.k(), 0,
                    w2.i(), w2.j(), w2.k(), 0,
                    w3.i(), w3.j(), w3.k(), 0,
                    0, 0, 0, 1);
  
    // compute t and put into last row
  HomCoord t = q1 - p1 * *this;
  (*this).XFORM(3,0) = t.i();
  (*this).XFORM(3,1) = t.j();
  (*this).XFORM(3,2) = t.k();

    // M should transform p to q
  assert((q1 == p1 * *this) &&
         (q2 == p2 * *this) &&
         (q3 == p3 * *this));
}

Friends And Related Function Documentation

friend class HomCoord [friend]

Definition at line 140 of file HomXform.hpp.


Member Data Documentation

Definition at line 142 of file HomXform.hpp.

int moab::HomXform::xForm[16] [private]

the matrix; don't bother storing the last column, since we assume for now it's always unused

Definition at line 136 of file HomXform.hpp.


The documentation for this class was generated from the following files:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines