Mesh Oriented datABase  (version 5.5.0)
An array-based unstructured mesh library
AxisBox.hpp
Go to the documentation of this file.
1 /**
2  * MOAB, a Mesh-Oriented datABase, is a software component for creating,
3  * storing and accessing finite element mesh data.
4  *
5  * Copyright 2004 Sandia Corporation. Under the terms of Contract
6  * DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government
7  * retains certain rights in this software.
8  *
9  * This library is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public
11  * License as published by the Free Software Foundation; either
12  * version 2.1 of the License, or (at your option) any later version.
13  *
14  */
15 
16 #ifndef MB_AXIS_BOX_HPP
17 #define MB_AXIS_BOX_HPP
18 
19 #include <limits>
20 #include "moab/Interface.hpp"
21 
22 namespace moab
23 {
24 
25 /**
26  * \brief Class representing axis-aligned bounding box
27  * \author Jason Kraftcheck ([email protected])
28  * \date August, 2006
29  */
30 class AxisBox
31 {
32  public:
33  inline AxisBox();
34 
35  inline AxisBox( const double* min, const double* max );
36 
37  inline AxisBox( const double* point );
38 
39  static ErrorCode get_tag( Tag& tag_handle_out, Interface* interface, const char* tag_name = 0 );
40 
41  /** Calculate a box bounding the entities contained in the passed set */
42  static ErrorCode calculate( AxisBox& box_out, EntityHandle set, Interface* interface );
43 
44  /** Calculate a box bounding the vertices/elements in the passed Range */
45  static ErrorCode calculate( AxisBox& box_out, const Range& elements, Interface* interface );
46 
47  /** intersect */
48  inline AxisBox& operator&=( const AxisBox& other );
49 
50  /** unite */
51  inline AxisBox& operator|=( const AxisBox& other );
52 
53  /** unite */
54  inline AxisBox& operator|=( const double* point );
55 
56  inline const double* minimum() const
57  {
58  return minVect;
59  }
60 
61  inline const double* maximum() const
62  {
63  return maxVect;
64  }
65 
66  inline double* minimum()
67  {
68  return minVect;
69  }
70 
71  inline double* maximum()
72  {
73  return maxVect;
74  }
75 
76  inline void center( double* center_out ) const;
77 
78  inline void diagonal( double* diagonal_out ) const;
79 
80  /**\brief Check if two boxes intersect.
81  *
82  * Check if two boxes are within the specified tolerance of
83  * each other. If tolerance is less than zero, then boxes must
84  * overlap by at least the magnitude of the tolerance to be
85  * considered intersecting.
86  */
87  inline bool intersects( const AxisBox& other, double tolerance ) const;
88 
89  /**\brief Check if box contains point
90  *
91  * Check if a position is in or on the box, within the specified tolerance
92  */
93  inline bool intersects( const double* point, double tolerance ) const;
94 
95  /**\brief Check that box is valid
96  *
97  * Check that box is defined (contains at least a single point.)
98  */
99  inline bool valid() const;
100 
101  /**\brief Find closest position on/within box to input position.
102  *
103  * Find the closest position in the solid box to the input position.
104  * If the input position is on or within the box, then the output
105  * position will be the same as the input position. If the input
106  * position is outside the box, the outside position will be the
107  * closest point on the box boundary to the input position.
108  */
109  inline void closest_position_within_box( const double* input_position, double* output_position ) const;
110 
111  private:
112  double minVect[3], maxVect[3];
113 };
114 
115 /** intersect */
116 inline AxisBox operator&( const AxisBox& a, const AxisBox& b )
117 {
118  return AxisBox( a ) &= b;
119 }
120 
121 /** unite */
122 inline AxisBox operator|( const AxisBox& a, const AxisBox& b )
123 {
124  return AxisBox( a ) |= b;
125 }
126 
127 /** intersects */
128 inline bool operator||( const AxisBox& a, const AxisBox& b )
129 {
130  return a.minimum()[0] <= b.maximum()[0] && a.minimum()[1] <= b.maximum()[1] && a.minimum()[2] <= b.maximum()[2] &&
131  a.maximum()[0] >= b.minimum()[0] && a.maximum()[1] >= b.minimum()[1] && a.maximum()[2] >= b.minimum()[2];
132 }
133 
135 {
136  minVect[0] = minVect[1] = minVect[2] = std::numeric_limits< double >::max();
137  maxVect[0] = maxVect[1] = maxVect[2] = -std::numeric_limits< double >::max();
138 }
139 
140 inline AxisBox::AxisBox( const double* min, const double* max )
141 {
142  minVect[0] = min[0];
143  minVect[1] = min[1];
144  minVect[2] = min[2];
145  maxVect[0] = max[0];
146  maxVect[1] = max[1];
147  maxVect[2] = max[2];
148 }
149 
150 inline AxisBox::AxisBox( const double* point )
151 {
152  minVect[0] = maxVect[0] = point[0];
153  minVect[1] = maxVect[1] = point[1];
154  minVect[2] = maxVect[2] = point[2];
155 }
156 
157 inline AxisBox& AxisBox::operator&=( const AxisBox& other )
158 {
159  for( int i = 0; i < 3; ++i )
160  {
161  if( minVect[i] < other.minVect[i] ) minVect[i] = other.minVect[i];
162  if( maxVect[i] > other.maxVect[i] ) maxVect[i] = other.maxVect[i];
163  }
164  return *this;
165 }
166 
167 inline AxisBox& AxisBox::operator|=( const AxisBox& other )
168 {
169  for( int i = 0; i < 3; ++i )
170  {
171  if( minVect[i] > other.minVect[i] ) minVect[i] = other.minVect[i];
172  if( maxVect[i] < other.maxVect[i] ) maxVect[i] = other.maxVect[i];
173  }
174  return *this;
175 }
176 
177 inline AxisBox& AxisBox::operator|=( const double* point )
178 {
179  for( int i = 0; i < 3; ++i )
180  {
181  if( minVect[i] > point[i] ) minVect[i] = point[i];
182  if( maxVect[i] < point[i] ) maxVect[i] = point[i];
183  }
184  return *this;
185 }
186 
187 inline void AxisBox::center( double* center_out ) const
188 {
189  center_out[0] = 0.5 * ( minVect[0] + maxVect[0] );
190  center_out[1] = 0.5 * ( minVect[1] + maxVect[1] );
191  center_out[2] = 0.5 * ( minVect[2] + maxVect[2] );
192 }
193 
194 inline void AxisBox::diagonal( double* diagonal_out ) const
195 {
196  diagonal_out[0] = maxVect[0] - minVect[0];
197  diagonal_out[1] = maxVect[1] - minVect[1];
198  diagonal_out[2] = maxVect[2] - minVect[2];
199 }
200 
201 inline bool AxisBox::intersects( const AxisBox& other, double tolerance ) const
202 {
203  return minVect[0] - other.maxVect[0] <= tolerance && minVect[1] - other.maxVect[1] <= tolerance &&
204  minVect[2] - other.maxVect[2] <= tolerance && other.minVect[0] - maxVect[0] <= tolerance &&
205  other.minVect[1] - maxVect[1] <= tolerance && other.minVect[2] - maxVect[2] <= tolerance;
206 }
207 
208 inline bool AxisBox::intersects( const double* point, double tolerance ) const
209 {
210  return minVect[0] - point[0] <= tolerance && minVect[1] - point[1] <= tolerance &&
211  minVect[2] - point[2] <= tolerance && maxVect[0] - point[0] <= tolerance &&
212  maxVect[1] - point[1] <= tolerance && maxVect[2] - point[2] <= tolerance;
213 }
214 
215 inline bool AxisBox::valid() const
216 {
217  return minVect[0] <= maxVect[0] && minVect[1] <= maxVect[1] && minVect[2] <= maxVect[2];
218 }
219 
220 inline void AxisBox::closest_position_within_box( const double* input_position, double* output_position ) const
221 {
222  for( int i = 0; i < 3; ++i )
223  {
224  if( input_position[i] < minVect[i] )
225  output_position[i] = minVect[i];
226  else if( input_position[i] > maxVect[i] )
227  output_position[i] = maxVect[i];
228  else
229  output_position[i] = input_position[i];
230  }
231 }
232 
233 } // namespace moab
234 
235 #endif