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 ;
00112
00117 const TSimpleBox3& operator = (const TSimpleBox3& box)
00118 ;
00119
00124 void get(TSimpleBox3& box) const;
00125
00130 void get(TVector3<T>& lower, TVector3<T>& upper) const
00131 ;
00132
00141 void get(T& ax, T& ay, T& az, T& bx, T& by, T& bz) const;
00142
00146 void swap(TSimpleBox3& box);
00147
00149
00150
00157 T getSurface() const
00158 ;
00159
00163 T getVolume() const
00164 ;
00165
00169 T getWidth() const
00170 ;
00171
00175 T getHeight() const
00176 ;
00177
00181 T getDepth() const
00182 ;
00183
00189 void join(const TSimpleBox3& box)
00190 ;
00191
00193
00196
00200 bool operator == (const TSimpleBox3& box) const
00201 ;
00202
00206 bool operator != (const TSimpleBox3& box) const
00207 ;
00208
00215 bool has(const TVector3<T>& point, bool on_surface = false) const
00216 ;
00217
00222 bool isIntersecting(const TSimpleBox3& box) const
00223 ;
00225
00229
00234 bool isValid() const
00235 ;
00236
00243 void dump(std::ostream& s = std::cout, Size depth = 0) const
00244 ;
00246
00247
00251
00254 TVector3<T> a;
00255
00258 TVector3<T> b;
00260 };
00262
00263 template <typename T>
00264 TSimpleBox3<T>::TSimpleBox3()
00265
00266 : a(),
00267 b()
00268 {
00269 }
00270
00271 template <typename T>
00272 TSimpleBox3<T>::TSimpleBox3(const TSimpleBox3<T>& box)
00273
00274 : a(box.a),
00275 b(box.b)
00276 {
00277 }
00278
00279 template <typename T>
00280 TSimpleBox3<T>::TSimpleBox3(const TVector3<T>& lower, const TVector3<T>& upper)
00281
00282 : a(lower),
00283 b(upper)
00284 {
00285 }
00286
00287 template <typename T>
00288 TSimpleBox3<T>::TSimpleBox3(const T& ax, const T& ay, const T& az,
00289 const T& bx, const T& by, const T& bz)
00290
00291 : a(ax, ay, az),
00292 b(bx, by, bz)
00293 {
00294 }
00295
00296 template <typename T>
00297 BALL_INLINE
00298 void TSimpleBox3<T>::set(const TSimpleBox3<T>& box)
00299
00300 {
00301 a.set(box.a);
00302 b.set(box.b);
00303 }
00304
00305 template <typename T>
00306 BALL_INLINE
00307 void TSimpleBox3<T>::set(const TVector3<T>& lower, const TVector3<T>& upper)
00308
00309 {
00310 a.set(lower);
00311 b.set(upper);
00312 }
00313
00314 template <typename T>
00315 BALL_INLINE
00316 void TSimpleBox3<T>::set(const T& ax, const T& ay, const T& az,
00317 const T& bx, const T& by, const T& bz)
00318
00319 {
00320 a.set(ax, ay, az);
00321 b.set(bx, by, bz);
00322 }
00323
00324 template <typename T>
00325 BALL_INLINE
00326 const TSimpleBox3<T>& TSimpleBox3<T>::operator = (const TSimpleBox3<T> &box)
00327
00328 {
00329 set(box);
00330 return *this;
00331 }
00332
00333 template <typename T>
00334 BALL_INLINE
00335 void TSimpleBox3<T>::get(TSimpleBox3<T>& box) const
00336
00337 {
00338 box.set(*this);
00339 }
00340
00341 template <typename T>
00342 BALL_INLINE
00343 void TSimpleBox3<T>::get(TVector3<T>& lower, TVector3<T>& upper) const
00344
00345 {
00346 lower.set(a);
00347 upper.set(b);
00348 }
00349
00350 template <typename T>
00351 BALL_INLINE
00352 void TSimpleBox3<T>::get(T& ax, T& ay, T& az, T& bx, T& by, T& bz) const
00353
00354 {
00355 a.get(ax, ay, az);
00356 b.get(bx, by, bz);
00357 }
00358
00359 template <typename T>
00360 BALL_INLINE
00361 void TSimpleBox3<T>::swap(TSimpleBox3<T>& box)
00362
00363 {
00364 a.swap(box.a);
00365 b.swap(box.b);
00366 }
00367
00368 template <typename T>
00369 BALL_INLINE
00370 void TSimpleBox3<T>::clear()
00371
00372 {
00373 a.set((T)0, (T)0, (T)0);
00374 b.set((T)0, (T)0, (T)0);
00375 }
00376
00377 template <typename T>
00378 BALL_INLINE
00379 T TSimpleBox3<T>::getSurface() const
00380
00381 {
00382 T width = Maths::abs(b.x - a.x);
00383 T height = Maths::abs(b.y - a.y);
00384 T depth = Maths::abs(b.z - a.z);
00385
00386 return ((width * height + width * depth + height * depth) * 2);
00387 }
00388
00389 template <typename T>
00390 BALL_INLINE
00391 T TSimpleBox3<T>::getVolume() const
00392
00393 {
00394 T width = Maths::abs(b.x - a.x);
00395 T height = Maths::abs(b.y - a.y);
00396 T depth = Maths::abs(b.z - a.z);
00397
00398 return (width * height * depth);
00399 }
00400
00401 template <typename T>
00402 BALL_INLINE
00403 T TSimpleBox3<T>::getWidth() const
00404
00405 {
00406 return Maths::abs(b.x - a.x);
00407 }
00408
00409 template <typename T>
00410 BALL_INLINE
00411 T TSimpleBox3<T>::getHeight() const
00412
00413 {
00414 return Maths::abs(b.y - a.y);
00415 }
00416
00417 template <typename T>
00418 BALL_INLINE
00419 T TSimpleBox3<T>::getDepth() const
00420
00421 {
00422 return Maths::abs(b.z - a.z);
00423 }
00424
00425 template <typename T>
00426 void TSimpleBox3<T>::join(const TSimpleBox3<T>& box)
00427
00428 {
00429 T minimum = a.x;
00430 minimum = Maths::min(minimum, b.x);
00431 minimum = Maths::min(minimum, box.a.x);
00432 minimum = Maths::min(minimum, box.b.x);
00433
00434 T maximum = a.x;
00435 maximum = Maths::max(maximum, b.x);
00436 maximum = Maths::max(maximum, box.a.x);
00437 maximum = Maths::max(maximum, box.b.x);
00438
00439 a.x = minimum;
00440 b.x = maximum;
00441
00442 minimum = a.y;
00443 minimum = Maths::min(minimum, b.y);
00444 minimum = Maths::min(minimum, box.a.y);
00445 minimum = Maths::min(minimum, box.b.y);
00446
00447 maximum = a.y;
00448 maximum = Maths::max(maximum, b.y);
00449 maximum = Maths::max(maximum, box.a.y);
00450 maximum = Maths::max(maximum, box.b.y);
00451
00452 a.y = minimum;
00453 b.y = maximum;
00454
00455 minimum = a.z;
00456 minimum = Maths::min(minimum, b.z);
00457 minimum = Maths::min(minimum, box.a.z);
00458 minimum = Maths::min(minimum, box.b.z);
00459
00460 maximum = a.z;
00461 maximum = Maths::max(maximum, b.z);
00462 maximum = Maths::max(maximum, box.a.z);
00463 maximum = Maths::max(maximum, box.b.z);
00464
00465 a.z = minimum;
00466 b.z = maximum;
00467 }
00468
00469 template <typename T>
00470 BALL_INLINE
00471 bool TSimpleBox3<T>::operator == (const TSimpleBox3<T>& box) const
00472
00473 {
00474 return (a == box.a && b == box.b);
00475 }
00476
00477 template <typename T>
00478 BALL_INLINE
00479 bool TSimpleBox3<T>::operator != (const TSimpleBox3<T> &box) const
00480
00481 {
00482 return !(*this == box);
00483 }
00484
00485 template <typename T>
00486 BALL_INLINE
00487 bool TSimpleBox3<T>::isValid() const
00488
00489 {
00490 return (a.isValid() && b.isValid());
00491 }
00492
00493 template <typename T>
00494 bool TSimpleBox3<T>::has(const TVector3<T>& point, bool on_surface) const
00495
00496 {
00497 if (!on_surface)
00498 {
00499 if (Maths::isLess(b[0],a[0]) || Maths::isLess(b[1],a[1]) || Maths::isLess(b[2],a[2]))
00500 {
00501 for (int i = 0; i < 3; i++)
00502 {
00503 if (Maths::isLess(point[i],b[i]) || Maths::isLess(a[i],point[i]))
00504 {
00505 return false;
00506 }
00507 }
00508 }
00509 else
00510 {
00511 for (int i = 0; i < 3; i++)
00512 {
00513 if (Maths::isLess(point[i],a[i]) || Maths::isLess(b[i],point[i]))
00514 {
00515 return false;
00516 }
00517 }
00518 }
00519 return true;
00520 }
00521
00522 bool temp = false;
00523 for (int i = 0; i < 3; i++)
00524 {
00525 if (Maths::isEqual(point[i],a[i]) || Maths::isEqual(point[i],b[i]))
00526 {
00527 temp = true;
00528 break;
00529 }
00530 }
00531 return (temp && has(point, false));
00532 }
00533
00534 template <typename T>
00535 bool TSimpleBox3<T>::isIntersecting(const TSimpleBox3& box) const
00536
00537 {
00538 const TVector3<T>* lower;
00539 const TVector3<T>* higher;
00540 const TVector3<T>* box_lower;
00541 const TVector3<T>* box_higher;
00542
00543 if (Maths::isLess(b[0],a[0]) ||
00544 Maths::isLess(b[1],a[1]) ||
00545 Maths::isLess(b[2],a[2]))
00546 {
00547 lower = &b;
00548 higher = &a;
00549 }
00550 else
00551 {
00552 lower = &a;
00553 higher = &b;
00554 }
00555
00556 if (Maths::isLess(box.b[0],box.a[0]) ||
00557 Maths::isLess(box.b[1],box.a[1]) ||
00558 Maths::isLess(box.b[2],box.a[2]))
00559 {
00560 box_lower = &box.b;
00561 box_higher = &box.a;
00562 }
00563 else
00564 {
00565 box_lower = &box.a;
00566 box_higher = &box.b;;
00567 }
00568
00569 for (int i = 0; i < 3; i++)
00570 {
00571 if (Maths::isLess((*box_higher)[i],(*lower)[i]) || Maths::isLess((*higher)[i],(*box_lower)[i]))
00572 {
00573 return false;
00574 }
00575 }
00576
00577 return true;
00578 }
00579
00580 template <typename T>
00581 void TSimpleBox3<T>::dump(std::ostream& s, Size depth) const
00582
00583 {
00584 BALL_DUMP_STREAM_PREFIX(s);
00585
00586 BALL_DUMP_HEADER(s, this, this);
00587
00588 BALL_DUMP_DEPTH(s, depth);
00589 s << " a: " << a << std::endl;
00590
00591 BALL_DUMP_DEPTH(s, depth);
00592 s << " b: " << b << std::endl;
00593
00594 BALL_DUMP_STREAM_SUFFIX(s);
00595 }
00596
00600
00605 template <typename T>
00606 std::istream& operator >> (std::istream& s, TSimpleBox3<T>& box)
00607
00608 {
00609 char c;
00610 s >> c >> box.a >> box.b >> c;
00611 return s;
00612 }
00613
00622 template <typename T>
00623 std::ostream& operator << (std::ostream& s, const TSimpleBox3<T>& box)
00624
00625 {
00626 return s << "(" << box.a << ' ' << box.b << ')';
00627 }
00628
00632 typedef TSimpleBox3<float> SimpleBox3;
00633
00634 }
00635
00636 #endif // BALL_MATHS_SimpleBox3_H