00001
00002
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 }
00882
00883 #endif // BALL_MATHS_VECTOR4_H