00001
00002
00003
00004
00005
00006
00007 #ifndef BALL_MATHS_VECTOR4_H
00008 #define BALL_MATHS_VECTOR4_H
00009
00010 #ifndef BALL_COMMON_EXCEPTION_H
00011 # include <BALL/COMMON/exception.h>
00012 #endif
00013
00014 #ifndef BALL_MATHS_ANGLE_H
00015 # include <BALL/MATHS/angle.h>
00016 #endif
00017
00018 #ifdef BALL_HAS_IEEEFP_H
00019 # include <ieeefp.h>
00020 #endif
00021
00022 namespace BALL
00023 {
00028
00029 template <typename T>
00030 class TVector4;
00031
00035
00036 template <typename T>
00037 BALL_INLINE
00038 TVector4<T> operator + (const TVector4<T>& a, const TVector4<T>& b);
00039
00040 template <typename T>
00041 BALL_INLINE
00042 TVector4<T> operator - (const TVector4<T>& a, const TVector4<T>& b);
00043
00044 template <typename T>
00045 std::istream& operator >> (std::istream& s, TVector4<T>& vector);
00046
00047 template <typename T>
00048 std::ostream& operator << (std::ostream& s, const TVector4<T>& vector);
00049
00053 template <typename T>
00054 class TVector4
00055 {
00056 public:
00057
00058 BALL_CREATE(TVector4<T>)
00059
00060
00063
00068 TVector4();
00069
00076 TVector4(const T* ptr)
00077 throw(Exception::NullPointer);
00078
00084 explicit TVector4(const T& value);
00085
00093 TVector4(const T& x, const T& y, const T& z, const T& h = (T)1);
00094
00099 TVector4(const TVector4& vector);
00100
00105 virtual ~TVector4();
00106
00110 virtual void clear()
00111 {
00112 x = y = z = h = (T)0;
00113 }
00114
00116
00119
00126 void set(const T* ptr)
00127 throw(Exception::NullPointer);
00128
00135 void set(const T& rx, const T& ry, const T& rz, const T& rh = (T)1);
00136
00140 void set(const TVector4& vector);
00141
00147 TVector4& operator = (const T* ptr)
00148 throw(Exception::NullPointer);
00149
00154 TVector4& operator = (const TVector4& vector);
00155
00160 TVector4& operator = (T value);
00161
00168 void get(T* ptr) const
00169 throw(Exception::NullPointer);
00170
00177 void get(T& rx, T& ry, T& rz, T& rh) const;
00178
00183 void get(TVector4& vector) const;
00184
00188 void swap(TVector4& vector);
00189
00191
00194
00200 T getLength() const;
00201
00207 T getSquareLength() const;
00208
00215 TVector4& normalize()
00216 throw(Exception::DivisionByZero);
00217
00220 static const TVector4& getZero();
00221
00224 static const TVector4& getUnit();
00225
00229 void set(const T& value = (T)1);
00230
00234 T& operator [] (Position position)
00235 throw(Exception::IndexOverflow);
00236
00240 const T& operator [] (Position position) const
00241 throw(Exception::IndexOverflow);
00242
00244
00247
00250 TVector4 operator + () const;
00251
00254 TVector4 operator - () const;
00255
00260 TVector4& operator += (const TVector4& vector);
00261
00266 TVector4& operator -= (const TVector4& vector);
00267
00273 TVector4 operator * (const T& scalar);
00274
00280 TVector4& operator *= (const T& scalar);
00281
00288 TVector4 operator / (const T& scalar)
00289 throw(Exception::DivisionByZero);
00290
00296 TVector4& operator /= (const T& scalar)
00297 throw(Exception::DivisionByZero);
00298
00303 T operator * (const TVector4& vector) const;
00304
00309 T getDistance(const TVector4& vector) const;
00310
00317 T getSquareDistance(const TVector4& vector) const
00318 ;
00319
00321
00324
00330 bool operator == (const TVector4& vector) const
00331 ;
00332
00338 bool operator != (const TVector4& vector) const
00339 ;
00340
00343 bool isOrthogonalTo(const TVector4& vector) const
00344 ;
00345
00347
00350
00355 bool isValid() const
00356 ;
00357
00364 void dump(std::ostream& s = std::cout, Size depth = 0) const
00365 ;
00366
00368
00372
00375 T x;
00376
00379 T y;
00380
00383 T z;
00384
00387 T h;
00388
00390 };
00392
00393 template <typename T>
00394 TVector4<T>::TVector4()
00395
00396 : x(0),
00397 y(0),
00398 z(0),
00399 h(0)
00400 {
00401 }
00402
00403 template <typename T>
00404 TVector4<T>::TVector4(const T* ptr)
00405 throw(Exception::NullPointer)
00406 {
00407 if (ptr == 0)
00408 {
00409 throw Exception::NullPointer(__FILE__, __LINE__);
00410 }
00411
00412 x = *ptr++;
00413 y = *ptr++;
00414 z = *ptr++;
00415 h = *ptr;
00416 }
00417
00418
00419 template <typename T>
00420 TVector4<T>::TVector4(const T& value)
00421
00422 : x(value),
00423 y(value),
00424 z(value),
00425 h(value)
00426 {
00427 }
00428
00429 template <typename T>
00430 TVector4<T>::TVector4(const T& x, const T& y, const T& z, const T& h)
00431
00432 : x(x),
00433 y(y),
00434 z(z),
00435 h(h)
00436 {
00437 }
00438
00439 template <typename T>
00440 TVector4<T>::TVector4(const TVector4<T>& v)
00441
00442 : x(v.x),
00443 y(v.y),
00444 z(v.z),
00445 h(v.h)
00446 {
00447 }
00448
00449 template <typename T>
00450 TVector4<T>::~TVector4()
00451
00452 {
00453 }
00454
00455 template <typename T>
00456 BALL_INLINE
00457 void TVector4<T>::set(const T* ptr)
00458 throw(Exception::NullPointer)
00459 {
00460 if (ptr == 0)
00461 {
00462 throw Exception::NullPointer(__FILE__, __LINE__);
00463 }
00464 x = *ptr++;
00465 y = *ptr++;
00466 z = *ptr++;
00467 h = *ptr;
00468 }
00469
00470 template <typename T>
00471 BALL_INLINE
00472 void TVector4<T>::set(const T& rx, const T& ry, const T& rz, const T& rh)
00473
00474 {
00475 x = rx;
00476 y = ry;
00477 z = rz;
00478 h = rh;
00479 }
00480
00481 template <typename T>
00482 BALL_INLINE
00483 void TVector4<T>::set(const TVector4<T>& v)
00484
00485 {
00486 x = v.x;
00487 y = v.y;
00488 z = v.z;
00489 h = v.h;
00490 }
00491
00492 template <typename T>
00493 BALL_INLINE
00494 TVector4<T>& TVector4<T>::operator = (const T* ptr)
00495 throw(Exception::NullPointer)
00496 {
00497 if (ptr == 0)
00498 {
00499 throw Exception::NullPointer(__FILE__, __LINE__);
00500 }
00501 x = *ptr++;
00502 y = *ptr++;
00503 z = *ptr++;
00504 h = *ptr;
00505
00506 return *this;
00507 }
00508
00509 template <typename T>
00510 BALL_INLINE
00511 TVector4<T>& TVector4<T>::operator = (const TVector4<T>& v)
00512
00513 {
00514 x = v.x;
00515 y = v.y;
00516 z = v.z;
00517 h = v.h;
00518
00519 return *this;
00520 }
00521
00522 template <typename T>
00523 BALL_INLINE
00524 TVector4<T>& TVector4<T>::operator = (T value)
00525
00526 {
00527 x = value;
00528 y = value;
00529 z = value;
00530 h = value;
00531
00532 return *this;
00533 }
00534
00535 template <typename T>
00536 BALL_INLINE
00537 void TVector4<T>::get(T* ptr) const
00538 throw(Exception::NullPointer)
00539 {
00540 if (ptr == 0)
00541 {
00542 throw Exception::NullPointer(__FILE__, __LINE__);
00543 }
00544 *ptr++ = x;
00545 *ptr++ = y;
00546 *ptr++ = z;
00547 *ptr = h;
00548 }
00549
00550 template <typename T>
00551 BALL_INLINE
00552 void TVector4<T>::get(T& rx, T& ry, T& rz, T& rh) const
00553
00554 {
00555 rx = x;
00556 ry = y;
00557 rz = z;
00558 rh = h;
00559 }
00560
00561 template <typename T>
00562 BALL_INLINE
00563 void TVector4<T>::get(TVector4<T>& v) const
00564
00565 {
00566 v.x = x;
00567 v.y = y;
00568 v.z = z;
00569 v.h = h;
00570 }
00571
00572 template <typename T>
00573 void TVector4<T>::swap(TVector4<T>& v)
00574
00575 {
00576 T temp = x;
00577 x = v.x;
00578 v.x = temp;
00579
00580 temp = y;
00581 y = v.y;
00582 v.y = temp;
00583
00584 temp = z;
00585 z = v.z;
00586 v.z = temp;
00587
00588 temp = h;
00589 h = v.h;
00590 v.h = temp;
00591 }
00592
00593 template <typename T>
00594 BALL_INLINE
00595 T TVector4<T>::getLength() const
00596
00597 {
00598 return (T)sqrt(x * x + y * y + z * z + h * h);
00599 }
00600
00601 template <typename T>
00602 BALL_INLINE
00603 T TVector4<T>::getSquareLength() const
00604
00605 {
00606 return (T)(x * x + y * y + z * z + h * h);
00607 }
00608
00609 template <typename T>
00610
00611 BALL_INLINE
00612 TVector4<T>& TVector4<T>::normalize()
00613 throw(Exception::DivisionByZero)
00614 {
00615 T len = (T)sqrt(x * x + y * y + z * z + h * h);
00616
00617 if (Maths::isZero(len))
00618 {
00619 throw Exception::DivisionByZero(__FILE__, __LINE__);
00620 }
00621
00622 x /= len;
00623 y /= len;
00624 z /= len;
00625 h /= len;
00626
00627 return *this;
00628 }
00629
00630 template <typename T>
00631 BALL_INLINE
00632 const TVector4<T>& TVector4<T>::getZero()
00633
00634 {
00635 static const TVector4<T> null4(0, 0, 0, 0);
00636 return null4;
00637 }
00638
00639 template <typename T>
00640 BALL_INLINE
00641 const TVector4<T>& TVector4<T>::getUnit()
00642
00643 {
00644 static const TVector4<T> unit_vector(1, 1, 1, 1);
00645 return unit_vector;
00646 }
00647
00648 template <typename T>
00649 BALL_INLINE
00650 void TVector4<T>::set(const T& value)
00651
00652 {
00653 x = y = z = h = value;
00654 }
00655
00656 template <typename T>
00657 BALL_INLINE
00658 T& TVector4<T>::operator [] (Position pos)
00659 throw(Exception::IndexOverflow)
00660 {
00661 if (pos > 3)
00662 {
00663 throw Exception::IndexOverflow(__FILE__, __LINE__);
00664 }
00665 switch (pos)
00666 {
00667 case 0: return x;
00668 case 1: return y;
00669 case 2: return z;
00670 case 3:
00671 default:
00672 return h;
00673 }
00674 }
00675
00676 template <typename T>
00677 BALL_INLINE
00678 const T& TVector4<T>::operator [] (Position pos) const
00679 throw(Exception::IndexOverflow)
00680 {
00681 if (pos > 3)
00682 {
00683 throw Exception::IndexOverflow(__FILE__, __LINE__);
00684 }
00685 switch (pos)
00686 {
00687 case 0: return x;
00688 case 1: return y;
00689 case 2: return z;
00690 case 3:
00691 default:
00692 return h;
00693 }
00694 }
00695
00696 template <typename T>
00697 BALL_INLINE
00698 TVector4<T> TVector4<T>::operator + () const
00699
00700 {
00701 return *this;
00702 }
00703
00704 template <typename T>
00705 BALL_INLINE
00706 TVector4<T> TVector4<T>::operator - () const
00707
00708 {
00709 return TVector4<T>(-x, -y, -z, -h);
00710 }
00711
00712 template <typename T>
00713 BALL_INLINE
00714 TVector4<T>& TVector4<T>::operator += (const TVector4<T>& v)
00715
00716 {
00717 x += v.x;
00718 y += v.y;
00719 z += v.z;
00720 h += v.h;
00721
00722 return *this;
00723 }
00724
00725 template <typename T>
00726 BALL_INLINE
00727 TVector4<T>& TVector4<T>::operator -= (const TVector4<T> &v)
00728
00729 {
00730 x -= v.x;
00731 y -= v.y;
00732 z -= v.z;
00733 h -= v.h;
00734
00735 return *this;
00736 }
00737
00738 template <typename T>
00739 BALL_INLINE
00740 TVector4<T> TVector4<T>::operator * (const T& scalar)
00741
00742 {
00743 return TVector4<T>(x * scalar, y * scalar, z * scalar, h * scalar);
00744 }
00745
00746 template <typename T>
00747 BALL_INLINE
00748 TVector4<T>& TVector4<T>::operator *= (const T &scalar)
00749
00750 {
00751 x *= scalar;
00752 y *= scalar;
00753 z *= scalar;
00754 h *= scalar;
00755
00756 return *this;
00757 }
00758
00759 template <typename T>
00760 TVector4<T>TVector4<T>::operator / (const T &scalar)
00761 throw(Exception::DivisionByZero)
00762 {
00763 if (Maths::isZero(scalar))
00764 {
00765 throw Exception::DivisionByZero(__FILE__, __LINE__);
00766 }
00767 return TVector4<T>(x / scalar, y / scalar, z / scalar, h / scalar);
00768 }
00769
00770 template <typename T>
00771 TVector4<T>& TVector4<T>::operator /= (const T& scalar)
00772 throw(Exception::DivisionByZero)
00773 {
00774 if (Maths::isZero(scalar))
00775 {
00776 throw Exception::DivisionByZero(__FILE__, __LINE__);
00777 }
00778 x /= scalar;
00779 y /= scalar;
00780 z /= scalar;
00781 h /= scalar;
00782
00783 return *this;
00784 }
00785
00786 template <typename T>
00787 BALL_INLINE
00788 T TVector4<T>::operator * (const TVector4<T>& v) const
00789
00790 {
00791 return (x * v.x + y * v.y + z * v.z + h * v.h);
00792 }
00793
00794 template <typename T>
00795 BALL_INLINE
00796 T TVector4<T>::getDistance(const TVector4<T> &v) const
00797
00798 {
00799 T da = x - v.x;
00800 T db = y - v.y;
00801 T dc = z - v.z;
00802 T dd = h - v.h;
00803
00804 return (T)sqrt(da * da + db * db + dc * dc + dd * dd);
00805 }
00806
00807 template <typename T>
00808 BALL_INLINE
00809 T TVector4<T>::getSquareDistance(const TVector4<T> &v) const
00810
00811 {
00812 T da = x - v.x;
00813 T db = y - v.y;
00814 T dc = z - v.z;
00815 T dd = h - v.h;
00816
00817 return (da * da + db * db + dc * dc + dd * dd);
00818 }
00819
00820 template <typename T>
00821 BALL_INLINE
00822 bool TVector4<T>::operator == (const TVector4<T>& v) const
00823
00824 {
00825 return (Maths::isEqual(x, v.x) && Maths::isEqual(y, v.y)
00826 && Maths::isEqual(z, v.z) && Maths::isEqual(h, v.h));
00827 }
00828
00829 template <typename T>
00830 BALL_INLINE
00831 bool TVector4<T>::operator != (const TVector4<T>& v) const
00832
00833 {
00834 return (Maths::isNotEqual(x, v.x) || Maths::isNotEqual(y, v.y)
00835 || Maths::isNotEqual(z, v.z) || Maths::isNotEqual(h, v.h));
00836 }
00837
00838 template <typename T>
00839 BALL_INLINE
00840 bool TVector4<T>::isOrthogonalTo(const TVector4<T>& v) const
00841
00842 {
00843 return Maths::isZero(*this * v);
00844 }
00845
00846 template <typename T>
00847 BALL_INLINE
00848 bool TVector4<T>::isValid() const
00849
00850 {
00851 return true;
00852 }
00853
00854 template <typename T>
00855 void TVector4<T>::dump(std::ostream& s, Size depth) const
00856
00857 {
00858 BALL_DUMP_STREAM_PREFIX(s);
00859
00860 BALL_DUMP_HEADER(s, this, this);
00861
00862 BALL_DUMP_DEPTH(s, depth);
00863 s << "x= " << x
00864 << ", y = " << y
00865 << ", z = " << z
00866 << ", h = " << h << std::endl;
00867
00868 BALL_DUMP_STREAM_SUFFIX(s);
00869 }
00870
00873 typedef TVector4<float> Vector4;
00874
00877 template <typename T>
00878 BALL_INLINE
00879 TVector4<T> operator + (const TVector4<T>& a, const TVector4<T>& b)
00880
00881 {
00882 return TVector4<T>(a.x + b.x, a.y + b.y, a.z + b.z, a.h + b.h);
00883 }
00884
00888 template <typename T>
00889 BALL_INLINE
00890 TVector4<T> operator - (const TVector4<T>& a, const TVector4<T>& b)
00891
00892 {
00893 return TVector4<T>(a.x - b.x, a.y - b.y, a.z - b.z, a.h - b.h);
00894 }
00895
00899 template <typename T>
00900 BALL_INLINE
00901 TVector4<T> operator * (const T& scalar, const TVector4<T>& v)
00902
00903 {
00904 return TVector4<T>(scalar * v.x, scalar * v.y, scalar * v.z, scalar * v.h);
00905 }
00906
00910 template <typename T>
00911 BALL_INLINE
00912 TVector4<T> operator * (const TVector4<T>& v, const T& scalar)
00913
00914 {
00915 return TVector4<T>(scalar * v.x, scalar * v.y, scalar * v.z, scalar * v.h);
00916 }
00917
00918
00923 template <typename T>
00924 std::istream& operator >> (std::istream& s, TVector4<T>& v)
00925
00926 {
00927 char c;
00928 s >> c >> v.x >> v.y >> v.z >> v.h >>c;
00929 return s;
00930 }
00931
00938 template <typename T>
00939 std::ostream& operator << (std::ostream& s, const TVector4<T>& v)
00940
00941 {
00942 s << '(' <<v.x << ' ' << v.y << ' ' << v.z << ' ' << v.h << ')';
00943
00944 return s;
00945 }
00946 }
00947
00948 #endif // BALL_MATHS_VECTOR4_H