MOAB: Mesh Oriented datABase  (version 5.3.0)
AffineXform.cpp
Go to the documentation of this file.
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 (kraftche@cae.wisc.edu)
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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines