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 (kraftche@cae.wisc.edu)
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,
45 MB_TAG_BYTES | MB_TAG_CREAT | MB_TAG_DENSE );
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