BALL
1.4.1
|
00001 // -*- Mode: C++; tab-width: 2; -*- 00002 // vi: set ts=2: 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 /* Output stream. 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 : PersistentObject(), 00388 x(0), 00389 y(0) 00390 { 00391 } 00392 00393 template <typename T> 00394 TVector2<T>::TVector2(const T& value) 00395 : PersistentObject(), 00396 x(value), 00397 y(value) 00398 { 00399 } 00400 00401 template <typename T> 00402 TVector2<T>::TVector2(const T& vx, const T& vy) 00403 : PersistentObject(), 00404 x(vx), 00405 y(vy) 00406 { 00407 } 00408 00409 template <typename T> 00410 TVector2<T>::TVector2(const TVector2& vector) 00411 : PersistentObject(), 00412 x(vector.x), 00413 y(vector.y) 00414 { 00415 } 00416 00417 template <typename T> 00418 TVector2<T>::~TVector2() 00419 { 00420 } 00421 00422 template <typename T> 00423 BALL_INLINE 00424 TVector2<T>::TVector2(const T* ptr) 00425 { 00426 if (ptr == 0) 00427 { 00428 throw Exception::NullPointer(__FILE__, __LINE__); 00429 } 00430 00431 x = *ptr++; 00432 y = *ptr; 00433 } 00434 00435 template <typename T> 00436 void TVector2<T>::clear() 00437 { 00438 x = y = (T)0; 00439 } 00440 00441 template <typename T> 00442 void TVector2<T>::persistentWrite(PersistenceManager& pm, const char* name) const 00443 { 00444 pm.writeObjectHeader(this, name); 00445 pm.writePrimitive(x, "x"); 00446 pm.writePrimitive(y, "y"); 00447 pm.writeObjectTrailer(name); 00448 } 00449 00450 template <typename T> 00451 void TVector2<T>::persistentRead(PersistenceManager& pm) 00452 { 00453 pm.readPrimitive(x, "x"); 00454 pm.readPrimitive(y, "y"); 00455 } 00456 00457 template <typename T> 00458 BALL_INLINE 00459 void TVector2<T>::set(const T& value) 00460 { 00461 x = value; 00462 y = value; 00463 } 00464 00465 template <typename T> 00466 BALL_INLINE 00467 void TVector2<T>::set(const T& vx, const T& vy) 00468 { 00469 x = vx; 00470 y = vy; 00471 } 00472 00473 template <typename T> 00474 BALL_INLINE 00475 void TVector2<T>::set(const TVector2<T>& vector) 00476 { 00477 x = vector.x; 00478 y = vector.y; 00479 } 00480 00481 template <typename T> 00482 BALL_INLINE 00483 TVector2<T>& TVector2<T>::operator = (const TVector2<T>& vector) 00484 { 00485 x = vector.x; 00486 y = vector.y; 00487 00488 return *this; 00489 } 00490 00491 template <typename T> 00492 BALL_INLINE 00493 TVector2<T>& TVector2<T>::operator = (const T* ptr) 00494 { 00495 if (ptr == 0) 00496 { 00497 throw Exception::NullPointer(__FILE__, __LINE__); 00498 } 00499 x = *ptr++;; 00500 y = *ptr;; 00501 00502 return *this; 00503 } 00504 00505 template <typename T> 00506 BALL_INLINE 00507 TVector2<T>& TVector2<T>::operator = (const T& value) 00508 { 00509 x = value; 00510 y = value; 00511 00512 return *this; 00513 } 00514 00515 template <typename T> 00516 BALL_INLINE 00517 T TVector2<T>::getLength() const 00518 { 00519 return (T)sqrt(x * x + y * y); 00520 } 00521 00522 template <typename T> 00523 BALL_INLINE 00524 T TVector2<T>::getSquareLength() const 00525 { 00526 return (T)(x * x + y * y); 00527 } 00528 00529 template <typename T> 00530 TVector2<T>& TVector2<T>::normalize() 00531 { 00532 T len = (T)sqrt(x * x + y * y); 00533 00534 if (Maths::isZero(len)) 00535 { 00536 throw Exception::DivisionByZero(__FILE__, __LINE__); 00537 } 00538 00539 x /= len; 00540 y /= len; 00541 00542 return *this; 00543 } 00544 00545 template <typename T> 00546 TVector2<T>& TVector2<T>::negate() 00547 { 00548 x *= -1; 00549 y *= -1; 00550 return *this; 00551 } 00552 00553 template <typename T> 00554 BALL_INLINE 00555 const TVector2<T>& TVector2<T>::getZero() 00556 { 00557 static TVector2<T> null_vector(0, 0); 00558 return null_vector; 00559 } 00560 00561 template <typename T> 00562 BALL_INLINE 00563 const TVector2<T>& TVector2<T>::getUnit() 00564 { 00565 static TVector2<T> unit_vector(1, 1); 00566 return unit_vector; 00567 } 00568 00569 template <typename T> 00570 BALL_INLINE 00571 T& TVector2<T>::operator [] (Position position) 00572 { 00573 if (position > 1) 00574 { 00575 throw Exception::IndexOverflow(__FILE__, __LINE__); 00576 } 00577 switch (position) 00578 { 00579 case 0: return x; 00580 case 1: 00581 default: 00582 return y; 00583 } 00584 } 00585 00586 template <typename T> 00587 BALL_INLINE 00588 const T& TVector2<T>::operator [] (Position position) const 00589 { 00590 if (position > 1) 00591 { 00592 throw Exception::IndexOverflow(__FILE__, __LINE__); 00593 } 00594 switch (position) 00595 { 00596 case 0: return x; 00597 case 1: 00598 default: 00599 return y; 00600 } 00601 } 00602 00603 template <typename T> 00604 BALL_INLINE 00605 const TVector2<T>& TVector2<T>::operator + () const 00606 { 00607 return *this; 00608 } 00609 00610 template <typename T> 00611 BALL_INLINE 00612 TVector2<T> TVector2<T>::operator - () const 00613 { 00614 return TVector2<T>(-x, -y); 00615 } 00616 00617 template <typename T> 00618 BALL_INLINE 00619 TVector2<T> TVector2<T>::operator + (const TVector2<T>& b) const 00620 { 00621 return TVector2<T>(x + b.x, y + b.y); 00622 } 00623 00624 template <typename T> 00625 BALL_INLINE 00626 TVector2<T> TVector2<T>::operator - (const TVector2<T>& b) const 00627 { 00628 return TVector2<T>(x - b.x, y - b.y); 00629 } 00630 00631 template <typename T> 00632 BALL_INLINE 00633 TVector2<T>& TVector2<T>::operator += (const TVector2<T>& vector) 00634 { 00635 x += vector.x; 00636 y += vector.y; 00637 00638 return *this; 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 T& scalar) const 00654 { 00655 return TVector2<T>(x * scalar, y * scalar); 00656 } 00657 00658 template <typename T> 00659 BALL_INLINE 00660 TVector2<T>& TVector2<T>::operator *= (const T &scalar) 00661 { 00662 x *= scalar; 00663 y *= scalar; 00664 00665 return *this; 00666 } 00667 00668 template <typename T> 00669 TVector2<T> TVector2<T>::operator / (const T& lambda) const 00670 { 00671 if (lambda == (T)0) 00672 { 00673 throw Exception::DivisionByZero(__FILE__, __LINE__); 00674 } 00675 return TVector2<T>(x / lambda, y / lambda); 00676 } 00677 00678 template <typename T> 00679 TVector2<T>& TVector2<T>::operator /= (const T& lambda) 00680 { 00681 if (lambda == (T)0) 00682 { 00683 throw Exception::DivisionByZero(__FILE__, __LINE__); 00684 } 00685 x /= lambda; 00686 y /= lambda; 00687 00688 return *this; 00689 } 00690 00691 template <typename T> 00692 BALL_INLINE 00693 T TVector2<T>::operator * (const TVector2<T>& vector) const 00694 { 00695 return (x * vector.x + y * vector.y); 00696 } 00697 00698 template <typename T> 00699 BALL_INLINE 00700 T TVector2<T>::getDistance(const TVector2<T>& v) const 00701 { 00702 T dx = x - v.x; 00703 T dy = y - v.y; 00704 00705 return (T)sqrt(dx * dx + dy * dy); 00706 } 00707 00708 template <typename T> 00709 BALL_INLINE 00710 T TVector2<T>::getSquareDistance(const TVector2<T>& v) const 00711 { 00712 T dx = x - v.x; 00713 T dy = y - v.y; 00714 00715 return (dx * dx + dy * dy); 00716 } 00717 00718 template <typename T> 00719 BALL_INLINE 00720 bool TVector2<T>::operator == (const TVector2<T>& v) const 00721 { 00722 return (Maths::isEqual(x, v.x) && Maths::isEqual(y, v.y)); 00723 } 00724 00725 template <typename T> 00726 BALL_INLINE 00727 bool TVector2<T>::operator != (const TVector2<T>& v) const 00728 { 00729 return (Maths::isNotEqual(x, v.x) || Maths::isNotEqual(y, v.y)); 00730 } 00731 00732 template <typename T> 00733 BALL_INLINE 00734 bool TVector2<T>::isOrthogonalTo(TVector2<T>& v) const 00735 { 00736 return Maths::isZero((*this) * v); 00737 } 00738 00739 template <typename T> 00740 BALL_INLINE 00741 bool TVector2<T>::isValid() const 00742 { 00743 return true; 00744 } 00745 00746 template <typename T> 00747 BALL_INLINE 00748 bool TVector2<T>::isZero() const 00749 { 00750 return (Maths::isZero(x) && Maths::isZero(y)); 00751 } 00752 00753 template <typename T> 00754 void TVector2<T>::dump(std::ostream& s, Size depth) const 00755 { 00756 BALL_DUMP_STREAM_PREFIX(s); 00757 00758 BALL_DUMP_HEADER(s, this, this); 00759 00760 BALL_DUMP_DEPTH(s, depth); 00761 s << " (x = " << x << ", y = " << y << ")" << std::endl; 00762 00763 BALL_DUMP_STREAM_SUFFIX(s); 00764 } 00765 00771 typedef TVector2<float> Vector2; 00772 00773 template <typename T> 00774 BALL_INLINE 00775 TVector2<T> operator * (const T& scalar, const TVector2<T>& vector) 00776 { 00777 return TVector2<T>(scalar * vector.x, scalar * vector.y); 00778 } 00779 00780 template <typename T> 00781 std::istream& operator >> (std::istream& s, TVector2<T>& v) 00782 { 00783 char c; 00784 s >> c >> v.x >> v.y >> c; 00785 00786 return s; 00787 } 00788 00789 template <typename T> 00790 std::ostream& operator << (std::ostream& s, const TVector2<T>& v) 00791 { 00792 s << "(" << v.x << ' ' << v.y << ')'; 00793 00794 return s; 00795 } 00796 00797 }// namespace BALL 00798 00799 #endif // BALL_MATHS_VECTOR2_H