Branch data Line data Source code
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 <assert.h>
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 : 0 : ErrorCode AffineXform::get_tag( Tag& tag_out, Interface* interface, const char* tagname )
39 : : {
40 [ # # ]: 0 : assert( sizeof( AffineXform ) == 12 * sizeof( double ) );
41 : :
42 [ # # ]: 0 : if( !tagname ) tagname = AFFINE_XFORM_TAG_NAME;
43 : :
44 : : return interface->tag_get_handle( tagname, sizeof( AffineXform ), MB_TYPE_DOUBLE, tag_out,
45 : 0 : MB_TAG_BYTES | MB_TAG_CREAT | MB_TAG_DENSE );
46 : : }
47 : :
48 : 2 : AffineXform AffineXform::rotation( const double* from_vec, const double* to_vec )
49 : : {
50 [ + - ]: 2 : CartVect from( from_vec );
51 [ + - ]: 2 : CartVect to( to_vec );
52 [ + - ]: 2 : CartVect a = from * to;
53 [ + - ]: 2 : double len = a.length();
54 : :
55 : : // If input vectors are not parallel (the normal case)
56 [ + + ]: 2 : if( len >= std::numeric_limits< double >::epsilon() )
57 : : {
58 [ + - ]: 1 : from.normalize();
59 [ + - ]: 1 : to.normalize();
60 [ + - ][ + - ]: 1 : 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 [ + - ][ - + ]: 1 : 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 [ + - ]: 1 : from.normalize();
76 [ + - ][ + - ]: 1 : double lenxy = std::sqrt( from[0] * from[0] + from[1] * from[1] );
[ + - ][ + - ]
77 [ + - ][ + - ]: 1 : CartVect axis( -from[0] * from[2] / lenxy, -from[1] * from[2] / lenxy, lenxy );
[ + - ][ + - ]
[ + - ]
78 [ + - ]: 2 : return rotation( -1, 0, axis );
79 : : }
80 : :
81 [ + - ][ + - ]: 4 : } // namespace moab
|