BALL
1.4.1
|
00001 // -*- Mode: C++; tab-width: 2; -*- 00002 // vi: set ts=2: 00003 // 00004 // $Id: simpleBox3.h,v 1.9 2004/05/27 19:49:42 oliver Exp $ 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 } // namespace BALL 00618 00619 #endif // BALL_MATHS_SimpleBox3_H