00001
00002
00003
00004
00005 #ifndef BALL_MATHS_VECTOR2_H
00006 #define BALL_MATHS_VECTOR2_H
00007
00008 #ifndef BALL_CONCEPT_PERSISTENCEMANAGER_H
00009 # include <BALL/CONCEPT/persistenceManager.h>
00010 #endif
00011
00012 #ifndef BALL_COMMON_EXCEPTION_H
00013 # include <BALL/COMMON/exception.h>
00014 #endif
00015
00016 #ifndef BALL_MATHS_COMMON_H
00017 # include <BALL/MATHS/common.h>
00018 #endif
00019
00020
00021 namespace BALL
00022 {
00023
00031
00032 template <typename T>
00033 class TVector2;
00034
00038
00042 template <typename T>
00043 BALL_INLINE
00044 TVector2<T> operator * (const T& scalar, const TVector2<T>& vector);
00045
00048 template <typename T>
00049 std::istream& operator >> (std::istream& s, TVector2<T>& vector);
00050
00051
00052
00053 template <typename T>
00054 std::ostream& operator << (std::ostream& s, const TVector2<T>& vector);
00055
00057
00060 template <typename T>
00061 class TVector2
00062 : public PersistentObject
00063 {
00064 public:
00065
00066 BALL_CREATE(TVector2<T>)
00067
00068
00071
00076 TVector2();
00077
00083 explicit TVector2(const T& value);
00084
00090 TVector2(const T& vx, const T& vy);
00091
00096 TVector2(const TVector2& vector);
00097
00104 TVector2(const T* ptr);
00105
00106
00111 virtual ~TVector2();
00112
00116 virtual void clear();
00117
00119
00123
00128 virtual void persistentWrite(PersistenceManager& pm,
00129 const char* name = 0) const;
00130
00136 virtual void persistentRead(PersistenceManager& pm);
00137
00139
00143
00148 void set(const T& value);
00149
00154 void set(const T& vx, const T& vy);
00155
00159 void set(const TVector2& vector);
00160
00165 TVector2& operator = (const TVector2& v);
00166
00171 TVector2& operator = (const T& value);
00172
00178 TVector2& operator = (const T* ptr);
00179
00185 T getLength() const;
00186
00192 T getSquareLength() const;
00193
00200 TVector2& normalize();
00201
00206 TVector2& negate();
00207
00210 static const TVector2& getZero();
00211
00215 static const TVector2& getUnit();
00216
00220 T& operator [] (Position position);
00221
00225 const T& operator [] (Position position) const;
00226
00228
00231
00234 const TVector2& operator + () const;
00235
00238 TVector2 operator - () const;
00239
00242 TVector2 operator + (const TVector2& b) const;
00243
00246 TVector2 operator - (const TVector2& b) const;
00247
00253 TVector2& operator += (const TVector2& vector);
00254
00259 TVector2& operator -= (const TVector2& vector);
00260
00267 TVector2 operator * (const T& scalar) const;
00268
00274 TVector2& operator *= (const T& scalar);
00275
00282 TVector2 operator / (const T& lambda) const;
00283
00289 TVector2& operator /= (const T& lambda);
00290
00294 T operator * (const TVector2& vector) const;
00295
00297
00301
00304 T getDistance(const TVector2& vector) const;
00305
00308 T getSquareDistance(const TVector2& vector) const;
00309
00311
00315
00321 bool operator == (const TVector2& vector) const;
00322
00328 bool operator != (const TVector2& vector) const;
00329
00334 bool isZero() const;
00335
00338 bool isOrthogonalTo(TVector2& vector) const;
00339
00341
00342
00346
00353 void dump(std::ostream& s = std::cout, Size depth = 0) const;
00354
00359 bool isValid() const;
00360
00362
00363
00369
00372 T x;
00373
00376 T y;
00377
00379
00380 private:
00381
00382 };
00384
00385 template <typename T>
00386 TVector2<T>::TVector2()
00387
00388 : PersistentObject(),
00389 x(0),
00390 y(0)
00391 {
00392 }
00393
00394 template <typename T>
00395 TVector2<T>::TVector2(const T& value)
00396
00397 : PersistentObject(),
00398 x(value),
00399 y(value)
00400 {
00401 }
00402
00403 template <typename T>
00404 TVector2<T>::TVector2(const T& vx, const T& vy)
00405
00406 : PersistentObject(),
00407 x(vx),
00408 y(vy)
00409 {
00410 }
00411
00412 template <typename T>
00413 TVector2<T>::TVector2(const TVector2& vector)
00414
00415 : PersistentObject(),
00416 x(vector.x),
00417 y(vector.y)
00418 {
00419 }
00420
00421 template <typename T>
00422 TVector2<T>::~TVector2()
00423
00424 {
00425 }
00426
00427 template <typename T>
00428 BALL_INLINE
00429 TVector2<T>::TVector2(const T* ptr)
00430 {
00431 if (ptr == 0)
00432 {
00433 throw Exception::NullPointer(__FILE__, __LINE__);
00434 }
00435
00436 x = *ptr++;
00437 y = *ptr;
00438 }
00439
00440 template <typename T>
00441 void TVector2<T>::clear()
00442
00443 {
00444 x = y = (T)0;
00445 }
00446
00447 template <typename T>
00448 void TVector2<T>::persistentWrite(PersistenceManager& pm, const char* name) const
00449 {
00450 pm.writeObjectHeader(this, name);
00451 pm.writePrimitive(x, "x");
00452 pm.writePrimitive(y, "y");
00453 pm.writeObjectTrailer(name);
00454 }
00455
00456 template <typename T>
00457 void TVector2<T>::persistentRead(PersistenceManager& pm)
00458 {
00459 pm.readPrimitive(x, "x");
00460 pm.readPrimitive(y, "y");
00461 }
00462
00463 template <typename T>
00464 BALL_INLINE
00465 void TVector2<T>::set(const T& value)
00466
00467 {
00468 x = value;
00469 y = value;
00470 }
00471
00472 template <typename T>
00473 BALL_INLINE
00474 void TVector2<T>::set(const T& vx, const T& vy)
00475
00476 {
00477 x = vx;
00478 y = vy;
00479 }
00480
00481 template <typename T>
00482 BALL_INLINE
00483 void TVector2<T>::set(const TVector2<T>& vector)
00484
00485 {
00486 x = vector.x;
00487 y = vector.y;
00488 }
00489
00490 template <typename T>
00491 BALL_INLINE
00492 TVector2<T>& TVector2<T>::operator = (const TVector2<T>& vector)
00493
00494 {
00495 x = vector.x;
00496 y = vector.y;
00497
00498 return *this;
00499 }
00500
00501 template <typename T>
00502 BALL_INLINE
00503 TVector2<T>& TVector2<T>::operator = (const T* ptr)
00504 {
00505 if (ptr == 0)
00506 {
00507 throw Exception::NullPointer(__FILE__, __LINE__);
00508 }
00509 x = *ptr++;;
00510 y = *ptr;;
00511
00512 return *this;
00513 }
00514
00515 template <typename T>
00516 BALL_INLINE
00517 TVector2<T>& TVector2<T>::operator = (const T& value)
00518 {
00519 x = value;
00520 y = value;
00521
00522 return *this;
00523 }
00524
00525 template <typename T>
00526 BALL_INLINE
00527 T TVector2<T>::getLength() const
00528 {
00529 return (T)sqrt(x * x + y * y);
00530 }
00531
00532 template <typename T>
00533 BALL_INLINE
00534 T TVector2<T>::getSquareLength() const
00535 {
00536 return (T)(x * x + y * y);
00537 }
00538
00539 template <typename T>
00540 TVector2<T>& TVector2<T>::normalize()
00541 {
00542 T len = (T)sqrt(x * x + y * y);
00543
00544 if (Maths::isZero(len))
00545 {
00546 throw Exception::DivisionByZero(__FILE__, __LINE__);
00547 }
00548
00549 x /= len;
00550 y /= len;
00551
00552 return *this;
00553 }
00554
00555 template <typename T>
00556 TVector2<T>& TVector2<T>::negate()
00557 {
00558 x *= -1;
00559 y *= -1;
00560 return *this;
00561 }
00562
00563 template <typename T>
00564 BALL_INLINE
00565 const TVector2<T>& TVector2<T>::getZero()
00566 {
00567 static TVector2<T> null_vector(0, 0);
00568 return null_vector;
00569 }
00570
00571 template <typename T>
00572 BALL_INLINE
00573 const TVector2<T>& TVector2<T>::getUnit()
00574 {
00575 static TVector2<T> unit_vector(1, 1);
00576 return unit_vector;
00577 }
00578
00579 template <typename T>
00580 BALL_INLINE
00581 T& TVector2<T>::operator [] (Position position)
00582 {
00583 if (position > 1)
00584 {
00585 throw Exception::IndexOverflow(__FILE__, __LINE__);
00586 }
00587 switch (position)
00588 {
00589 case 0: return x;
00590 case 1:
00591 default:
00592 return y;
00593 }
00594 }
00595
00596 template <typename T>
00597 BALL_INLINE
00598 const T& TVector2<T>::operator [] (Position position) const
00599 {
00600 if (position > 1)
00601 {
00602 throw Exception::IndexOverflow(__FILE__, __LINE__);
00603 }
00604 switch (position)
00605 {
00606 case 0: return x;
00607 case 1:
00608 default:
00609 return y;
00610 }
00611 }
00612
00613 template <typename T>
00614 BALL_INLINE
00615 const TVector2<T>& TVector2<T>::operator + () const
00616 {
00617 return *this;
00618 }
00619
00620 template <typename T>
00621 BALL_INLINE
00622 TVector2<T> TVector2<T>::operator - () const
00623 {
00624 return TVector2<T>(-x, -y);
00625 }
00626
00627 template <typename T>
00628 BALL_INLINE
00629 TVector2<T> TVector2<T>::operator + (const TVector2<T>& b) const
00630 {
00631 return TVector2<T>(x + b.x, y + b.y);
00632 }
00633
00634 template <typename T>
00635 BALL_INLINE
00636 TVector2<T> TVector2<T>::operator - (const TVector2<T>& b) const
00637 {
00638 return TVector2<T>(x - b.x, y - b.y);
00639 }
00640
00641 template <typename T>
00642 BALL_INLINE
00643 TVector2<T>& TVector2<T>::operator += (const TVector2<T>& vector)
00644 {
00645 x += vector.x;
00646 y += vector.y;
00647
00648 return *this;
00649 }
00650
00651 template <typename T>
00652 BALL_INLINE
00653 TVector2<T>& TVector2<T>::operator -= (const TVector2<T>& vector)
00654 {
00655 x -= vector.x;
00656 y -= vector.y;
00657
00658 return *this;
00659 }
00660
00661 template <typename T>
00662 BALL_INLINE
00663 TVector2<T> TVector2<T>::operator * (const T& scalar) const
00664 {
00665 return TVector2<T>(x * scalar, y * scalar);
00666 }
00667
00668 template <typename T>
00669 BALL_INLINE
00670 TVector2<T>& TVector2<T>::operator *= (const T &scalar)
00671 {
00672 x *= scalar;
00673 y *= scalar;
00674
00675 return *this;
00676 }
00677
00678 template <typename T>
00679 TVector2<T> TVector2<T>::operator / (const T& lambda) const
00680 {
00681 if (lambda == (T)0)
00682 {
00683 throw Exception::DivisionByZero(__FILE__, __LINE__);
00684 }
00685 return TVector2<T>(x / lambda, y / lambda);
00686 }
00687
00688 template <typename T>
00689 TVector2<T>& TVector2<T>::operator /= (const T& lambda)
00690 {
00691 if (lambda == (T)0)
00692 {
00693 throw Exception::DivisionByZero(__FILE__, __LINE__);
00694 }
00695 x /= lambda;
00696 y /= lambda;
00697
00698 return *this;
00699 }
00700
00701 template <typename T>
00702 BALL_INLINE
00703 T TVector2<T>::operator * (const TVector2<T>& vector) const
00704 {
00705 return (x * vector.x + y * vector.y);
00706 }
00707
00708 template <typename T>
00709 BALL_INLINE
00710 T TVector2<T>::getDistance(const TVector2<T>& v) const
00711 {
00712 T dx = x - v.x;
00713 T dy = y - v.y;
00714
00715 return (T)sqrt(dx * dx + dy * dy);
00716 }
00717
00718 template <typename T>
00719 BALL_INLINE
00720 T TVector2<T>::getSquareDistance(const TVector2<T>& v) const
00721 {
00722 T dx = x - v.x;
00723 T dy = y - v.y;
00724
00725 return (dx * dx + dy * dy);
00726 }
00727
00728 template <typename T>
00729 BALL_INLINE
00730 bool TVector2<T>::operator == (const TVector2<T>& v) const
00731 {
00732 return (Maths::isEqual(x, v.x) && Maths::isEqual(y, v.y));
00733 }
00734
00735 template <typename T>
00736 BALL_INLINE
00737 bool TVector2<T>::operator != (const TVector2<T>& v) const
00738 {
00739 return (Maths::isNotEqual(x, v.x) || Maths::isNotEqual(y, v.y));
00740 }
00741
00742 template <typename T>
00743 BALL_INLINE
00744 bool TVector2<T>::isOrthogonalTo(TVector2<T>& v) const
00745 {
00746 return Maths::isZero((*this) * v);
00747 }
00748
00749 template <typename T>
00750 BALL_INLINE
00751 bool TVector2<T>::isValid() const
00752 {
00753 return true;
00754 }
00755
00756 template <typename T>
00757 BALL_INLINE
00758 bool TVector2<T>::isZero() const
00759 {
00760 return (Maths::isZero(x) && Maths::isZero(y));
00761 }
00762
00763 template <typename T>
00764 void TVector2<T>::dump(std::ostream& s, Size depth) const
00765 {
00766 BALL_DUMP_STREAM_PREFIX(s);
00767
00768 BALL_DUMP_HEADER(s, this, this);
00769
00770 BALL_DUMP_DEPTH(s, depth);
00771 s << " (x = " << x << ", y = " << y << ")" << std::endl;
00772
00773 BALL_DUMP_STREAM_SUFFIX(s);
00774 }
00775
00781 typedef TVector2<float> Vector2;
00782
00783 template <typename T>
00784 BALL_INLINE
00785 TVector2<T> operator * (const T& scalar, const TVector2<T>& vector)
00786 {
00787 return TVector2<T>(scalar * vector.x, scalar * vector.y);
00788 }
00789
00790 template <typename T>
00791 std::istream& operator >> (std::istream& s, TVector2<T>& v)
00792 {
00793 char c;
00794 s >> c >> v.x >> v.y >> c;
00795
00796 return s;
00797 }
00798
00799 template <typename T>
00800 std::ostream& operator << (std::ostream& s, const TVector2<T>& v)
00801 {
00802 s << "(" << v.x << ' ' << v.y << ')';
00803
00804 return s;
00805 }
00806
00807 }
00808
00809 #endif // BALL_MATHS_VECTOR2_H