OpenWalnut  1.5.0dev
WBoundingBox.h
1 //---------------------------------------------------------------------------
2 //
3 // Project: OpenWalnut ( http://www.openwalnut.org )
4 //
5 // Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
6 // For more information see http://www.openwalnut.org/copying
7 //
8 // This file is part of OpenWalnut.
9 //
10 // OpenWalnut is free software: you can redistribute it and/or modify
11 // it under the terms of the GNU Lesser General Public License as published by
12 // the Free Software Foundation, either version 3 of the License, or
13 // (at your option) any later version.
14 //
15 // OpenWalnut is distributed in the hope that it will be useful,
16 // but WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 // GNU Lesser General Public License for more details.
19 //
20 // You should have received a copy of the GNU Lesser General Public License
21 // along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
22 //
23 //---------------------------------------------------------------------------
24 
25 #ifndef WBOUNDINGBOX_H
26 #define WBOUNDINGBOX_H
27 
28 #include <ostream>
29 #include <iomanip> // for setprecision
30 #include <cmath> // std::sqrt
31 
32 #include <osg/BoundingBox>
33 
34 #include "exceptions/WInvalidBoundingBox.h"
35 //#include "math/linearAlgebra/WLinearAlgebra.h"
36 
37 /**
38  * Represents a \e axis \e parallel bounding box and provides some useful operations with them.
39  *
40  * \note Reason for subclassing: We don't want \c _min and \c _max member variables to be public.
41  * \note Reason for not having a \e private osg::BoundingBox member is, we don't have to wrap many
42  * member functions and can make use of the using directive. A downside on this is, we cannot
43  * automatical cast to osg::BoundingBox even if we provide a cast operator! Hence when we need this
44  * we will provide a toOsgBB() member function.
45  */
46 template< class VT >
47 class WBoundingBoxImpl : private osg::BoundingBoxImpl< VT >
48 {
49 public:
50  /**
51  * Vertex type for min and max positions of this box.
52  */
53  typedef typename osg::BoundingBoxImpl< VT >::vec_type vec_type;
54 
55  /**
56  * Value type of the vertex type for example double, float, etc.
57  */
58  typedef typename osg::BoundingBoxImpl< VT >::value_type value_type;
59 
60  /**
61  * Default constructor.
62  */
64 
65  /**
66  * Wrapps the component wise bounding box constructor from osg::BoundingBox.
67  *
68  * \param xmin Minimal x coordinate
69  * \param ymin Minimal y coordinate
70  * \param zmin Minimal z coordinate
71  * \param xmax Maximal x coordinate
72  * \param ymax Maximal y coordinate
73  * \param zmax Maximal z coordinate
74  */
76 
77  /**
78  * Constructs a bounding box by min and max positions.
79  *
80  * \param min Position containing minx miny and minz coordinates.
81  * \param max Position containing maxx maxy and maxz coordinates.
82  */
83  WBoundingBoxImpl( const vec_type& min, const vec_type& max );
84 
85  /**
86  * Create BoundinmgBox using a given sphere.
87  *
88  * \param bs the sphere
89  */
90  explicit WBoundingBoxImpl( const osg::BoundingSphereImpl< VT >& bs );
91 
92  /**
93  * Destructs this instance.
94  */
95  virtual ~WBoundingBoxImpl();
96 
97  /**
98  * Resets this box to an initial state where max is FLT_MIN and min FLT_MAX.
99  *
100  * \note This is a wrapper call to osg::BoundingBoxImpl< VT >::init()
101  */
102  void reset();
103 
104  using osg::BoundingBoxImpl< VT >::valid;
105  using osg::BoundingBoxImpl< VT >::set;
106  using osg::BoundingBoxImpl< VT >::xMin;
107  using osg::BoundingBoxImpl< VT >::yMin;
108  using osg::BoundingBoxImpl< VT >::zMin;
109  using osg::BoundingBoxImpl< VT >::xMax;
110  using osg::BoundingBoxImpl< VT >::yMax;
111  using osg::BoundingBoxImpl< VT >::zMax;
112  using osg::BoundingBoxImpl< VT >::center;
113  using osg::BoundingBoxImpl< VT >::radius;
114 
115  /**
116  * Calculates and returns the squared length of the bounding box radius.
117  *
118  * \note This is a wrapper call to osg::BoundingBoxImpl< VT >::radius2()
119  *
120  * \return squared bbox radius
121  */
123 
124  using osg::BoundingBoxImpl< VT >::corner;
125 
126  /**
127  * Explicit type conversion function to use a WBoundingBox as osg::BoundingBox.
128  *
129  * \return A copy of this bounding box as osg::BoundingBox.
130  */
131  osg::BoundingBox toOSGBB() const;
132 
133  using osg::BoundingBoxImpl< VT >::expandBy;
134 
135  /**
136  * Expands this bounding box to include the given bounding box.
137  *
138  * \param bb The other bounding box.
139  */
140  void expandBy( const WBoundingBoxImpl< VT > &bb );
141 
142  /**
143  * Checks for intersection of this bounding box with the specified bounding box.
144  *
145  * \param bb The other bouding box to tetst with.
146  *
147  * \return True if they intersect, false otherwise.
148  */
149  bool intersects( const WBoundingBoxImpl< VT > &bb ) const;
150 
151  /**
152  * Computes the minimal distance of tow axis parallel bounding boxes.
153  *
154  * \param bb The other bounding box.
155  *
156  * \return Zero if they intersect, otherwise their minimal distance.
157  */
159 
160  using osg::BoundingBoxImpl< VT >::contains;
161 
162  /**
163  * Gives the front lower left aka minimum corner.
164  *
165  * \return Minimum corner.
166  */
167  const vec_type& getMin() const;
168 
169  /**
170  * Gives the back upper right aka maximum corner.
171  *
172  * \return Maximum corner.
173  */
174  const vec_type& getMax() const;
175 
176 protected:
177 private:
178  /**
179  * Checks if the two given intervals intersect and computes the distance between them.
180  *
181  * \param a0 lower bound of the first interval
182  * \param a1 upper bound of the first interval
183  * \param b0 lower bound of the second interval
184  * \param b1 upper bound if the second interval
185  *
186  * \return The distance between those intervals if they don't overlap, zero otherwise
187  */
188  double intervalDistance( double a0, double a1, double b0, double b1 ) const;
189 };
190 
191 template< class VT >
193  : osg::BoundingBoxImpl< VT >()
194 {
195 }
196 
197 template< class VT >
198 inline WBoundingBoxImpl< VT >::WBoundingBoxImpl( value_type xmin, value_type ymin, value_type zmin, value_type xmax, value_type ymax, value_type zmax ) // NOLINT line length
199  : osg::BoundingBoxImpl< VT >( xmin, ymin, zmin, xmax, ymax, zmax )
200 {
201 }
202 
203 template< class VT >
205  : osg::BoundingBoxImpl< VT >( min, max )
206 {
207 }
208 
209 template< class VT >
210 inline WBoundingBoxImpl< VT >::WBoundingBoxImpl( const osg::BoundingSphereImpl< VT >& bs )
211  : osg::BoundingBoxImpl< VT >( bs.center() - VT( bs.radius(), bs.radius(), bs.radius() ) ,
212  bs.center() + VT( bs.radius(), bs.radius(), bs.radius() ) )
213 {
214 }
215 
216 template< class VT >
218 {
219 }
220 
221 template< class VT >
223 {
224  this->init();
225 }
226 
227 template< class VT >
229 {
230  return this->radius2();
231 }
232 
233 template< class VT >
234 inline osg::BoundingBox WBoundingBoxImpl< VT >::toOSGBB() const
235 {
236  return osg::BoundingBox( osg::BoundingBoxImpl< VT >::_min, osg::BoundingBoxImpl< VT >::_max );
237 }
238 
239 template< class VT >
241 {
242  osg::BoundingBoxImpl< VT >::expandBy( bb );
243 }
244 
245 template< class VT >
247 {
248  return osg::BoundingBoxImpl< VT >::intersects( bb );
249 }
250 
251 template< class VT >
252 inline double WBoundingBoxImpl< VT >::intervalDistance( double a0, double a1, double b0, double b1 ) const
253 {
254  if( a1 < b0 )
255  {
256  return b0 - a1;
257  }
258  else if( b1 < a0 )
259  {
260  return a0 - b1;
261  }
262  return 0.0;
263 }
264 
265 template< class VT >
267 {
268  // test if they are valid
269  if( !valid() || !bb.valid() )
270  {
271  throw WInvalidBoundingBox( "One of the both bounding boxes inside minDistance computation is not valid." );
272  }
273 
274  double dx = intervalDistance( xMin(), xMax(), bb.xMin(), bb.xMax() );
275  double dy = intervalDistance( yMin(), yMax(), bb.yMin(), bb.yMax() );
276  double dz = intervalDistance( zMin(), zMax(), bb.zMin(), bb.zMax() );
277  if( dx == 0.0 && dy == 0.0 && dz == 0.0 )
278  {
279  return 0.0;
280  }
281  return std::sqrt( dx * dx + dy * dy + dz * dz );
282 }
283 
284 /**
285  * Output operator for the WBoundingBoxImpl class.
286  *
287  * \param out Output stream operator
288  * \param bb The box which should be streamed out
289  *
290  * \return reference to the output stream
291  */
292 template< class VT >
293 inline std::ostream& operator<<( std::ostream& out, const WBoundingBoxImpl< VT >& bb )
294 {
295  out << std::scientific << std::setprecision( 16 );
296  out << "AABB( min: " << bb.xMin() << ", " << bb.yMin() << ", " << bb.zMin();
297  out << " max: " << bb.xMax() << ", " << bb.yMax() << ", " << bb.zMax() << " )";
298  return out;
299 }
300 
301 template< class VT >
303 {
304  return osg::BoundingBoxImpl< VT >::_min;
305 }
306 
307 template< class VT >
309 {
310  return osg::BoundingBoxImpl< VT >::_max;
311 }
312 
314 
315 #endif // WBOUNDINGBOX_H
Represents a axis parallel bounding box and provides some useful operations with them.
Definition: WBoundingBox.h:48
WBoundingBoxImpl()
Default constructor.
Definition: WBoundingBox.h:192
osg::BoundingBoxImpl< VT >::value_type value_type
Value type of the vertex type for example double, float, etc.
Definition: WBoundingBox.h:58
virtual ~WBoundingBoxImpl()
Destructs this instance.
Definition: WBoundingBox.h:217
bool intersects(const WBoundingBoxImpl< VT > &bb) const
Checks for intersection of this bounding box with the specified bounding box.
Definition: WBoundingBox.h:246
value_type radiusSquare() const
Calculates and returns the squared length of the bounding box radius.
Definition: WBoundingBox.h:228
const vec_type & getMax() const
Gives the back upper right aka maximum corner.
Definition: WBoundingBox.h:308
value_type minDistance(const WBoundingBoxImpl< VT > &bb) const
Computes the minimal distance of tow axis parallel bounding boxes.
Definition: WBoundingBox.h:266
double intervalDistance(double a0, double a1, double b0, double b1) const
Checks if the two given intervals intersect and computes the distance between them.
Definition: WBoundingBox.h:252
const vec_type & getMin() const
Gives the front lower left aka minimum corner.
Definition: WBoundingBox.h:302
void expandBy(const WBoundingBoxImpl< VT > &bb)
Expands this bounding box to include the given bounding box.
Definition: WBoundingBox.h:240
osg::BoundingBoxImpl< VT >::vec_type vec_type
Vertex type for min and max positions of this box.
Definition: WBoundingBox.h:53
WBoundingBoxImpl(const vec_type &min, const vec_type &max)
Constructs a bounding box by min and max positions.
Definition: WBoundingBox.h:204
WBoundingBoxImpl(value_type xmin, value_type ymin, value_type zmin, value_type xmax, value_type ymax, value_type zmax)
Wrapps the component wise bounding box constructor from osg::BoundingBox.
Definition: WBoundingBox.h:198
osg::BoundingBox toOSGBB() const
Explicit type conversion function to use a WBoundingBox as osg::BoundingBox.
Definition: WBoundingBox.h:234
void reset()
Resets this box to an initial state where max is FLT_MIN and min FLT_MAX.
Definition: WBoundingBox.h:222
WBoundingBoxImpl(const osg::BoundingSphereImpl< VT > &bs)
Create BoundinmgBox using a given sphere.
Definition: WBoundingBox.h:210
Indicates that a bounding box is not valid, meaning its valid() member function delivers false.