OpenWalnut  1.2.5
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
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 
30 #include <osg/BoundingBox>
31 
32 #include "exceptions/WInvalidBoundingBox.h"
33 #include "math/linearAlgebra/WLinearAlgebra.h"
34 
35 /**
36  * Represents a \e axis \e parallel bounding box and provides some useful operations with them.
37  *
38  * \note Reason for subclassing: We don't want \c _min and \c _max member variables to be public.
39  * \note Reason for not having a \e private osg::BoundingBox member is, we don't have to wrap many
40  * member functions and can make use of the using directive. A downside on this is, we cannot
41  * automatical cast to osg::BoundingBox even if we provide a cast operator! Hence when we need this
42  * we will provide a toOsgBB() member function.
43  */
44 template< class VT >
45 class WBoundingBoxImpl : private osg::BoundingBoxImpl< VT >
46 {
47 public:
48  /**
49  * Vertex type for min and max positions of this box.
50  */
51  typedef typename osg::BoundingBoxImpl< VT >::vec_type vec_type;
52 
53  /**
54  * Value type of the vertex type for example double, float, etc.
55  */
56  typedef typename osg::BoundingBoxImpl< VT >::value_type value_type;
57 
58  /**
59  * Default constructor.
60  */
62 
63  /**
64  * Wrapps the component wise bounding box constructor from osg::BoundingBox.
65  *
66  * \param xmin Minimal x coordinate
67  * \param ymin Minimal y coordinate
68  * \param zmin Minimal z coordinate
69  * \param xmax Maximal x coordinate
70  * \param ymax Maximal y coordinate
71  * \param zmax Maximal z coordinate
72  */
73  WBoundingBoxImpl( value_type xmin, value_type ymin, value_type zmin, value_type xmax, value_type ymax, value_type zmax );
74 
75  /**
76  * Constructs a bounding box by min and max positions.
77  *
78  * \param min Position containing minx miny and minz coordinates.
79  * \param max Position containing maxx maxy and maxz coordinates.
80  */
81  WBoundingBoxImpl( const vec_type& min, const vec_type& max );
82 
83  /**
84  * Destructs this instance.
85  */
86  virtual ~WBoundingBoxImpl();
87 
88  /**
89  * Resets this box to an initial state where max is FLT_MIN and min FLT_MAX.
90  *
91  * \note This is a wrapper call to osg::BoundingBoxImpl< VT >::init()
92  */
93  void reset();
94 
95  using osg::BoundingBoxImpl< VT >::valid;
96  using osg::BoundingBoxImpl< VT >::set;
97  using osg::BoundingBoxImpl< VT >::xMin;
98  using osg::BoundingBoxImpl< VT >::yMin;
99  using osg::BoundingBoxImpl< VT >::zMin;
100  using osg::BoundingBoxImpl< VT >::xMax;
101  using osg::BoundingBoxImpl< VT >::yMax;
102  using osg::BoundingBoxImpl< VT >::zMax;
103  using osg::BoundingBoxImpl< VT >::center;
104  using osg::BoundingBoxImpl< VT >::radius;
105 
106  /**
107  * Calculates and returns the squared length of the bounding box radius.
108  *
109  * \note This is a wrapper call to osg::BoundingBoxImpl< VT >::radius2()
110  *
111  * \return squared bbox radius
112  */
113  value_type radiusSquare() const;
114 
115  using osg::BoundingBoxImpl< VT >::corner;
116 
117  /**
118  * Explicit type conversion function to use a WBoundingBox as osg::BoundingBox.
119  *
120  * \return A copy of this bounding box as osg::BoundingBox.
121  */
122  osg::BoundingBox toOSGBB() const;
123 
124  using osg::BoundingBoxImpl< VT >::expandBy;
125 
126  /**
127  * Expands this bounding box to include the given bounding box.
128  *
129  * \param bb The other bounding box.
130  */
131  void expandBy( const WBoundingBoxImpl< VT > &bb );
132 
133  /**
134  * Checks for intersection of this bounding box with the specified bounding box.
135  *
136  * \param bb The other bouding box to tetst with.
137  *
138  * \return True if they intersect, false otherwise.
139  */
140  bool intersects( const WBoundingBoxImpl< VT > &bb ) const;
141 
142  /**
143  * Computes the minimal distance of tow axis parallel bounding boxes.
144  *
145  * \param bb The other bounding box.
146  *
147  * \return Zero if they intersect, otherwise their minimal distance.
148  */
149  value_type minDistance( const WBoundingBoxImpl< VT > &bb ) const;
150 
151  using osg::BoundingBoxImpl< VT >::contains;
152 
153  /**
154  * Gives the front lower left aka minimum corner.
155  *
156  * \return Minimum corner.
157  */
158  const vec_type& getMin() const;
159 
160  /**
161  * Gives the back upper right aka maximum corner.
162  *
163  * \return Maximum corner.
164  */
165  const vec_type& getMax() const;
166 
167 protected:
168 private:
169 };
170 
171 template< class VT >
173  : osg::BoundingBoxImpl< VT >()
174 {
175 }
176 
177 template< class VT >
178 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
179  : osg::BoundingBoxImpl< VT >( xmin, ymin, zmin, xmax, ymax, zmax )
180 {
181 }
182 
183 template< class VT >
185  : osg::BoundingBoxImpl< VT >( min, max )
186 {
187 }
188 
189 template< class VT >
191 {
192 }
193 
194 template< class VT >
196 {
197  this->init();
198 }
199 
200 template< class VT >
202 {
203  return this->raidus2();
204 }
205 
206 template< class VT >
207 inline osg::BoundingBox WBoundingBoxImpl< VT >::toOSGBB() const
208 {
209  return osg::BoundingBox( osg::BoundingBoxImpl< VT >::_min, osg::BoundingBoxImpl< VT >::_max );
210 }
211 
212 template< class VT >
214 {
215  osg::BoundingBoxImpl< VT >::expandBy( bb );
216 }
217 
218 template< class VT >
220 {
221  return osg::BoundingBoxImpl< VT >::intersects( bb );
222 }
223 
224 /**
225  * Anonymous namespace, just to be DRY in minDistance.
226  */
227 namespace
228 {
229  /**
230  * Checks if the two given intervals intersect and computes the distance between them.
231  *
232  * \param a0 lower bound of the first interval
233  * \param a1 upper bound of the first interval
234  * \param b0 lower bound of the second interval
235  * \param b1 upper bound if the second interval
236  *
237  * \return The distance between those intervals if they don't overlap, zero otherwise
238  */
239  inline double intervalDistance( double a0, double a1, double b0, double b1 )
240  {
241  if( a1 < b0 )
242  {
243  return b0 - a1;
244  }
245  else if( b1 < a0 )
246  {
247  return a0 - b1;
248  }
249  return 0.0;
250  }
251 }
252 
253 template< class VT >
255 {
256  // test if they are valid
257  if( !valid() || !bb.valid() )
258  {
259  throw WInvalidBoundingBox( "One of the both bounding boxes inside minDistance computation is not valid." );
260  }
261 
262  double dx = intervalDistance( xMin(), xMax(), bb.xMin(), bb.xMax() );
263  double dy = intervalDistance( yMin(), yMax(), bb.yMin(), bb.yMax() );
264  double dz = intervalDistance( zMin(), zMax(), bb.zMin(), bb.zMax() );
265  if( dx == 0.0 && dy == 0.0 && dz == 0.0 )
266  {
267  return 0.0;
268  }
269  return std::sqrt( dx * dx + dy * dy + dz * dz );
270 }
271 
272 /**
273  * Output operator for the WBoundingBoxImpl class.
274  *
275  * \param out Output stream operator
276  * \param bb The box which should be streamed out
277  *
278  * \return reference to the output stream
279  */
280 template< class VT >
281 inline std::ostream& operator<<( std::ostream& out, const WBoundingBoxImpl< VT >& bb )
282 {
283  out << std::scientific << std::setprecision( 16 );
284  out << "AABB( min: " << bb.xMin() << ", " << bb.yMin() << ", " << bb.zMin();
285  out << " max: " << bb.xMax() << ", " << bb.yMax() << ", " << bb.zMax() << " )";
286  return out;
287 }
288 
289 template< class VT >
291 {
292  return osg::BoundingBoxImpl< VT >::_min;
293 }
294 
295 template< class VT >
297 {
298  return osg::BoundingBoxImpl< VT >::_max;
299 }
300 
302 
303 #endif // WBOUNDINGBOX_H