Mesh Oriented datABase  (version 5.5.0)
An array-based unstructured mesh library
AffineXform.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 /**
17  * \class AffineXform
18  * \brief Define an affine transformatino
19  * \author Jason Kraftcheck ([email protected])
20  * \date August, 2006
21  */
22 
23 #ifdef WIN32 /* windows */
24 #define _USE_MATH_DEFINES // For M_PI
25 #endif
26 
27 #include "AffineXform.hpp"
28 #include "moab/Interface.hpp"
29 #include <cassert>
30 
31 namespace moab
32 {
33 
34 // Don't include tag-related stuff in test build because we don't
35 // link to MOAB to test all other functionality.
36 const char* const AFFINE_XFORM_TAG_NAME = "AFFINE_TRANSFORM";
37 
38 ErrorCode AffineXform::get_tag( Tag& tag_out, Interface* interface, const char* tagname )
39 {
40  assert( sizeof( AffineXform ) == 12 * sizeof( double ) );
41 
42  if( !tagname ) tagname = AFFINE_XFORM_TAG_NAME;
43 
44  return interface->tag_get_handle( tagname, sizeof( AffineXform ), MB_TYPE_DOUBLE, tag_out,
46 }
47 
48 AffineXform AffineXform::rotation( const double* from_vec, const double* to_vec )
49 {
50  CartVect from( from_vec );
51  CartVect to( to_vec );
52  CartVect a = from * to;
53  double len = a.length();
54 
55  // If input vectors are not parallel (the normal case)
56  if( len >= std::numeric_limits< double >::epsilon() )
57  {
58  from.normalize();
59  to.normalize();
60  return rotation( from % to, ( from * to ).length(), a / len );
61  }
62 
63  // Vectors are parallel:
64  //
65  // If vectors are in same direction then rotation is identity (no transform)
66  if( from % to >= 0.0 ) return AffineXform();
67 
68  // Parallel vectors in opposite directions:
69  //
70  // NOTE: This case is ill-defined. There are infinitely
71  // many rotations that can align the two vectors. The angle
72  // of rotation is 180 degrees, but the axis of rotation may
73  // be any unit vector orthogonal to the input vectors.
74  //
75  from.normalize();
76  double lenxy = std::sqrt( from[0] * from[0] + from[1] * from[1] );
77  CartVect axis( -from[0] * from[2] / lenxy, -from[1] * from[2] / lenxy, lenxy );
78  return rotation( -1, 0, axis );
79 }
80 
81 } // namespace moab