vector_2d.h

説明を見る。
00001 // -*-c++-*-
00002 
00008 /*
00009  *Copyright:
00010 
00011  Copyright (C) Hidehisa AKIYAMA, Hiroki Shimora
00012 
00013  This code is free software; you can redistribute it and/or
00014  modify it under the terms of the GNU Lesser General Public
00015  License as published by the Free Software Foundation; either
00016  version 2.1 of the License, or (at your option) any later version.
00017 
00018  This library is distributed in the hope that it will be useful,
00019  but WITHOUT ANY WARRANTY; without even the implied warranty of
00020  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00021  Lesser General Public License for more details.
00022 
00023  You should have received a copy of the GNU Lesser General Public
00024  License along with this library; if not, write to the Free Software
00025  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00026 
00027  *EndCopyright:
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     // : public boost::addable< Vector2D >
00049     // , public boost::subtractable< Vector2D >
00050     // , public multipliable2< Vector2D, double >
00051     // , public dividable2< Vector2D, double >
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     //       \brief type conversion operator. alias of valid().
00094     //       \return true if value is validate.
00095     //      */
00096     //     operator bool() const
00097     //       {
00098     //           return valid();
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           //return std::hypot( x, y );
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           //return ( Vector2D( *this ) -= p ).r2();
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           //return std::hypot( this->x - p.x,
00320           //                   this->y - p.y );
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           // ==  |this| * |v| * (*this - v).th().cos()
00441       }
00442 
00448     double outerProduct( const Vector2D & v ) const
00449       {
00450           /*---------------------*
00451            * assume virtual 3D environment.
00452            * calculate Z-coordinate of outer product in right hand orientation.
00453            * For the time being, Input Vector's Z-coordinate is set to ZERO.
00454            *---------------------*/
00455           // Normal 3D outer product
00456           //   xn = this->y * v.z - this->z * v.y;
00457           //   yn = this->z * v.x - this->x * v.z;
00458           // # zn = this->x * v.y - this->y * v.x;
00459           return this->x * v.y - this->y * v.x;
00460           // == |this| * |v| * (*this - v).th().sin()
00461       }
00462 
00464     // static utility
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     // stream utility
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     // functors for comparison
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     // functor for region
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 } // end of namespace
00641 
00642 
00644 // comparison operators
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 // arithmetic operators
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

librcscに対してThu May 1 15:41:20 2008に生成されました。  doxygen 1.5.0