MOAB: Mesh Oriented datABase
(version 5.4.1)
|
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 #ifndef MB_AXIS_BOX_HPP 00017 #define MB_AXIS_BOX_HPP 00018 00019 #include <limits> 00020 #include "moab/Interface.hpp" 00021 00022 namespace moab 00023 { 00024 00025 /** 00026 * \brief Class representing axis-aligned bounding box 00027 * \author Jason Kraftcheck ([email protected]) 00028 * \date August, 2006 00029 */ 00030 class AxisBox 00031 { 00032 public: 00033 inline AxisBox(); 00034 00035 inline AxisBox( const double* min, const double* max ); 00036 00037 inline AxisBox( const double* point ); 00038 00039 static ErrorCode get_tag( Tag& tag_handle_out, Interface* interface, const char* tag_name = 0 ); 00040 00041 /** Calculate a box bounding the entities contained in the passed set */ 00042 static ErrorCode calculate( AxisBox& box_out, EntityHandle set, Interface* interface ); 00043 00044 /** Calculate a box bounding the vertices/elements in the passed Range */ 00045 static ErrorCode calculate( AxisBox& box_out, const Range& elements, Interface* interface ); 00046 00047 /** intersect */ 00048 inline AxisBox& operator&=( const AxisBox& other ); 00049 00050 /** unite */ 00051 inline AxisBox& operator|=( const AxisBox& other ); 00052 00053 /** unite */ 00054 inline AxisBox& operator|=( const double* point ); 00055 00056 inline const double* minimum() const 00057 { 00058 return minVect; 00059 } 00060 00061 inline const double* maximum() const 00062 { 00063 return maxVect; 00064 } 00065 00066 inline double* minimum() 00067 { 00068 return minVect; 00069 } 00070 00071 inline double* maximum() 00072 { 00073 return maxVect; 00074 } 00075 00076 inline void center( double* center_out ) const; 00077 00078 inline void diagonal( double* diagonal_out ) const; 00079 00080 /**\brief Check if two boxes intersect. 00081 * 00082 * Check if two boxes are within the specified tolerance of 00083 * each other. If tolerance is less than zero, then boxes must 00084 * overlap by at least the magnitude of the tolerance to be 00085 * considered intersecting. 00086 */ 00087 inline bool intersects( const AxisBox& other, double tolerance ) const; 00088 00089 /**\brief Check if box contains point 00090 * 00091 * Check if a position is in or on the box, within the specified tolerance 00092 */ 00093 inline bool intersects( const double* point, double tolerance ) const; 00094 00095 /**\brief Check that box is valid 00096 * 00097 * Check that box is defined (contains at least a single point.) 00098 */ 00099 inline bool valid() const; 00100 00101 /**\brief Find closest position on/within box to input position. 00102 * 00103 * Find the closest position in the solid box to the input position. 00104 * If the input position is on or within the box, then the output 00105 * position will be the same as the input position. If the input 00106 * position is outside the box, the outside position will be the 00107 * closest point on the box boundary to the input position. 00108 */ 00109 inline void closest_position_within_box( const double* input_position, double* output_position ) const; 00110 00111 private: 00112 double minVect[3], maxVect[3]; 00113 }; 00114 00115 /** intersect */ 00116 inline AxisBox operator&( const AxisBox& a, const AxisBox& b ) 00117 { 00118 return AxisBox( a ) &= b; 00119 } 00120 00121 /** unite */ 00122 inline AxisBox operator|( const AxisBox& a, const AxisBox& b ) 00123 { 00124 return AxisBox( a ) |= b; 00125 } 00126 00127 /** intersects */ 00128 inline bool operator||( const AxisBox& a, const AxisBox& b ) 00129 { 00130 return a.minimum()[0] <= b.maximum()[0] && a.minimum()[1] <= b.maximum()[1] && a.minimum()[2] <= b.maximum()[2] && 00131 a.maximum()[0] >= b.minimum()[0] && a.maximum()[1] >= b.minimum()[1] && a.maximum()[2] >= b.minimum()[2]; 00132 } 00133 00134 inline AxisBox::AxisBox() 00135 { 00136 minVect[0] = minVect[1] = minVect[2] = std::numeric_limits< double >::max(); 00137 maxVect[0] = maxVect[1] = maxVect[2] = -std::numeric_limits< double >::max(); 00138 } 00139 00140 inline AxisBox::AxisBox( const double* min, const double* max ) 00141 { 00142 minVect[0] = min[0]; 00143 minVect[1] = min[1]; 00144 minVect[2] = min[2]; 00145 maxVect[0] = max[0]; 00146 maxVect[1] = max[1]; 00147 maxVect[2] = max[2]; 00148 } 00149 00150 inline AxisBox::AxisBox( const double* point ) 00151 { 00152 minVect[0] = maxVect[0] = point[0]; 00153 minVect[1] = maxVect[1] = point[1]; 00154 minVect[2] = maxVect[2] = point[2]; 00155 } 00156 00157 inline AxisBox& AxisBox::operator&=( const AxisBox& other ) 00158 { 00159 for( int i = 0; i < 3; ++i ) 00160 { 00161 if( minVect[i] < other.minVect[i] ) minVect[i] = other.minVect[i]; 00162 if( maxVect[i] > other.maxVect[i] ) maxVect[i] = other.maxVect[i]; 00163 } 00164 return *this; 00165 } 00166 00167 inline AxisBox& AxisBox::operator|=( const AxisBox& other ) 00168 { 00169 for( int i = 0; i < 3; ++i ) 00170 { 00171 if( minVect[i] > other.minVect[i] ) minVect[i] = other.minVect[i]; 00172 if( maxVect[i] < other.maxVect[i] ) maxVect[i] = other.maxVect[i]; 00173 } 00174 return *this; 00175 } 00176 00177 inline AxisBox& AxisBox::operator|=( const double* point ) 00178 { 00179 for( int i = 0; i < 3; ++i ) 00180 { 00181 if( minVect[i] > point[i] ) minVect[i] = point[i]; 00182 if( maxVect[i] < point[i] ) maxVect[i] = point[i]; 00183 } 00184 return *this; 00185 } 00186 00187 inline void AxisBox::center( double* center_out ) const 00188 { 00189 center_out[0] = 0.5 * ( minVect[0] + maxVect[0] ); 00190 center_out[1] = 0.5 * ( minVect[1] + maxVect[1] ); 00191 center_out[2] = 0.5 * ( minVect[2] + maxVect[2] ); 00192 } 00193 00194 inline void AxisBox::diagonal( double* diagonal_out ) const 00195 { 00196 diagonal_out[0] = maxVect[0] - minVect[0]; 00197 diagonal_out[1] = maxVect[1] - minVect[1]; 00198 diagonal_out[2] = maxVect[2] - minVect[2]; 00199 } 00200 00201 inline bool AxisBox::intersects( const AxisBox& other, double tolerance ) const 00202 { 00203 return minVect[0] - other.maxVect[0] <= tolerance && minVect[1] - other.maxVect[1] <= tolerance && 00204 minVect[2] - other.maxVect[2] <= tolerance && other.minVect[0] - maxVect[0] <= tolerance && 00205 other.minVect[1] - maxVect[1] <= tolerance && other.minVect[2] - maxVect[2] <= tolerance; 00206 } 00207 00208 inline bool AxisBox::intersects( const double* point, double tolerance ) const 00209 { 00210 return minVect[0] - point[0] <= tolerance && minVect[1] - point[1] <= tolerance && 00211 minVect[2] - point[2] <= tolerance && maxVect[0] - point[0] <= tolerance && 00212 maxVect[1] - point[1] <= tolerance && maxVect[2] - point[2] <= tolerance; 00213 } 00214 00215 inline bool AxisBox::valid() const 00216 { 00217 return minVect[0] <= maxVect[0] && minVect[1] <= maxVect[1] && minVect[2] <= maxVect[2]; 00218 } 00219 00220 inline void AxisBox::closest_position_within_box( const double* input_position, double* output_position ) const 00221 { 00222 for( int i = 0; i < 3; ++i ) 00223 { 00224 if( input_position[i] < minVect[i] ) 00225 output_position[i] = minVect[i]; 00226 else if( input_position[i] > maxVect[i] ) 00227 output_position[i] = maxVect[i]; 00228 else 00229 output_position[i] = input_position[i]; 00230 } 00231 } 00232 00233 } // namespace moab 00234 00235 #endif