00001
00002
00003
00004
00005
00006
00007 #ifndef BALL_MATHS_VECTOR2_H
00008 #define BALL_MATHS_VECTOR2_H
00009
00010 #ifndef BALL_CONCEPT_PERSISTENCEMANAGER_H
00011 # include <BALL/CONCEPT/persistenceManager.h>
00012 #endif
00013
00014 #ifndef BALL_COMMON_EXCEPTION_H
00015 # include <BALL/COMMON/exception.h>
00016 #endif
00017
00018 #ifndef BALL_MATHS_COMMON_H
00019 # include <BALL/MATHS/common.h>
00020 #endif
00021
00022
00023 namespace BALL
00024 {
00025
00033
00034 template <typename T>
00035 class TVector2;
00036
00040
00044 template <typename T>
00045 BALL_INLINE
00046 TVector2<T> operator * (const T& scalar, const TVector2<T>& vector);
00047
00050 template <typename T>
00051 std::istream& operator >> (std::istream& s, TVector2<T>& vector)
00052 ;
00053
00054
00055
00056 template <typename T>
00057 std::ostream& operator << (std::ostream& s, const TVector2<T>& vector);
00058
00060
00063 template <typename T>
00064 class TVector2
00065 : public PersistentObject
00066 {
00067 public:
00068
00069 BALL_CREATE(TVector2<T>)
00070
00071
00074
00079 TVector2()
00080 ;
00081
00087 explicit TVector2(const T& value)
00088 ;
00089
00095 TVector2(const T& vx, const T& vy)
00096 ;
00097
00102 TVector2(const TVector2& vector)
00103 ;
00104
00111 TVector2(const T* ptr)
00112 throw(Exception::NullPointer);
00113
00114
00119 virtual ~TVector2()
00120 ;
00121
00125 virtual void clear()
00126 ;
00127
00129
00133
00138 virtual void persistentWrite(PersistenceManager& pm,
00139 const char* name = 0) const
00140 throw(Exception::GeneralException);
00141
00146 virtual void persistentRead(PersistenceManager& pm)
00147 throw(Exception::GeneralException);
00148
00150
00154
00159 void set(const T& value)
00160 ;
00161
00166 void set(const T& vx, const T& vy)
00167 ;
00168
00172 void set(const TVector2& vector)
00173 ;
00174
00179 TVector2& operator = (const TVector2& v)
00180 ;
00181
00186 TVector2& operator = (const T& value)
00187 ;
00188
00194 TVector2& operator = (const T* ptr)
00195 throw(Exception::NullPointer);
00196
00202 T getLength() const
00203 ;
00204
00210 T getSquareLength() const
00211 ;
00212
00219 TVector2& normalize()
00220 throw(Exception::DivisionByZero);
00221
00226 TVector2& negate()
00227 ;
00228
00231 static const TVector2& getZero()
00232 ;
00233
00237 static const TVector2& getUnit()
00238 ;
00239
00243 T& operator [] (Position position)
00244 throw(Exception::IndexOverflow);
00245
00249 const T& operator [] (Position position) const
00250 throw(Exception::IndexOverflow);
00251
00253
00256
00259 const TVector2& operator + () const
00260 ;
00261
00264 TVector2 operator - () const
00265 ;
00266
00269 TVector2 operator + (const TVector2& b) const
00270 ;
00271
00274 TVector2 operator - (const TVector2& b) const
00275 ;
00276
00282 TVector2& operator += (const TVector2& vector)
00283 ;
00284
00289 TVector2& operator -= (const TVector2& vector)
00290 ;
00291
00298 TVector2 operator * (const T& scalar) const
00299 ;
00300
00306 TVector2& operator *= (const T& scalar)
00307 ;
00308
00315 TVector2 operator / (const T& lambda) const
00316 throw(Exception::DivisionByZero);
00317
00323 TVector2& operator /= (const T& lambda)
00324 throw(Exception::DivisionByZero);
00325
00329 T operator * (const TVector2& vector) const
00330 ;
00331
00333
00337
00340 T getDistance(const TVector2& vector) const
00341 ;
00342
00345 T getSquareDistance(const TVector2& vector) const
00346 ;
00347
00349
00353
00359 bool operator == (const TVector2& vector) const
00360 ;
00361
00367 bool operator != (const TVector2& vector) const
00368 ;
00369
00374 bool isZero() const
00375 ;
00376
00379 bool isOrthogonalTo(TVector2& vector) const
00380 ;
00381
00383
00384
00388
00395 void dump(std::ostream& s = std::cout, Size depth = 0) const
00396 ;
00397
00402 bool isValid() const
00403 ;
00404
00406
00407
00413
00416 T x;
00417
00420 T y;
00421
00423
00424 private:
00425
00426 };
00428
00429 template <typename T>
00430 TVector2<T>::TVector2()
00431
00432 : PersistentObject(),
00433 x(0),
00434 y(0)
00435 {
00436 }
00437
00438 template <typename T>
00439 TVector2<T>::TVector2(const T& value)
00440
00441 : PersistentObject(),
00442 x(value),
00443 y(value)
00444 {
00445 }
00446
00447 template <typename T>
00448 TVector2<T>::TVector2(const T& vx, const T& vy)
00449
00450 : PersistentObject(),
00451 x(vx),
00452 y(vy)
00453 {
00454 }
00455
00456 template <typename T>
00457 TVector2<T>::TVector2(const TVector2& vector)
00458
00459 : PersistentObject(),
00460 x(vector.x),
00461 y(vector.y)
00462 {
00463 }
00464
00465 template <typename T>
00466 TVector2<T>::~TVector2()
00467
00468 {
00469 }
00470
00471 template <typename T>
00472 BALL_INLINE
00473 TVector2<T>::TVector2(const T* ptr)
00474 throw(Exception::NullPointer)
00475 {
00476 if (ptr == 0)
00477 {
00478 throw Exception::NullPointer(__FILE__, __LINE__);
00479 }
00480
00481 x = *ptr++;
00482 y = *ptr;
00483 }
00484
00485 template <typename T>
00486 void TVector2<T>::clear()
00487
00488 {
00489 x = y = (T)0;
00490 }
00491
00492 template <typename T>
00493 void TVector2<T>::persistentWrite(PersistenceManager& pm, const char* name) const
00494 throw(Exception::GeneralException)
00495 {
00496 pm.writeObjectHeader(this, name);
00497 pm.writePrimitive(x, "x");
00498 pm.writePrimitive(y, "y");
00499 pm.writeObjectTrailer(name);
00500 }
00501
00502 template <typename T>
00503 void TVector2<T>::persistentRead(PersistenceManager& pm)
00504 throw(Exception::GeneralException)
00505 {
00506 pm.readPrimitive(x, "x");
00507 pm.readPrimitive(y, "y");
00508 }
00509
00510 template <typename T>
00511 BALL_INLINE
00512 void TVector2<T>::set(const T& value)
00513
00514 {
00515 x = value;
00516 y = value;
00517 }
00518
00519 template <typename T>
00520 BALL_INLINE
00521 void TVector2<T>::set(const T& vx, const T& vy)
00522
00523 {
00524 x = vx;
00525 y = vy;
00526 }
00527
00528 template <typename T>
00529 BALL_INLINE
00530 void TVector2<T>::set(const TVector2<T>& vector)
00531
00532 {
00533 x = vector.x;
00534 y = vector.y;
00535 }
00536
00537 template <typename T>
00538 BALL_INLINE
00539 TVector2<T>& TVector2<T>::operator = (const TVector2<T>& vector)
00540
00541 {
00542 x = vector.x;
00543 y = vector.y;
00544
00545 return *this;
00546 }
00547
00548 template <typename T>
00549 BALL_INLINE
00550 TVector2<T>& TVector2<T>::operator = (const T* ptr)
00551 throw(Exception::NullPointer)
00552 {
00553 if (ptr == 0)
00554 {
00555 throw Exception::NullPointer(__FILE__, __LINE__);
00556 }
00557 x = *ptr++;;
00558 y = *ptr;;
00559
00560 return *this;
00561 }
00562
00563 template <typename T>
00564 BALL_INLINE
00565 TVector2<T>& TVector2<T>::operator = (const T& value)
00566
00567 {
00568 x = value;
00569 y = value;
00570
00571 return *this;
00572 }
00573
00574 template <typename T>
00575 BALL_INLINE
00576 T TVector2<T>::getLength() const
00577
00578 {
00579 return (T)sqrt(x * x + y * y);
00580 }
00581
00582 template <typename T>
00583 BALL_INLINE
00584 T TVector2<T>::getSquareLength() const
00585
00586 {
00587 return (T)(x * x + y * y);
00588 }
00589
00590 template <typename T>
00591 TVector2<T>& TVector2<T>::normalize()
00592 throw(Exception::DivisionByZero)
00593 {
00594 T len = (T)sqrt(x * x + y * y);
00595
00596 if (Maths::isZero(len))
00597 {
00598 throw Exception::DivisionByZero(__FILE__, __LINE__);
00599 }
00600
00601 x /= len;
00602 y /= len;
00603
00604 return *this;
00605 }
00606
00607 template <typename T>
00608 TVector2<T>& TVector2<T>::negate()
00609
00610 {
00611 x *= -1;
00612 y *= -1;
00613 return *this;
00614 }
00615
00616 template <typename T>
00617 BALL_INLINE
00618 const TVector2<T>& TVector2<T>::getZero()
00619
00620 {
00621 static TVector2<T> null_vector(0, 0);
00622 return null_vector;
00623 }
00624
00625 template <typename T>
00626 BALL_INLINE
00627 const TVector2<T>& TVector2<T>::getUnit()
00628
00629 {
00630 static TVector2<T> unit_vector(1, 1);
00631 return unit_vector;
00632 }
00633
00634 template <typename T>
00635 BALL_INLINE
00636 T& TVector2<T>::operator [] (Position position)
00637 throw(Exception::IndexOverflow)
00638 {
00639 if (position > 1)
00640 {
00641 throw Exception::IndexOverflow(__FILE__, __LINE__);
00642 }
00643 switch (position)
00644 {
00645 case 0: return x;
00646 case 1:
00647 default:
00648 return y;
00649 }
00650 }
00651
00652 template <typename T>
00653 BALL_INLINE
00654 const T& TVector2<T>::operator [] (Position position) const
00655 throw(Exception::IndexOverflow)
00656 {
00657 if (position > 1)
00658 {
00659 throw Exception::IndexOverflow(__FILE__, __LINE__);
00660 }
00661 switch (position)
00662 {
00663 case 0: return x;
00664 case 1:
00665 default:
00666 return y;
00667 }
00668 }
00669
00670 template <typename T>
00671 BALL_INLINE
00672 const TVector2<T>& TVector2<T>::operator + () const
00673
00674 {
00675 return *this;
00676 }
00677
00678 template <typename T>
00679 BALL_INLINE
00680 TVector2<T> TVector2<T>::operator - () const
00681
00682 {
00683 return TVector2<T>(-x, -y);
00684 }
00685
00686 template <typename T>
00687 BALL_INLINE
00688 TVector2<T> TVector2<T>::operator + (const TVector2<T>& b) const
00689
00690 {
00691 return TVector2<T>(x + b.x, y + b.y);
00692 }
00693
00694 template <typename T>
00695 BALL_INLINE
00696 TVector2<T> TVector2<T>::operator - (const TVector2<T>& b) const
00697
00698 {
00699 return TVector2<T>(x - b.x, y - b.y);
00700 }
00701
00702 template <typename T>
00703 BALL_INLINE
00704 TVector2<T>& TVector2<T>::operator += (const TVector2<T>& vector)
00705
00706 {
00707 x += vector.x;
00708 y += vector.y;
00709
00710 return *this;
00711 }
00712
00713 template <typename T>
00714 BALL_INLINE
00715 TVector2<T>& TVector2<T>::operator -= (const TVector2<T>& vector)
00716
00717 {
00718 x -= vector.x;
00719 y -= vector.y;
00720
00721 return *this;
00722 }
00723
00724 template <typename T>
00725 BALL_INLINE
00726 TVector2<T> TVector2<T>::operator * (const T& scalar) const
00727
00728 {
00729 return TVector2<T>(x * scalar, y * scalar);
00730 }
00731
00732 template <typename T>
00733 BALL_INLINE
00734 TVector2<T>& TVector2<T>::operator *= (const T &scalar)
00735
00736 {
00737 x *= scalar;
00738 y *= scalar;
00739
00740 return *this;
00741 }
00742
00743 template <typename T>
00744 TVector2<T> TVector2<T>::operator / (const T& lambda) const
00745 throw(Exception::DivisionByZero)
00746 {
00747 if (lambda == (T)0)
00748 {
00749 throw Exception::DivisionByZero(__FILE__, __LINE__);
00750 }
00751 return TVector2<T>(x / lambda, y / lambda);
00752 }
00753
00754 template <typename T>
00755 TVector2<T>& TVector2<T>::operator /= (const T& lambda)
00756 throw(Exception::DivisionByZero)
00757 {
00758 if (lambda == (T)0)
00759 {
00760 throw Exception::DivisionByZero(__FILE__, __LINE__);
00761 }
00762 x /= lambda;
00763 y /= lambda;
00764
00765 return *this;
00766 }
00767
00768 template <typename T>
00769 BALL_INLINE
00770 T TVector2<T>::operator * (const TVector2<T>& vector) const
00771
00772 {
00773 return (x * vector.x + y * vector.y);
00774 }
00775
00776 template <typename T>
00777 BALL_INLINE
00778 T TVector2<T>::getDistance(const TVector2<T>& v) const
00779
00780 {
00781 T dx = x - v.x;
00782 T dy = y - v.y;
00783
00784 return (T)sqrt(dx * dx + dy * dy);
00785 }
00786
00787 template <typename T>
00788 BALL_INLINE
00789 T TVector2<T>::getSquareDistance(const TVector2<T>& v) const
00790
00791 {
00792 T dx = x - v.x;
00793 T dy = y - v.y;
00794
00795 return (dx * dx + dy * dy);
00796 }
00797
00798 template <typename T>
00799 BALL_INLINE
00800 bool TVector2<T>::operator == (const TVector2<T>& v) const
00801
00802 {
00803 return (Maths::isEqual(x, v.x) && Maths::isEqual(y, v.y));
00804 }
00805
00806 template <typename T>
00807 BALL_INLINE
00808 bool TVector2<T>::operator != (const TVector2<T>& v) const
00809
00810 {
00811 return (Maths::isNotEqual(x, v.x) || Maths::isNotEqual(y, v.y));
00812 }
00813
00814 template <typename T>
00815 BALL_INLINE
00816 bool TVector2<T>::isOrthogonalTo(TVector2<T>& v) const
00817
00818 {
00819 return Maths::isZero((*this) * v);
00820 }
00821
00822 template <typename T>
00823 BALL_INLINE
00824 bool TVector2<T>::isValid() const
00825
00826 {
00827 return true;
00828 }
00829
00830 template <typename T>
00831 BALL_INLINE
00832 bool TVector2<T>::isZero() const
00833
00834 {
00835 return (Maths::isZero(x) && Maths::isZero(y));
00836 }
00837
00838 template <typename T>
00839 void TVector2<T>::dump(std::ostream& s, Size depth) const
00840
00841 {
00842 BALL_DUMP_STREAM_PREFIX(s);
00843
00844 BALL_DUMP_HEADER(s, this, this);
00845
00846 BALL_DUMP_DEPTH(s, depth);
00847 s << " (x = " << x << ", y = " << y << ")" << std::endl;
00848
00849 BALL_DUMP_STREAM_SUFFIX(s);
00850 }
00851
00857 typedef TVector2<float> Vector2;
00858
00859 template <typename T>
00860 BALL_INLINE
00861 TVector2<T> operator * (const T& scalar, const TVector2<T>& vector)
00862
00863 {
00864 return TVector2<T>(scalar * vector.x, scalar * vector.y);
00865 }
00866
00867 template <typename T>
00868 std::istream& operator >> (std::istream& s, TVector2<T>& v)
00869
00870 {
00871 char c;
00872 s >> c >> v.x >> v.y >> c;
00873
00874 return s;
00875 }
00876
00877 template <typename T>
00878 std::ostream& operator << (std::ostream& s, const TVector2<T>& v)
00879
00880 {
00881 s << "(" << v.x << ' ' << v.y << ')';
00882
00883 return s;
00884 }
00885
00886 }
00887
00888 #endif // BALL_MATHS_VECTOR2_H