moab
OrientedBox.hpp
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 Coroporation, 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 
00021 #ifndef MB_ORIENTED_BOX_HPP
00022 #define MB_ORIENTED_BOX_HPP
00023 
00024 #include "moab/Forward.hpp"
00025 #include "moab/CartVect.hpp"
00026 #include "moab/Matrix3.hpp"
00027 
00028 #include <iosfwd>
00029 
00030 namespace moab {
00031 
00032 #define MB_ORIENTED_BOX_UNIT_VECTORS 1
00033 #define MB_ORIENTED_BOX_OUTER_RADIUS 1
00034 
00035 class Range;
00036 
00037 
00040 class OrientedBox
00041 {
00042 public:
00043   CartVect center;  
00044   CartVect axis[3]; 
00045 #if MB_ORIENTED_BOX_UNIT_VECTORS
00046   CartVect length;  
00047 #endif
00048 #if MB_ORIENTED_BOX_OUTER_RADIUS
00049   double radius;      
00050 #endif
00051 
00052   inline OrientedBox() {}
00053 
00054   OrientedBox( const CartVect axis[3], const CartVect& center );
00055 
00056   inline double inner_radius() const; 
00057   inline double outer_radius() const; 
00058   inline double outer_radius_squared(const double reps) const; 
00059   inline double inner_radius_squared(const double reps) const; 
00060   inline double volume() const;               
00061   inline CartVect dimensions() const;       
00062   inline double area() const;                 
00063   inline CartVect scaled_axis( int index ) const; 
00064   
00066   bool contained( const CartVect& point, double tolerance ) const;
00067   
00068   //bool contained( const OrientedBox& other, double tolerance ) const;
00069   
00081   static ErrorCode tag_handle( Tag& handle_out,
00082                                  Interface* instance, 
00083                                  const char* name);
00084 
00086   static ErrorCode compute_from_vertices( OrientedBox& result,
00087                                             Interface* instance,
00088                                             const Range& vertices );
00089                                   
00091   static ErrorCode compute_from_2d_cells( OrientedBox& result,
00092                                             Interface* instance,
00093                                             const Range& elements );
00094 
00100   struct CovarienceData {
00101     CovarienceData() {}
00102     CovarienceData( const Matrix3& m, const CartVect& c, double a)
00103       : matrix(m), center(c), area(a) {}
00104     Matrix3 matrix;    
00105     CartVect center;   
00106     double area;         
00107   };
00108   
00110   static ErrorCode covariance_data_from_tris( CovarienceData& result,
00111                                                 Interface* moab_instance,
00112                                                 const Range& elements );
00113   
00117   static ErrorCode compute_from_covariance_data( OrientedBox& result,
00118                                           Interface* moab_instance,
00119                                           const CovarienceData* orient_array,
00120                                           unsigned orient_array_length,
00121                                           const Range& vertices );
00122   
00131   bool intersect_ray( const CartVect& ray_start_point,
00132                       const CartVect& ray_unit_direction,
00133                       const double    distance_tolerance,
00134                       const double*   nonnegatve_ray_len = 0,
00135                       const double*   negative_ray_len   = 0 ) const;
00136                       
00145   void closest_location_in_box( const CartVect& input_position,
00146                                 CartVect& output_position ) const;
00147                       
00149   ErrorCode make_hex( EntityHandle& hex, Interface* instance );
00150                                     
00151   
00155   static ErrorCode compute_from_covariance_data( OrientedBox& result,
00156                                           Interface* moab_instance,
00157                                           CovarienceData& orientation_data,
00158                                           const Range& vertices );
00159 };
00160 
00161 std::ostream& operator<<( std::ostream&, const OrientedBox& );
00162 
00163 double OrientedBox::inner_radius() const
00164 {
00165 #if MB_ORIENTED_BOX_UNIT_VECTORS
00166   return length[0];
00167 #else
00168   return axis[0].length();
00169 #endif
00170 }
00171 
00172 double OrientedBox::outer_radius() const
00173 {
00174 #if MB_ORIENTED_BOX_OUTER_RADIUS
00175   return radius;
00176 #elif MB_ORIENTED_BOX_UNIT_VECTORS
00177   return length.length();
00178 #else
00179   return (axis[0] + axis[1] + axis[2]).length();
00180 #endif
00181 }
00182 
00183 // Add at least epsilon to the radius, before squaring it.
00184 double OrientedBox::outer_radius_squared(const double reps) const
00185 {
00186 #if MB_ORIENTED_BOX_OUTER_RADIUS
00187   return (radius+reps)*(radius+reps);
00188 #elif MB_ORIENTED_BOX_UNIT_VECTORS
00189   CartVect tmp(length[0]+reps,length[1]+reps,length[2]+reps);
00190   return tmp % tmp;
00191 #else
00192   CartVect half_diag = axis[0] + axis[1] + axis[2];
00193   half_diag += CartVect(reps,reps,reps);
00194   return half_diag % half_diag;
00195 #endif
00196 }
00197 
00198 // Subtract epsilon from the length of the shortest axis, before squaring it.
00199 double OrientedBox::inner_radius_squared(const double reps) const
00200 {
00201 #if MB_ORIENTED_BOX_UNIT_VECTORS
00202   return (length[0]-reps) * (length[0]-reps);
00203 #else
00204   CartVect tmp = axis[0];
00205   tmp -= CartVect(reps,reps,reps);
00206   return (tmp % tmp);
00207 #endif
00208 }
00209 
00210 double OrientedBox::volume() const
00211 {
00212 #if MB_ORIENTED_BOX_UNIT_VECTORS
00213   return 8 * length[0] * length[1] * length[2];
00214 #else
00215   return fabs(8 * axis[0] % (axis[1] * axis[2]));
00216 #endif
00217 }
00218 
00219 CartVect OrientedBox::dimensions() const
00220 {
00221 #if MB_ORIENTED_BOX_UNIT_VECTORS
00222   return 2.0 * length;
00223 #else
00224   return 2.0 * CartVect( axis[0].length(), axis[1].length(), axis[2].length() );
00225 #endif
00226 }
00227 
00228 double OrientedBox::area() const
00229 {
00230 #if MB_ORIENTED_BOX_UNIT_VECTORS
00231   return 4 * length[1] * length[2];
00232 #else
00233   return 4 * (axis[1] * axis[2]).length();
00234 #endif
00235 }
00236 
00237 CartVect OrientedBox::scaled_axis( int index ) const
00238 {
00239 #if MB_ORIENTED_BOX_UNIT_VECTORS
00240   return length[index] * axis[index];
00241 #else
00242   return axis[index];
00243 #endif
00244 }
00245   
00246 } // namespace moab
00247 
00248 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines