BALL
1.4.1
|
00001 // -*- Mode: C++; tab-width: 2; -*- 00002 // vi: set ts=2: 00003 // 00004 00005 #ifndef BALL_MATHS_VECTOR4_H 00006 #define BALL_MATHS_VECTOR4_H 00007 00008 #ifndef BALL_COMMON_EXCEPTION_H 00009 # include <BALL/COMMON/exception.h> 00010 #endif 00011 00012 #ifndef BALL_MATHS_ANGLE_H 00013 # include <BALL/MATHS/angle.h> 00014 #endif 00015 00016 #ifdef BALL_HAS_IEEEFP_H 00017 # include <ieeefp.h> 00018 #endif 00019 00020 namespace BALL 00021 { 00026 00027 template <typename T> 00028 class TVector4; 00029 00033 00034 template <typename T> 00035 BALL_INLINE 00036 TVector4<T> operator + (const TVector4<T>& a, const TVector4<T>& b); 00037 00038 template <typename T> 00039 BALL_INLINE 00040 TVector4<T> operator - (const TVector4<T>& a, const TVector4<T>& b); 00041 00042 template <typename T> 00043 std::istream& operator >> (std::istream& s, TVector4<T>& vector); 00044 00045 template <typename T> 00046 std::ostream& operator << (std::ostream& s, const TVector4<T>& vector); 00047 00051 template <typename T> 00052 class TVector4 00053 { 00054 public: 00055 00056 BALL_CREATE(TVector4<T>) 00057 00058 00061 00066 TVector4(); 00067 00074 TVector4(const T* ptr); 00075 00081 explicit TVector4(const T& value); 00082 00090 TVector4(const T& x, const T& y, const T& z, const T& h = (T)1); 00091 00096 TVector4(const TVector4& vector); 00097 00102 virtual ~TVector4(); 00103 00107 virtual void clear() 00108 { 00109 x = y = z = h = (T)0; 00110 } 00111 00113 00116 00123 void set(const T* ptr); 00124 00131 void set(const T& rx, const T& ry, const T& rz, const T& rh = (T)1); 00132 00136 void set(const TVector4& vector); 00137 00143 TVector4& operator = (const T* ptr); 00144 00149 TVector4& operator = (const TVector4& vector); 00150 00155 TVector4& operator = (T value); 00156 00163 void get(T* ptr) const; 00164 00171 void get(T& rx, T& ry, T& rz, T& rh) const; 00172 00177 void get(TVector4& vector) const; 00178 00182 void swap(TVector4& vector); 00183 00185 00188 00194 T getLength() const; 00195 00201 T getSquareLength() const; 00202 00209 TVector4& normalize(); 00210 00213 static const TVector4& getZero(); 00214 00217 static const TVector4& getUnit(); 00218 00222 void set(const T& value = (T)1); 00223 00227 T& operator [] (Position position); 00228 00232 const T& operator [] (Position position) const; 00233 00235 00238 00241 TVector4 operator + () const; 00242 00245 TVector4 operator - () const; 00246 00251 TVector4& operator += (const TVector4& vector); 00252 00257 TVector4& operator -= (const TVector4& vector); 00258 00264 TVector4 operator * (const T& scalar); 00265 00271 TVector4& operator *= (const T& scalar); 00272 00279 TVector4 operator / (const T& scalar); 00280 00286 TVector4& operator /= (const T& scalar); 00287 00292 T operator * (const TVector4& vector) const; 00293 00298 T getDistance(const TVector4& vector) const; 00299 00306 T getSquareDistance(const TVector4& vector) const; 00307 00309 00312 00318 bool operator == (const TVector4& vector) const; 00319 00325 bool operator != (const TVector4& vector) const; 00326 00329 bool isOrthogonalTo(const TVector4& vector) const; 00330 00332 00335 00340 bool isValid() const; 00341 00348 void dump(std::ostream& s = std::cout, Size depth = 0) const; 00349 00351 00355 00358 T x; 00359 00362 T y; 00363 00366 T z; 00367 00370 T h; 00371 00373 }; 00375 00376 template <typename T> 00377 TVector4<T>::TVector4() 00378 : x(0), 00379 y(0), 00380 z(0), 00381 h(0) 00382 { 00383 } 00384 00385 template <typename T> 00386 TVector4<T>::TVector4(const T* ptr) 00387 { 00388 if (ptr == 0) 00389 { 00390 throw Exception::NullPointer(__FILE__, __LINE__); 00391 } 00392 00393 x = *ptr++; 00394 y = *ptr++; 00395 z = *ptr++; 00396 h = *ptr; 00397 } 00398 00399 00400 template <typename T> 00401 TVector4<T>::TVector4(const T& value) 00402 : x(value), 00403 y(value), 00404 z(value), 00405 h(value) 00406 { 00407 } 00408 00409 template <typename T> 00410 TVector4<T>::TVector4(const T& x, const T& y, const T& z, const T& h) 00411 : x(x), 00412 y(y), 00413 z(z), 00414 h(h) 00415 { 00416 } 00417 00418 template <typename T> 00419 TVector4<T>::TVector4(const TVector4<T>& v) 00420 : x(v.x), 00421 y(v.y), 00422 z(v.z), 00423 h(v.h) 00424 { 00425 } 00426 00427 template <typename T> 00428 TVector4<T>::~TVector4() 00429 { 00430 } 00431 00432 template <typename T> 00433 BALL_INLINE 00434 void TVector4<T>::set(const T* ptr) 00435 { 00436 if (ptr == 0) 00437 { 00438 throw Exception::NullPointer(__FILE__, __LINE__); 00439 } 00440 x = *ptr++; 00441 y = *ptr++; 00442 z = *ptr++; 00443 h = *ptr; 00444 } 00445 00446 template <typename T> 00447 BALL_INLINE 00448 void TVector4<T>::set(const T& rx, const T& ry, const T& rz, const T& rh) 00449 { 00450 x = rx; 00451 y = ry; 00452 z = rz; 00453 h = rh; 00454 } 00455 00456 template <typename T> 00457 BALL_INLINE 00458 void TVector4<T>::set(const TVector4<T>& v) 00459 { 00460 x = v.x; 00461 y = v.y; 00462 z = v.z; 00463 h = v.h; 00464 } 00465 00466 template <typename T> 00467 BALL_INLINE 00468 TVector4<T>& TVector4<T>::operator = (const T* ptr) 00469 { 00470 if (ptr == 0) 00471 { 00472 throw Exception::NullPointer(__FILE__, __LINE__); 00473 } 00474 x = *ptr++; 00475 y = *ptr++; 00476 z = *ptr++; 00477 h = *ptr; 00478 00479 return *this; 00480 } 00481 00482 template <typename T> 00483 BALL_INLINE 00484 TVector4<T>& TVector4<T>::operator = (const TVector4<T>& v) 00485 { 00486 x = v.x; 00487 y = v.y; 00488 z = v.z; 00489 h = v.h; 00490 00491 return *this; 00492 } 00493 00494 template <typename T> 00495 BALL_INLINE 00496 TVector4<T>& TVector4<T>::operator = (T value) 00497 { 00498 x = value; 00499 y = value; 00500 z = value; 00501 h = value; 00502 00503 return *this; 00504 } 00505 00506 template <typename T> 00507 BALL_INLINE 00508 void TVector4<T>::get(T* ptr) const 00509 { 00510 if (ptr == 0) 00511 { 00512 throw Exception::NullPointer(__FILE__, __LINE__); 00513 } 00514 *ptr++ = x; 00515 *ptr++ = y; 00516 *ptr++ = z; 00517 *ptr = h; 00518 } 00519 00520 template <typename T> 00521 BALL_INLINE 00522 void TVector4<T>::get(T& rx, T& ry, T& rz, T& rh) const 00523 { 00524 rx = x; 00525 ry = y; 00526 rz = z; 00527 rh = h; 00528 } 00529 00530 template <typename T> 00531 BALL_INLINE 00532 void TVector4<T>::get(TVector4<T>& v) const 00533 { 00534 v.x = x; 00535 v.y = y; 00536 v.z = z; 00537 v.h = h; 00538 } 00539 00540 template <typename T> 00541 void TVector4<T>::swap(TVector4<T>& v) 00542 { 00543 T temp = x; 00544 x = v.x; 00545 v.x = temp; 00546 00547 temp = y; 00548 y = v.y; 00549 v.y = temp; 00550 00551 temp = z; 00552 z = v.z; 00553 v.z = temp; 00554 00555 temp = h; 00556 h = v.h; 00557 v.h = temp; 00558 } 00559 00560 template <typename T> 00561 BALL_INLINE 00562 T TVector4<T>::getLength() const 00563 { 00564 return (T)sqrt(x * x + y * y + z * z + h * h); 00565 } 00566 00567 template <typename T> 00568 BALL_INLINE 00569 T TVector4<T>::getSquareLength() const 00570 { 00571 return (T)(x * x + y * y + z * z + h * h); 00572 } 00573 00574 template <typename T> 00575 BALL_INLINE 00576 TVector4<T>& TVector4<T>::normalize() 00577 { 00578 T len = (T)sqrt(x * x + y * y + z * z + h * h); 00579 00580 if (Maths::isZero(len)) 00581 { 00582 throw Exception::DivisionByZero(__FILE__, __LINE__); 00583 } 00584 00585 x /= len; 00586 y /= len; 00587 z /= len; 00588 h /= len; 00589 00590 return *this; 00591 } 00592 00593 template <typename T> 00594 BALL_INLINE 00595 const TVector4<T>& TVector4<T>::getZero() 00596 { 00597 static const TVector4<T> null4(0, 0, 0, 0); 00598 return null4; 00599 } 00600 00601 template <typename T> 00602 BALL_INLINE 00603 const TVector4<T>& TVector4<T>::getUnit() 00604 { 00605 static const TVector4<T> unit_vector(1, 1, 1, 1); 00606 return unit_vector; 00607 } 00608 00609 template <typename T> 00610 BALL_INLINE 00611 void TVector4<T>::set(const T& value) 00612 { 00613 x = y = z = h = value; 00614 } 00615 00616 template <typename T> 00617 BALL_INLINE 00618 T& TVector4<T>::operator [] (Position pos) 00619 { 00620 if (pos > 3) 00621 { 00622 throw Exception::IndexOverflow(__FILE__, __LINE__); 00623 } 00624 switch (pos) 00625 { 00626 case 0: return x; 00627 case 1: return y; 00628 case 2: return z; 00629 case 3: 00630 default: 00631 return h; 00632 } 00633 } 00634 00635 template <typename T> 00636 BALL_INLINE 00637 const T& TVector4<T>::operator [] (Position pos) const 00638 { 00639 if (pos > 3) 00640 { 00641 throw Exception::IndexOverflow(__FILE__, __LINE__); 00642 } 00643 switch (pos) 00644 { 00645 case 0: return x; 00646 case 1: return y; 00647 case 2: return z; 00648 case 3: 00649 default: 00650 return h; 00651 } 00652 } 00653 00654 template <typename T> 00655 BALL_INLINE 00656 TVector4<T> TVector4<T>::operator + () const 00657 { 00658 return *this; 00659 } 00660 00661 template <typename T> 00662 BALL_INLINE 00663 TVector4<T> TVector4<T>::operator - () const 00664 { 00665 return TVector4<T>(-x, -y, -z, -h); 00666 } 00667 00668 template <typename T> 00669 BALL_INLINE 00670 TVector4<T>& TVector4<T>::operator += (const TVector4<T>& v) 00671 { 00672 x += v.x; 00673 y += v.y; 00674 z += v.z; 00675 h += v.h; 00676 00677 return *this; 00678 } 00679 00680 template <typename T> 00681 BALL_INLINE 00682 TVector4<T>& TVector4<T>::operator -= (const TVector4<T> &v) 00683 { 00684 x -= v.x; 00685 y -= v.y; 00686 z -= v.z; 00687 h -= v.h; 00688 00689 return *this; 00690 } 00691 00692 template <typename T> 00693 BALL_INLINE 00694 TVector4<T> TVector4<T>::operator * (const T& scalar) 00695 { 00696 return TVector4<T>(x * scalar, y * scalar, z * scalar, h * scalar); 00697 } 00698 00699 template <typename T> 00700 BALL_INLINE 00701 TVector4<T>& TVector4<T>::operator *= (const T &scalar) 00702 { 00703 x *= scalar; 00704 y *= scalar; 00705 z *= scalar; 00706 h *= scalar; 00707 00708 return *this; 00709 } 00710 00711 template <typename T> 00712 TVector4<T>TVector4<T>::operator / (const T &scalar) 00713 { 00714 if (Maths::isZero(scalar)) 00715 { 00716 throw Exception::DivisionByZero(__FILE__, __LINE__); 00717 } 00718 return TVector4<T>(x / scalar, y / scalar, z / scalar, h / scalar); 00719 } 00720 00721 template <typename T> 00722 TVector4<T>& TVector4<T>::operator /= (const T& scalar) 00723 { 00724 if (Maths::isZero(scalar)) 00725 { 00726 throw Exception::DivisionByZero(__FILE__, __LINE__); 00727 } 00728 x /= scalar; 00729 y /= scalar; 00730 z /= scalar; 00731 h /= scalar; 00732 00733 return *this; 00734 } 00735 00736 template <typename T> 00737 BALL_INLINE 00738 T TVector4<T>::operator * (const TVector4<T>& v) const 00739 { 00740 return (x * v.x + y * v.y + z * v.z + h * v.h); 00741 } 00742 00743 template <typename T> 00744 BALL_INLINE 00745 T TVector4<T>::getDistance(const TVector4<T> &v) const 00746 { 00747 T da = x - v.x; 00748 T db = y - v.y; 00749 T dc = z - v.z; 00750 T dd = h - v.h; 00751 00752 return (T)sqrt(da * da + db * db + dc * dc + dd * dd); 00753 } 00754 00755 template <typename T> 00756 BALL_INLINE 00757 T TVector4<T>::getSquareDistance(const TVector4<T> &v) const 00758 { 00759 T da = x - v.x; 00760 T db = y - v.y; 00761 T dc = z - v.z; 00762 T dd = h - v.h; 00763 00764 return (da * da + db * db + dc * dc + dd * dd); 00765 } 00766 00767 template <typename T> 00768 BALL_INLINE 00769 bool TVector4<T>::operator == (const TVector4<T>& v) const 00770 { 00771 return (Maths::isEqual(x, v.x) && Maths::isEqual(y, v.y) 00772 && Maths::isEqual(z, v.z) && Maths::isEqual(h, v.h)); 00773 } 00774 00775 template <typename T> 00776 BALL_INLINE 00777 bool TVector4<T>::operator != (const TVector4<T>& v) const 00778 { 00779 return (Maths::isNotEqual(x, v.x) || Maths::isNotEqual(y, v.y) 00780 || Maths::isNotEqual(z, v.z) || Maths::isNotEqual(h, v.h)); 00781 } 00782 00783 template <typename T> 00784 BALL_INLINE 00785 bool TVector4<T>::isOrthogonalTo(const TVector4<T>& v) const 00786 { 00787 return Maths::isZero(*this * v); 00788 } 00789 00790 template <typename T> 00791 BALL_INLINE 00792 bool TVector4<T>::isValid() const 00793 { 00794 return true; 00795 } 00796 00797 template <typename T> 00798 void TVector4<T>::dump(std::ostream& s, Size depth) const 00799 { 00800 BALL_DUMP_STREAM_PREFIX(s); 00801 00802 BALL_DUMP_HEADER(s, this, this); 00803 00804 BALL_DUMP_DEPTH(s, depth); 00805 s << "x= " << x 00806 << ", y = " << y 00807 << ", z = " << z 00808 << ", h = " << h << std::endl; 00809 00810 BALL_DUMP_STREAM_SUFFIX(s); 00811 } 00812 00815 typedef TVector4<float> Vector4; 00816 00819 template <typename T> 00820 BALL_INLINE 00821 TVector4<T> operator + (const TVector4<T>& a, const TVector4<T>& b) 00822 { 00823 return TVector4<T>(a.x + b.x, a.y + b.y, a.z + b.z, a.h + b.h); 00824 } 00825 00829 template <typename T> 00830 BALL_INLINE 00831 TVector4<T> operator - (const TVector4<T>& a, const TVector4<T>& b) 00832 { 00833 return TVector4<T>(a.x - b.x, a.y - b.y, a.z - b.z, a.h - b.h); 00834 } 00835 00839 template <typename T> 00840 BALL_INLINE 00841 TVector4<T> operator * (const T& scalar, const TVector4<T>& v) 00842 { 00843 return TVector4<T>(scalar * v.x, scalar * v.y, scalar * v.z, scalar * v.h); 00844 } 00845 00849 template <typename T> 00850 BALL_INLINE 00851 TVector4<T> operator * (const TVector4<T>& v, const T& scalar) 00852 { 00853 return TVector4<T>(scalar * v.x, scalar * v.y, scalar * v.z, scalar * v.h); 00854 } 00855 00860 template <typename T> 00861 std::istream& operator >> (std::istream& s, TVector4<T>& v) 00862 { 00863 char c; 00864 s >> c >> v.x >> v.y >> v.z >> v.h >>c; 00865 return s; 00866 } 00867 00874 template <typename T> 00875 std::ostream& operator << (std::ostream& s, const TVector4<T>& v) 00876 { 00877 s << '(' <<v.x << ' ' << v.y << ' ' << v.z << ' ' << v.h << ')'; 00878 00879 return s; 00880 } 00881 } // namespace BALL 00882 00883 #endif // BALL_MATHS_VECTOR4_H