00001
00002
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00031
00032 #ifndef RCSC_GEOM_VECTOR2D_H
00033 #define RCSC_GEOM_VECTOR2D_H
00034
00035 #include <rcsc/geom/angle_deg.h>
00036
00037 #include <functional>
00038 #include <iostream>
00039 #include <cmath>
00040
00041 namespace rcsc {
00042
00047 class Vector2D {
00048
00049
00050
00051
00052
00053 public:
00054
00056 static const double ERROR_VALUE;
00057
00059 static const Vector2D INVALIDATED;
00060
00061 double x;
00062 double y;
00063
00067 Vector2D()
00068 : x( 0.0 )
00069 , y( 0.0 )
00070 { }
00071
00077 Vector2D( const double & xx,
00078 const double & yy )
00079 : x( xx )
00080 , y( yy )
00081 { }
00082
00087 bool valid() const
00088 {
00089 return ( ( x != ERROR_VALUE ) && ( y != ERROR_VALUE ) );
00090 }
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00107 const
00108 Vector2D & assign( const double & xx,
00109 const double & yy )
00110 {
00111 x = xx;
00112 y = yy;
00113 return *this;
00114 }
00115
00122 const
00123 Vector2D & setPolar( const double & radius,
00124 const AngleDeg & dir )
00125 {
00126 x = radius * dir.cos();
00127 y = radius * dir.sin();
00128 return *this;
00129 }
00130
00131 const
00132 Vector2D & invalidate()
00133 {
00134 x = ERROR_VALUE;
00135 y = ERROR_VALUE;
00136 return *this;
00137 }
00138
00143 double r2() const
00144 {
00145 return x * x + y * y;
00146 }
00147
00152 double r() const
00153 {
00154
00155 return std::sqrt( r2() );
00156 }
00157
00162 double length() const
00163 {
00164 return r();
00165 }
00166
00171 AngleDeg th() const
00172 {
00173 return AngleDeg( AngleDeg::atan2_deg( y, x ) );
00174 }
00175
00180 AngleDeg dir() const
00181 {
00182 return th();
00183 }
00184
00189 Vector2D abs() const
00190 {
00191 return Vector2D( std::fabs( x ), std::fabs( y ) );
00192 }
00193
00198 double absX() const
00199 {
00200 return std::fabs( x );
00201 }
00202
00207 double absY() const
00208 {
00209 return std::fabs( y );
00210 }
00211
00218 const
00219 Vector2D & add( const double & xx,
00220 const double & yy )
00221 {
00222 x += xx;
00223 y += yy;
00224 return *this;
00225 }
00226
00231 const Vector2D & operator+() const
00232 {
00233 return *this;
00234 }
00235
00240 Vector2D operator-() const
00241 {
00242 return Vector2D( -x, -y );
00243 }
00244
00250 const
00251 Vector2D & operator+=( const Vector2D & v )
00252 {
00253 x += v.x;
00254 y += v.y;
00255 return *this;
00256 }
00257
00263 const
00264 Vector2D & operator-=( const Vector2D & v )
00265 {
00266 x -= v.x;
00267 y -= v.y;
00268 return *this;
00269 }
00270
00276 const
00277 Vector2D & operator*=( const double & scalar )
00278 {
00279 x *= scalar;
00280 y *= scalar;
00281 return *this;
00282 }
00283
00289 const
00290 Vector2D & operator/=( const double & scalar )
00291 {
00292 if ( scalar != 0 )
00293 {
00294 x /= scalar;
00295 y /= scalar;
00296 }
00297 return *this;
00298 }
00299
00305 double dist2( const Vector2D & p ) const
00306 {
00307
00308 return ( std::pow( this->x - p.x, 2.0 )
00309 + std::pow( this->y - p.y, 2.0 ) );
00310 }
00311
00317 double dist( const Vector2D & p ) const
00318 {
00319
00320
00321 return std::sqrt( dist2( p ) );
00322 }
00323
00329 const
00330 Vector2D & setLength( const double & len )
00331 {
00332 double mag = this->r();
00333 if ( mag == 0 )
00334 {
00335 return *this;
00336 }
00337 return ( (*this) *= ( len / mag ) );
00338 }
00339
00345 Vector2D setLengthVector( const double & len ) const
00346 {
00347 return Vector2D( *this ).setLength( len );
00348 }
00349
00354 const
00355 Vector2D & normalize()
00356 {
00357 return setLength( 1.0 );
00358 }
00359
00365 Vector2D norm() const
00366 {
00367 return Vector2D( *this ).normalize();
00368 }
00369
00375 const
00376 Vector2D & rotate( const double & deg )
00377 {
00378 double radius = this->r();
00379 double rotated_angle = this->th().degree();
00380 rotated_angle += deg;
00381 rotated_angle *= AngleDeg::DEG2RAD;
00382 this->x = radius * std::cos( rotated_angle );
00383 this->y = radius * std::sin( rotated_angle );
00384 return *this;
00385 }
00386
00392 const
00393 Vector2D & rotate( const AngleDeg & angle )
00394 {
00395 return rotate( angle.degree() );
00396 }
00397
00403 Vector2D rotatedVector( const double & deg ) const
00404 {
00405 return Vector2D( *this ).rotate( deg );
00406 }
00407
00413 Vector2D rotatedVector( const AngleDeg & angle ) const
00414 {
00415 return Vector2D( *this ).rotate( angle.degree() );
00416 }
00417
00423 const
00424 Vector2D & setDir( const AngleDeg & dir )
00425 {
00426 double radius = this->r();
00427 x = radius * dir.cos();
00428 y = radius * dir.sin();
00429 return *this;
00430 }
00431
00437 double innerProduct( const Vector2D & v ) const
00438 {
00439 return this->x * v.x + this->y * v.y;
00440
00441 }
00442
00448 double outerProduct( const Vector2D & v ) const
00449 {
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459 return this->x * v.y - this->y * v.x;
00460
00461 }
00462
00464
00465
00472 inline
00473 static
00474 Vector2D polar2vector( const double & mag,
00475 const AngleDeg & theta )
00476 {
00477 return Vector2D( mag * theta.cos(), mag * theta.sin() );
00478 }
00479
00486 inline
00487 static
00488 Vector2D from_polar( const double & mag,
00489 const AngleDeg & theta )
00490 {
00491 return Vector2D( mag * theta.cos(), mag * theta.sin() );
00492 }
00493
00500 inline
00501 static
00502 double inner_product( const Vector2D & v1,
00503 const Vector2D & v2 )
00504 {
00505 return v1.innerProduct( v2 );
00506 }
00507
00514 inline
00515 static
00516 double outer_product( const Vector2D & v1,
00517 const Vector2D & v2 )
00518 {
00519 return v1.outerProduct( v2 );
00520 }
00521
00523
00524
00530 std::ostream & print( std::ostream & os ) const
00531 {
00532 os << "(" << x << ", " << y << ")";
00533 return os;
00534 }
00535
00542 std::ostream & printRound( std::ostream & os,
00543 const double & prec = 0.1 ) const
00544 {
00545 os << "(" << rint( x / prec ) * prec
00546 << ", " << rint( y / prec ) * prec << ")";
00547 return os;
00548 }
00549
00551
00552
00557 class XCmp
00558 : public std::binary_function< Vector2D, Vector2D, bool > {
00559 public:
00561 result_type operator()( const first_argument_type & lhs,
00562 const second_argument_type & rhs ) const
00563 {
00564 return lhs.x < rhs.x;
00565 }
00566 };
00567
00572 class YCmp
00573 : public std::binary_function< Vector2D, Vector2D, bool > {
00574 public:
00576 result_type operator()( const first_argument_type & lhs,
00577 const second_argument_type & rhs ) const
00578 {
00579 return lhs.y < rhs.y;
00580 }
00581 };
00582
00587 class AbsXCmp
00588 : public std::binary_function< Vector2D, Vector2D, bool > {
00589 public:
00591 result_type operator()( const first_argument_type & lhs,
00592 const second_argument_type & rhs ) const
00593 {
00594 return lhs.absX() < rhs.absX();
00595 }
00596 };
00597
00602 class AbsYCmp
00603 : public std::binary_function< Vector2D, Vector2D, bool > {
00604 public:
00606 result_type operator()( const first_argument_type & lhs,
00607 const second_argument_type & rhs ) const
00608 {
00609 return lhs.absY() < rhs.absY();
00610 }
00611 };
00612
00613
00615
00616
00621 template < typename REGION >
00622 class IsWithin
00623 : public std::unary_function< Vector2D, bool > {
00624 private:
00625 const REGION M_region;
00626 public:
00628 explicit
00629 IsWithin( const REGION & region )
00630 : M_region( region )
00631 { }
00633 result_type operator()( const argument_type & position ) const
00634 {
00635 return M_region.contains( position );
00636 }
00637 };
00638 };
00639
00640 }
00641
00642
00644
00651 inline
00652 bool
00653 operator==( const rcsc::Vector2D & lhs, const rcsc::Vector2D & rhs )
00654 {
00655 return lhs.x == rhs.x && lhs.y == rhs.y;
00656 }
00657
00664 inline
00665 bool
00666 operator!=( const rcsc::Vector2D & lhs, const rcsc::Vector2D & rhs )
00667 {
00668 return !operator==(lhs, rhs);
00669 }
00670
00671
00673
00674
00681 inline
00682 const
00683 rcsc::Vector2D
00684 operator+( const rcsc::Vector2D & lhs,
00685 const rcsc::Vector2D & rhs )
00686 {
00687 return rcsc::Vector2D( lhs ) += rhs;
00688 }
00689
00696 inline
00697 const
00698 rcsc::Vector2D
00699 operator-( const rcsc::Vector2D & lhs,
00700 const rcsc::Vector2D & rhs )
00701 {
00702 return rcsc::Vector2D( lhs ) -= rhs;
00703 }
00704
00711 inline
00712 const
00713 rcsc::Vector2D
00714 operator*( const rcsc::Vector2D & lhs,
00715 const double & rhs )
00716 {
00717 return rcsc::Vector2D( lhs ) *= rhs;
00718 }
00719
00726 inline
00727 const
00728 rcsc::Vector2D
00729 operator/( const rcsc::Vector2D & lhs,
00730 const double & rhs )
00731 {
00732 return rcsc::Vector2D( lhs ) /= rhs;
00733 }
00734
00738 template < typename T >
00739 bool
00740 operator<( const rcsc::Vector2D & lhs,
00741 const T & rhs );
00742
00746 template < typename T >
00747 bool
00748 operator<=( const rcsc::Vector2D & lhs,
00749 const T & rhs );
00750
00754 template < typename T >
00755 bool
00756 operator>( const rcsc::Vector2D & lhs,
00757 const T & rhs );
00758
00762 template < typename T >
00763 bool
00764 operator>=( const rcsc::Vector2D & lhs,
00765 const T & rhs );
00766
00770 template < typename T >
00771 bool
00772 operator<( const T & lhs,
00773 const rcsc::Vector2D & rhs );
00774
00775
00779 template < typename T >
00780 bool
00781 operator<=(const T & lhs,
00782 const rcsc::Vector2D & rhs );
00783
00784
00788 template < typename T >
00789 bool
00790 operator>( const T & lhs,
00791 const rcsc::Vector2D & rhs );
00792
00796 template < typename T >
00797 bool
00798 operator>=( const T & lhs,
00799 const rcsc::Vector2D & rhs );
00800
00804 template < typename T >
00805 bool
00806 operator==( const T & lhs,
00807 const rcsc::Vector2D & rhs );
00808
00812 template < typename T >
00813 bool
00814 operator!=( const T & lhs,
00815 const rcsc::Vector2D & rhs );
00816
00817
00818
00820
00827 inline
00828 std::ostream &
00829 operator<<( std::ostream & os,
00830 const rcsc::Vector2D & v )
00831 {
00832 return v.print( os );
00833 }
00834
00835
00836 #endif