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.cpp
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 #include "moab/HomXform.hpp" 17 #include <cassert> 18  19 namespace moab 20 { 21  22 HomCoord HomCoord::unitv[3] = { HomCoord( 1, 0, 0 ), HomCoord( 0, 1, 0 ), HomCoord( 0, 0, 1 ) }; 23 HomCoord HomCoord::IDENTITY( 1, 1, 1 ); 24  25 HomCoord& HomCoord::getUnitv( int c ) 26 { 27  return unitv[c]; 28 } 29  30 int dum[] = { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 }; 31 HomXform HomXform::IDENTITY( dum ); 32  33 void HomXform::three_pt_xform( const HomCoord& p1, 34  const HomCoord& q1, 35  const HomCoord& p2, 36  const HomCoord& q2, 37  const HomCoord& p3, 38  const HomCoord& q3 ) 39 { 40  // pmin and pmax are min and max bounding box corners which are mapped to 41  // qmin and qmax, resp. qmin and qmax are not necessarily min/max corners, 42  // since the mapping can change the orientation of the box in the q reference 43  // frame. Re-interpreting the min/max bounding box corners does not change 44  // the mapping. 45  46  // change that: base on three points for now (figure out whether we can 47  // just use two later); three points are assumed to define an orthogonal 48  // system such that (p2-p1)%(p3-p1) = 0 49  50  // use the three point rule to compute the mapping, from Mortensen, 51  // "Geometric Modeling". If p1, p2, p3 and q1, q2, q3 are three points in 52  // the two coordinate systems, the three pt rule is: 53  // 54  // v1 = p2 - p1 55  // v2 = p3 - p1 56  // v3 = v1 x v2 57  // w1-w3 similar, with q1-q3 58  // V = matrix with v1-v3 as rows 59  // W similar, with w1-w3 60  // R = V^-1 * W 61  // t = q1 - p1 * W 62  // Form transform matrix M from R, t 63  64  // check to see whether unity transform applies 65  if( p1 == q1 && p2 == q2 && p3 == q3 ) 66  { 67  *this = HomXform::IDENTITY; 68  return; 69  } 70  71  // first, construct 3 pts from input 72  HomCoord v1 = p2 - p1; 73  assert( v1.i() != 0 || v1.j() != 0 || v1.k() != 0 ); 74  HomCoord v2 = p3 - p1; 75  HomCoord v3 = v1 * v2; 76  77  if( v3.length_squared() == 0 ) 78  { 79  // 1d coordinate system; set one of v2's coordinates such that 80  // it's orthogonal to v1 81  if( v1.i() == 0 ) 82  v2.set( 1, 0, 0 ); 83  else if( v1.j() == 0 ) 84  v2.set( 0, 1, 0 ); 85  else if( v1.k() == 0 ) 86  v2.set( 0, 0, 1 ); 87  else 88  assert( false ); 89  v3 = v1 * v2; 90  assert( v3.length_squared() != 0 ); 91  } 92  // assert to make sure they're each orthogonal 93  assert( v1 % v2 == 0 && v1 % v3 == 0 && v2 % v3 == 0 ); 94  v1.normalize(); 95  v2.normalize(); 96  v3.normalize(); 97  // Make sure h is set to zero here, since it'll mess up things if it's one 98  v1.homCoord[3] = v2.homCoord[3] = v3.homCoord[3] = 0; 99  100  HomCoord w1 = q2 - q1; 101  assert( w1.i() != 0 || w1.j() != 0 || w1.k() != 0 ); 102  HomCoord w2 = q3 - q1; 103  HomCoord w3 = w1 * w2; 104  105  if( w3.length_squared() == 0 ) 106  { 107  // 1d coordinate system; set one of w2's coordinates such that 108  // it's orthogonal to w1 109  if( w1.i() == 0 ) 110  w2.set( 1, 0, 0 ); 111  else if( w1.j() == 0 ) 112  w2.set( 0, 1, 0 ); 113  else if( w1.k() == 0 ) 114  w2.set( 0, 0, 1 ); 115  else 116  assert( false ); 117  w3 = w1 * w2; 118  assert( w3.length_squared() != 0 ); 119  } 120  // assert to make sure they're each orthogonal 121  assert( w1 % w2 == 0 && w1 % w3 == 0 && w2 % w3 == 0 ); 122  w1.normalize(); 123  w2.normalize(); 124  w3.normalize(); 125  // Make sure h is set to zero here, since it'll mess up things if it's one 126  w1.homCoord[3] = w2.homCoord[3] = w3.homCoord[3] = 0; 127  128  // form v^-1 as transpose (ok for orthogonal vectors); put directly into 129  // transform matrix, since it's eventually going to become R 130  *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 ); 131  132  // multiply by w to get R 133  *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 ); 134  135  // compute t and put into last row 136  HomCoord t = q1 - p1 * *this; 137  ( *this ).XFORM( 3, 0 ) = t.i(); 138  ( *this ).XFORM( 3, 1 ) = t.j(); 139  ( *this ).XFORM( 3, 2 ) = t.k(); 140  141  // M should transform p to q 142  assert( ( q1 == p1 * *this ) && ( q2 == p2 * *this ) && ( q3 == p3 * *this ) ); 143 } 144  145 } // namespace moab