Mesh Oriented datABase
(version 5.4.1)
Array-based unstructured mesh datastructure
|
00001 /** 00002 * MOAB, a Mesh-Oriented datABase, is a software component for creating, 00003 * storing and accessing finite element mesh data. 00004 * 00005 * Copyright 2004 Sandia Corporation. Under the terms of Contract 00006 * DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government 00007 * retains certain rights in this software. 00008 * 00009 * This library is free software; you can redistribute it and/or 00010 * modify it under the terms of the GNU Lesser General Public 00011 * License as published by the Free Software Foundation; either 00012 * version 2.1 of the License, or (at your option) any later version. 00013 * 00014 */ 00015 00016 /** 00017 * \class AffineXform 00018 * \brief Define an affine transformatino 00019 * \author Jason Kraftcheck ([email protected]) 00020 * \date August, 2006 00021 */ 00022 00023 #ifdef WIN32 /* windows */ 00024 #define _USE_MATH_DEFINES // For M_PI 00025 #endif 00026 00027 #include "AffineXform.hpp" 00028 #include "moab/Interface.hpp" 00029 #include <cassert> 00030 00031 namespace moab 00032 { 00033 00034 // Don't include tag-related stuff in test build because we don't 00035 // link to MOAB to test all other functionality. 00036 const char* const AFFINE_XFORM_TAG_NAME = "AFFINE_TRANSFORM"; 00037 00038 ErrorCode AffineXform::get_tag( Tag& tag_out, Interface* interface, const char* tagname ) 00039 { 00040 assert( sizeof( AffineXform ) == 12 * sizeof( double ) ); 00041 00042 if( !tagname ) tagname = AFFINE_XFORM_TAG_NAME; 00043 00044 return interface->tag_get_handle( tagname, sizeof( AffineXform ), MB_TYPE_DOUBLE, tag_out, 00045 MB_TAG_BYTES | MB_TAG_CREAT | MB_TAG_DENSE ); 00046 } 00047 00048 AffineXform AffineXform::rotation( const double* from_vec, const double* to_vec ) 00049 { 00050 CartVect from( from_vec ); 00051 CartVect to( to_vec ); 00052 CartVect a = from * to; 00053 double len = a.length(); 00054 00055 // If input vectors are not parallel (the normal case) 00056 if( len >= std::numeric_limits< double >::epsilon() ) 00057 { 00058 from.normalize(); 00059 to.normalize(); 00060 return rotation( from % to, ( from * to ).length(), a / len ); 00061 } 00062 00063 // Vectors are parallel: 00064 // 00065 // If vectors are in same direction then rotation is identity (no transform) 00066 if( from % to >= 0.0 ) return AffineXform(); 00067 00068 // Parallel vectors in opposite directions: 00069 // 00070 // NOTE: This case is ill-defined. There are infinitely 00071 // many rotations that can align the two vectors. The angle 00072 // of rotation is 180 degrees, but the axis of rotation may 00073 // be any unit vector orthogonal to the input vectors. 00074 // 00075 from.normalize(); 00076 double lenxy = std::sqrt( from[0] * from[0] + from[1] * from[1] ); 00077 CartVect axis( -from[0] * from[2] / lenxy, -from[1] * from[2] / lenxy, lenxy ); 00078 return rotation( -1, 0, axis ); 00079 } 00080 00081 } // namespace moab