00001
00002
00003
00004
00005
00006
00007 #ifndef BALL_MATHS_SIMPLEBOX3_H
00008 #define BALL_MATHS_SIMPLEBOX3_H
00009
00010 #ifndef BALL_COMMON_H
00011 # include <BALL/common.h>
00012 #endif
00013
00014 #ifndef BALL_MATHS_VECTOR3_H
00015 # include <BALL/MATHS/vector3.h>
00016 #endif
00017
00018 namespace BALL
00019 {
00024
00030 template <typename T>
00031 class TSimpleBox3
00032 {
00033 public:
00034
00035 BALL_CREATE(TSimpleBox3<T>)
00036
00037
00040
00045 TSimpleBox3()
00046 ;
00047
00052 TSimpleBox3(const TSimpleBox3& box);
00053
00059 TSimpleBox3(const TVector3<T>& a, const TVector3<T>& b);
00060
00070 TSimpleBox3(const T& ax, const T& ay, const T& az, const T& bx, const T& by, const T& bz);
00071
00076 virtual ~TSimpleBox3()
00077
00078 {
00079 }
00080
00084 virtual void clear();
00085
00087
00090
00094 void set(const TSimpleBox3& box);
00095
00100 void set(const TVector3<T>& lower, const TVector3<T>& upper);
00101
00110 void set(const T& ax, const T& ay, const T& az, const T& bx, const T& by, const T& bz);
00111
00116 const TSimpleBox3& operator = (const TSimpleBox3& box);
00117
00122 void get(TSimpleBox3& box) const;
00123
00128 void get(TVector3<T>& lower, TVector3<T>& upper) const;
00129
00138 void get(T& ax, T& ay, T& az, T& bx, T& by, T& bz) const;
00139
00143 void swap(TSimpleBox3& box);
00144
00146
00147
00154 T getSurface() const;
00155
00159 T getVolume() const;
00160
00164 T getWidth() const;
00165
00169 T getHeight() const;
00170
00174 T getDepth() const;
00175
00181 void join(const TSimpleBox3& box);
00182
00184
00187
00191 bool operator == (const TSimpleBox3& box) const;
00192
00196 bool operator != (const TSimpleBox3& box) const;
00197
00204 bool has(const TVector3<T>& point, bool on_surface = false) const;
00205
00210 bool isIntersecting(const TSimpleBox3& box) const;
00212
00216
00221 bool isValid() const;
00222
00229 void dump(std::ostream& s = std::cout, Size depth = 0) const;
00231
00232
00236
00239 TVector3<T> a;
00240
00243 TVector3<T> b;
00245 };
00247
00248 template <typename T>
00249 TSimpleBox3<T>::TSimpleBox3()
00250 : a(),
00251 b()
00252 {
00253 }
00254
00255 template <typename T>
00256 TSimpleBox3<T>::TSimpleBox3(const TSimpleBox3<T>& box)
00257 : a(box.a),
00258 b(box.b)
00259 {
00260 }
00261
00262 template <typename T>
00263 TSimpleBox3<T>::TSimpleBox3(const TVector3<T>& lower, const TVector3<T>& upper)
00264
00265 : a(lower),
00266 b(upper)
00267 {
00268 }
00269
00270 template <typename T>
00271 TSimpleBox3<T>::TSimpleBox3(const T& ax, const T& ay, const T& az,
00272 const T& bx, const T& by, const T& bz)
00273
00274 : a(ax, ay, az),
00275 b(bx, by, bz)
00276 {
00277 }
00278
00279 template <typename T>
00280 BALL_INLINE
00281 void TSimpleBox3<T>::set(const TSimpleBox3<T>& box)
00282
00283 {
00284 a.set(box.a);
00285 b.set(box.b);
00286 }
00287
00288 template <typename T>
00289 BALL_INLINE
00290 void TSimpleBox3<T>::set(const TVector3<T>& lower, const TVector3<T>& upper)
00291
00292 {
00293 a.set(lower);
00294 b.set(upper);
00295 }
00296
00297 template <typename T>
00298 BALL_INLINE
00299 void TSimpleBox3<T>::set(const T& ax, const T& ay, const T& az,
00300 const T& bx, const T& by, const T& bz)
00301
00302 {
00303 a.set(ax, ay, az);
00304 b.set(bx, by, bz);
00305 }
00306
00307 template <typename T>
00308 BALL_INLINE
00309 const TSimpleBox3<T>& TSimpleBox3<T>::operator = (const TSimpleBox3<T> &box)
00310
00311 {
00312 set(box);
00313 return *this;
00314 }
00315
00316 template <typename T>
00317 BALL_INLINE
00318 void TSimpleBox3<T>::get(TSimpleBox3<T>& box) const
00319
00320 {
00321 box.set(*this);
00322 }
00323
00324 template <typename T>
00325 BALL_INLINE
00326 void TSimpleBox3<T>::get(TVector3<T>& lower, TVector3<T>& upper) const
00327
00328 {
00329 lower.set(a);
00330 upper.set(b);
00331 }
00332
00333 template <typename T>
00334 BALL_INLINE
00335 void TSimpleBox3<T>::get(T& ax, T& ay, T& az, T& bx, T& by, T& bz) const
00336
00337 {
00338 a.get(ax, ay, az);
00339 b.get(bx, by, bz);
00340 }
00341
00342 template <typename T>
00343 BALL_INLINE
00344 void TSimpleBox3<T>::swap(TSimpleBox3<T>& box)
00345
00346 {
00347 a.swap(box.a);
00348 b.swap(box.b);
00349 }
00350
00351 template <typename T>
00352 BALL_INLINE
00353 void TSimpleBox3<T>::clear()
00354
00355 {
00356 a.set((T)0, (T)0, (T)0);
00357 b.set((T)0, (T)0, (T)0);
00358 }
00359
00360 template <typename T>
00361 BALL_INLINE
00362 T TSimpleBox3<T>::getSurface() const
00363
00364 {
00365 T width = Maths::abs(b.x - a.x);
00366 T height = Maths::abs(b.y - a.y);
00367 T depth = Maths::abs(b.z - a.z);
00368
00369 return ((width * height + width * depth + height * depth) * 2);
00370 }
00371
00372 template <typename T>
00373 BALL_INLINE
00374 T TSimpleBox3<T>::getVolume() const
00375
00376 {
00377 T width = Maths::abs(b.x - a.x);
00378 T height = Maths::abs(b.y - a.y);
00379 T depth = Maths::abs(b.z - a.z);
00380
00381 return (width * height * depth);
00382 }
00383
00384 template <typename T>
00385 BALL_INLINE
00386 T TSimpleBox3<T>::getWidth() const
00387
00388 {
00389 return Maths::abs(b.x - a.x);
00390 }
00391
00392 template <typename T>
00393 BALL_INLINE
00394 T TSimpleBox3<T>::getHeight() const
00395
00396 {
00397 return Maths::abs(b.y - a.y);
00398 }
00399
00400 template <typename T>
00401 BALL_INLINE
00402 T TSimpleBox3<T>::getDepth() const
00403
00404 {
00405 return Maths::abs(b.z - a.z);
00406 }
00407
00408 template <typename T>
00409 void TSimpleBox3<T>::join(const TSimpleBox3<T>& box)
00410
00411 {
00412 T minimum = a.x;
00413 minimum = Maths::min(minimum, b.x);
00414 minimum = Maths::min(minimum, box.a.x);
00415 minimum = Maths::min(minimum, box.b.x);
00416
00417 T maximum = a.x;
00418 maximum = Maths::max(maximum, b.x);
00419 maximum = Maths::max(maximum, box.a.x);
00420 maximum = Maths::max(maximum, box.b.x);
00421
00422 a.x = minimum;
00423 b.x = maximum;
00424
00425 minimum = a.y;
00426 minimum = Maths::min(minimum, b.y);
00427 minimum = Maths::min(minimum, box.a.y);
00428 minimum = Maths::min(minimum, box.b.y);
00429
00430 maximum = a.y;
00431 maximum = Maths::max(maximum, b.y);
00432 maximum = Maths::max(maximum, box.a.y);
00433 maximum = Maths::max(maximum, box.b.y);
00434
00435 a.y = minimum;
00436 b.y = maximum;
00437
00438 minimum = a.z;
00439 minimum = Maths::min(minimum, b.z);
00440 minimum = Maths::min(minimum, box.a.z);
00441 minimum = Maths::min(minimum, box.b.z);
00442
00443 maximum = a.z;
00444 maximum = Maths::max(maximum, b.z);
00445 maximum = Maths::max(maximum, box.a.z);
00446 maximum = Maths::max(maximum, box.b.z);
00447
00448 a.z = minimum;
00449 b.z = maximum;
00450 }
00451
00452 template <typename T>
00453 BALL_INLINE
00454 bool TSimpleBox3<T>::operator == (const TSimpleBox3<T>& box) const
00455
00456 {
00457 return (a == box.a && b == box.b);
00458 }
00459
00460 template <typename T>
00461 BALL_INLINE
00462 bool TSimpleBox3<T>::operator != (const TSimpleBox3<T> &box) const
00463
00464 {
00465 return !(*this == box);
00466 }
00467
00468 template <typename T>
00469 BALL_INLINE
00470 bool TSimpleBox3<T>::isValid() const
00471
00472 {
00473 return (a.isValid() && b.isValid());
00474 }
00475
00476 template <typename T>
00477 bool TSimpleBox3<T>::has(const TVector3<T>& point, bool on_surface) const
00478
00479 {
00480 if (!on_surface)
00481 {
00482 if (Maths::isLess(b[0],a[0]) || Maths::isLess(b[1],a[1]) || Maths::isLess(b[2],a[2]))
00483 {
00484 for (int i = 0; i < 3; i++)
00485 {
00486 if (Maths::isLess(point[i],b[i]) || Maths::isLess(a[i],point[i]))
00487 {
00488 return false;
00489 }
00490 }
00491 }
00492 else
00493 {
00494 for (int i = 0; i < 3; i++)
00495 {
00496 if (Maths::isLess(point[i],a[i]) || Maths::isLess(b[i],point[i]))
00497 {
00498 return false;
00499 }
00500 }
00501 }
00502 return true;
00503 }
00504
00505 bool temp = false;
00506 for (int i = 0; i < 3; i++)
00507 {
00508 if (Maths::isEqual(point[i],a[i]) || Maths::isEqual(point[i],b[i]))
00509 {
00510 temp = true;
00511 break;
00512 }
00513 }
00514 return (temp && has(point, false));
00515 }
00516
00517 template <typename T>
00518 bool TSimpleBox3<T>::isIntersecting(const TSimpleBox3& box) const
00519
00520 {
00521 const TVector3<T>* lower;
00522 const TVector3<T>* higher;
00523 const TVector3<T>* box_lower;
00524 const TVector3<T>* box_higher;
00525
00526 if (Maths::isLess(b[0],a[0]) ||
00527 Maths::isLess(b[1],a[1]) ||
00528 Maths::isLess(b[2],a[2]))
00529 {
00530 lower = &b;
00531 higher = &a;
00532 }
00533 else
00534 {
00535 lower = &a;
00536 higher = &b;
00537 }
00538
00539 if (Maths::isLess(box.b[0],box.a[0]) ||
00540 Maths::isLess(box.b[1],box.a[1]) ||
00541 Maths::isLess(box.b[2],box.a[2]))
00542 {
00543 box_lower = &box.b;
00544 box_higher = &box.a;
00545 }
00546 else
00547 {
00548 box_lower = &box.a;
00549 box_higher = &box.b;;
00550 }
00551
00552 for (int i = 0; i < 3; i++)
00553 {
00554 if (Maths::isLess((*box_higher)[i],(*lower)[i]) || Maths::isLess((*higher)[i],(*box_lower)[i]))
00555 {
00556 return false;
00557 }
00558 }
00559
00560 return true;
00561 }
00562
00563 template <typename T>
00564 void TSimpleBox3<T>::dump(std::ostream& s, Size depth) const
00565
00566 {
00567 BALL_DUMP_STREAM_PREFIX(s);
00568
00569 BALL_DUMP_HEADER(s, this, this);
00570
00571 BALL_DUMP_DEPTH(s, depth);
00572 s << " a: " << a << std::endl;
00573
00574 BALL_DUMP_DEPTH(s, depth);
00575 s << " b: " << b << std::endl;
00576
00577 BALL_DUMP_STREAM_SUFFIX(s);
00578 }
00579
00583
00588 template <typename T>
00589 std::istream& operator >> (std::istream& s, TSimpleBox3<T>& box)
00590
00591 {
00592 char c;
00593 s >> c >> box.a >> box.b >> c;
00594 return s;
00595 }
00596
00605 template <typename T>
00606 std::ostream& operator << (std::ostream& s, const TSimpleBox3<T>& box)
00607
00608 {
00609 return s << "(" << box.a << ' ' << box.b << ')';
00610 }
00611
00615 typedef TSimpleBox3<float> SimpleBox3;
00616
00617 }
00618
00619 #endif // BALL_MATHS_SimpleBox3_H