![]() |
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 (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
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