math/VectorN.cpp

Go to the documentation of this file.
00001 #include <iostream>
00002 #include "../additional/streams/mystreams.h"
00003 #include <assert.h>
00004 #include <math.h>
00005 //## end module%36FDB2BC02C6.includes
00006 
00007 // VectorN
00008 #include "VectorN.h"
00009 //## begin module%36FDB2BC02C6.additionalDeclarations preserve=yes
00010 //## end module%36FDB2BC02C6.additionalDeclarations
00011 
00012 
00013 // Class VectorN 
00014 
00015 VectorN::VectorN ()
00016 {
00017 }
00018 
00019 VectorN::VectorN (const VectorN& right)
00020 {
00021         elements.erase( elements.begin(), elements.end() );
00022     int size = right.elements.size();
00023     elements.reserve( size );
00024         for( int i = 0; i < size; ++i )         //IAN IMPROVE: this for loop looks expensive
00025         {
00026                 elements.push_back( right.elements[ i ] );
00027         }
00028 }
00029 
00030 //=============================================================================
00031 // Constructor
00032 //
00033 // Description: construct a scalar (what a waste)
00034 //=============================================================================
00035 VectorN::VectorN( const double a )
00036 {
00037         SetLength( 1 );
00038         (*this)[ 0 ] = a;
00039 }
00040 
00041 
00042 //=============================================================================
00043 // Constructor
00044 //
00045 // Description: construct a pair
00046 //=============================================================================
00047 VectorN::VectorN( const double a, const double b )
00048 {
00049         SetLength( 2 );
00050         (*this)[ 0 ] = a;
00051         (*this)[ 1 ] = b;
00052 }
00053 
00054 //=============================================================================
00055 // Constructor
00056 //
00057 // Description: construct a triple
00058 //=============================================================================
00059 VectorN::VectorN( const double a, const double b, const double c )
00060 {
00061     SetLength( 3 );
00062     operator[]( 0 ) = a;
00063     operator[]( 1 ) = b;
00064     operator[]( 2 ) = c;
00065 }
00066 
00067 //=============================================================================
00068 // Constructor
00069 //
00070 // Description: construct a quad
00071 //=============================================================================
00072 VectorN::VectorN( const double a, const double b, const double c, const double d )
00073 {
00074         SetLength( 4 );
00075         (*this)[ 0 ] = a;
00076         (*this)[ 1 ] = b;
00077         (*this)[ 2 ] = c;
00078         (*this)[ 3 ] = d;
00079 }
00080 
00081 
00082 VectorN::~VectorN()
00083 {
00084         elements.clear() ;              //IMPROVE: is this absolutely needed?
00085 }
00086 
00087 
00088 
00089 //## Other Operations (implementation)
00090 void VectorN::SetLength (const int length)
00091 {
00092         if( elements.size() < length )
00093         {
00094                 //boost the size of the array up
00095                 elements.resize( length ) ;
00096         }
00097         else if( elements.size() > length )
00098         {
00099                 //reduce the size of the array
00100                 std::vector< double >::iterator it = elements.begin() ;
00101                 for( int i = 0 ; i < length ; i++ )
00102                 {
00103                         it++ ;
00104                 }
00105                 elements.erase( it, elements.end() ) ;
00106         }
00107 }
00108 
00109 double& VectorN::operator [] (const unsigned int index)
00110 {
00111   //## begin VectorN::operator[]%922595693.body preserve=yes
00112         int size = elements.size() ;
00113         assert( elements.size() > index ) ;
00114         return elements[ index ] ;
00115   //## end VectorN::operator[]%922595693.body
00116 }
00117 
00118 VectorN VectorN::operator + (const VectorN& right) const
00119 {
00120   //## begin VectorN::operator+%922595695.body preserve=yes
00121         VectorN returnMe = right ;
00122         for( int i = 0; i < elements.size(); i++ )
00123         {
00124                 returnMe[ i ] += elements[ i ] ;
00125         }
00126         return returnMe ;
00127   //## end VectorN::operator+%922595695.body
00128 }
00129 
00130 VectorN VectorN::operator - (const VectorN& right) const
00131 {
00132 #ifdef _DEBUG
00133     int length = Length();
00134     int rightLength = right.Length();
00135     IJG_Assert( length == rightLength );
00136 #endif
00137         VectorN returnMe = *this ;
00138         for( int i = 0; i < elements.size(); i++ )
00139         {
00140                 returnMe[ i ] -= right[ i ] ;
00141         }
00142         return returnMe ;
00143 }
00144 
00145 VectorN VectorN::operator * (const double right) const
00146 {
00147   //## begin VectorN::operator*%922595698.body preserve=yes
00148         VectorN returnMe = *this ;
00149         for( int i = 0; i < elements.size(); i++ )
00150         {
00151                 returnMe[ i ] *= right ;
00152         }
00153         return returnMe ;
00154   //## end VectorN::operator*%922595698.body
00155 }
00156 
00157 VectorN& VectorN::operator *= (const double right)
00158 {
00159         int i;
00160         int size = this->elements.size();
00161         for( i = 0; i < size; i++ )
00162         {
00163                 elements[ i ] *= right;
00164         }
00165         return *this;
00166 }
00167 
00168 VectorN& VectorN::operator += (const VectorN& right)
00169 {
00170         for( int i = 0; i < elements.size(); ++i )
00171         {
00172                 elements[ i ] += right[ i ] ;
00173         }
00174         return *this ;
00175 }
00176 
00177 VectorN& VectorN::operator -= (const VectorN& right)
00178 {
00179         for( int i = 0; i < elements.size(); ++i )
00180         {
00181                 elements[ i ] -= right[ i ] ;
00182         }
00183         return *this ;
00184 }
00185 
00186 VectorN& VectorN::operator = (const VectorN& right)
00187 {
00188   //## begin VectorN::operator=%923255753.body preserve=yes
00189         std::vector< double>::iterator b = elements.begin() ;
00190         std::vector< double>::iterator e = elements.end() ;
00191 
00192 
00193         if( this == &right )
00194         {
00195                 return *this ;
00196         }
00197         elements.clear() ;
00198     unsigned int length = right.Length();
00199         for( int i = 0; i < length; i++ )
00200         {
00201                 elements.push_back( right.elements[ i ] ) ;
00202         }
00203         return *this ;
00204   //## end VectorN::operator=%923255753.body
00205 }
00206 
00207 //=============================================================================
00208 // Append
00209 //
00210 // Description: appends one vector to another one
00211 //=============================================================================
00212 void VectorN::Append( const VectorN& right )
00213 {
00214         elements.insert( elements.end(), right.elements.begin(), right.elements.end() );
00215 }
00216 
00217 //=============================================================================
00218 // Compare
00219 //
00220 // Description: Compares if two vectors are equal to within a given Tolerance.
00221 //=============================================================================
00222 bool VectorN::Compare( const VectorN& right, const double& tol) const
00223 {
00224         //test that the lengths are the same
00225         if( Length() != right.Length() )
00226         {
00227                 return false ;
00228         }
00229 
00230         //test that the elements are the same
00231         for( int i = 0; i < elements.size(); i++ )
00232         {
00233                 double diff = elements[ i ] - right[ i ];
00234                 if( (diff > tol) || (diff < (-tol)) )
00235                 {
00236                         return false ;
00237                 }
00238         }
00239 
00240         // if still in the function, then all elements are equal to within tol.
00241         return true ;
00242 }
00243 
00244 //=============================================================================
00245 // VectorN::Dot
00246 //
00247 // Description: Dot product of two n dimentional vectors
00248 //=============================================================================
00249 double VectorN::Dot( const VectorN& right ) const
00250 {
00251     double returnMe = 0;
00252     int i;
00253     int size = elements.size();
00254     for( i = 0; i < size; ++i )
00255     {
00256         returnMe += elements[ i ] * right.elements[ i ];
00257     }
00258     return returnMe;
00259 }
00260 
00261 //=============================================================================
00262 // VectorN::Length
00263 //
00264 // Description: returns the length of the vector
00265 //=============================================================================
00266 unsigned int VectorN::Length () const
00267 {
00268         return elements.size();
00269 }
00270 
00271 void VectorN::Output () const
00272 {
00273   //## begin VectorN::Output%923255764.body preserve=yes
00274         for( int i = 0; i < Length() - 1; i++ )
00275         {
00276                 std::cout << operator[]( i ) << "," ;
00277         }
00278         std::cout << operator[]( Length() - 1 ) ;       //IMPROVE: do we want this function?
00279   //## end VectorN::Output%923255764.body
00280 }
00281 
00282 bool VectorN::operator == (const VectorN& right) const
00283 {
00284   //## begin VectorN::operator==%930083381.body preserve=yes
00285 
00286         //test that the lengths are the same
00287         if( Length() != right.Length() )
00288         {
00289                 return false ;
00290         }
00291 
00292         //test that the elements are the same
00293         for( int i = 0; i < elements.size(); i++ )
00294         {
00295                 if( elements[ i ] != right[ i ] )
00296                 {
00297                         return false ;
00298                 }
00299         }
00300         return true ;
00301   //## end VectorN::operator==%930083381.body
00302 }
00303 
00304 bool VectorN::operator != (const VectorN& right) const
00305 {
00306   //## begin VectorN::operator!=%930083382.body preserve=yes
00307         return ! (*this == right ) ;
00308   //## end VectorN::operator!=%930083382.body
00309 }
00310 
00311 VectorN VectorN::operator / (const double right) const
00312 {
00313   //## begin VectorN::operator/%930364107.body preserve=yes
00314         VectorN returnMe = *this ;
00315         for( int i = 0; i < elements.size(); i++ )
00316         {
00317                 returnMe[ i ] /= right ;
00318         }
00319         return returnMe ;
00320 
00321   //## end VectorN::operator/%930364107.body
00322 }
00323 
00324 VectorN& VectorN::operator /= ( const double right)
00325 {
00326     for( int i = 0; i < elements.size(); ++i )
00327     {
00328         elements[ i ] /= right;
00329     }
00330     return *this;
00331 }
00332 
00333 double VectorN::MagSquared () const
00334 {
00335   //## begin VectorN::MagSquared%965514807.body preserve=yes
00336         int i;
00337         double runningCount = 0;
00338         for( i = 0; i < this->Length(); i++ )
00339         {
00340                 double element = this->elements[ i ];
00341                 runningCount += element * element;
00342         }
00343         return runningCount;
00344   //## end VectorN::MagSquared%965514807.body
00345 }
00346 
00347 double VectorN::Magnitude () const
00348 {
00349   //## begin VectorN::Magnitude%965675401.body preserve=yes
00350         return sqrt( this->MagSquared() );
00351   //## end VectorN::Magnitude%965675401.body
00352 }
00353 
00354 //=============================================================================
00355 // VectorN::Normalize
00356 //
00357 // Description: makes the length of the vector unity
00358 //=============================================================================
00359 void VectorN::Normalize()
00360 {
00361     double magnitude = Magnitude();
00362     operator/=( Magnitude() );
00363 }
00364 
00365 //=============================================================================
00366 // VectorN::clear
00367 //
00368 // Description: just like a std container
00369 //=============================================================================
00370 void VectorN::clear()
00371 {
00372     elements.erase( elements.begin(), elements.end() );
00373 }
00374 
00375 //=============================================================================
00376 // VectorN::push_back
00377 //
00378 // Description: just like a std container
00379 //=============================================================================
00380 void VectorN::push_back( const double newElement )
00381 {
00382     elements.push_back( newElement );
00383 }
00384 
00385 //=============================================================================
00386 // VectorN::reserve
00387 //
00388 // Description: just like a std container
00389 //=============================================================================
00390 void VectorN::reserve( const unsigned int size )
00391 {
00392     elements.reserve( size );
00393 }
00394 
00395 //=============================================================================
00396 // VectorN::resize
00397 //
00398 // Description: just like a std container
00399 //=============================================================================
00400 void VectorN::resize( const unsigned int size, const double fill )
00401 {
00402     elements.resize( size, fill );
00403 }
00404 
00405 VectorN operator*( const double f, const VectorN& v )
00406 {
00407     return v * f;
00408 }
00409 
00410 // Additional Declarations
00411   //## begin VectorN%36FDB2BC02C6.declarations preserve=yes
00412 //-----------------------------------------------------------------------------
00413 std::ostream & operator<<( std::ostream &os, const VectorN& v )
00414 //file format looks like this
00415 //[0.01,1203,2309]
00416 {
00417         os << "[" ;
00418         for( int i = 0 ; i < v.Length(); i++ )
00419         {
00420                 os << v[ i ] ;
00421                 if( i != v.Length() - 1 )
00422                 {
00423                         os << "," ;
00424                 }
00425         }
00426         os      << "]" ;
00427         return os ;
00428 }
00429 //-----------------------------------------------------------------------------
00430 std::istream & operator>>( std::istream &is, VectorN& v )
00431 {
00432         //check inputs
00433         assert( is.good() ) ;
00434 
00435         //set the length of v to 0
00436         v.SetLength( 0 ) ;
00437 
00438         eatwhite( is ) ;
00439 
00440         //read in numbers seperated by commas until we hit the ']'
00441         while( ( is.peek() != ']' ) && ( is.peek() != EOF ) )
00442         {
00443                 //remove the first character from the string
00444                 char delimitingCharacter = 0 ;
00445                 is >> delimitingCharacter ;
00446 
00447                 //read in the number from the string
00448                 double number ;
00449                 is >> number ;
00450 
00451                 //add the number to the vector
00452                 int currentLength = v.Length() ;
00453                 v.SetLength( currentLength + 1 ) ;
00454                 v[ currentLength ] = number ;
00455                 eatwhite( is ) ;
00456                 //read the next character from the file
00457         }
00458 
00459         //eat the last ']' 
00460         if( is.peek() == ']' )
00461         {
00462                 is.get() ;
00463         }
00464         else
00465         {
00466                 //IMPROVE: should throw an exception or something?
00467         }
00468         return is ;
00469 }
00470 //-----------------------------------------------------------------------------
00471 double  Average( const VectorN& v )
00472 {
00473     int size = v.Size();
00474     int i;
00475     double total = 0.0;
00476     for( i = 0; i < size; ++i )
00477     {
00478         total += v[ i ];
00479     }
00480     total /= size;
00481     return total;
00482 }
00483 //-----------------------------------------------------------------------------
00484 double DistanceSquared( const VectorN& c0, const VectorN& c1, const VectorN& p)
00485 {
00486     VectorN segmentDirection = c1 - c0;
00487     VectorN pointDirection = p - c0;
00488     double dot = segmentDirection.Dot( pointDirection );
00489     if( dot <= 0.0 )
00490     {
00491         //
00492         // Point is behind the origin
00493         //
00494         double returnMe = pointDirection.MagSquared();
00495         return returnMe;
00496     }
00497 
00498     double segmentLengthSqr = segmentDirection.MagSquared();
00499     if( dot >= segmentLengthSqr )
00500     {
00501         //
00502         // Point is behind the other target
00503         //
00504         pointDirection -= segmentDirection;
00505         double returnMe = pointDirection.MagSquared();
00506         return returnMe;
00507     }
00508     else
00509     {
00510         //
00511         // Point is closest to somewhere in the middle of the line
00512         //
00513         dot /= segmentLengthSqr;
00514         pointDirection -= segmentDirection * dot;
00515         double returnMe = pointDirection.MagSquared();
00516         return returnMe;
00517     }
00518 }
00519 
00520 VectorN ClosestPoint( const VectorN& c0, const VectorN& c1, const VectorN& p)
00521 {
00522     VectorN segmentDirection = c1 - c0;
00523     VectorN pointDirection = p - c0;
00524     double dot = segmentDirection.Dot( pointDirection );
00525     if( dot <= 0.0 )
00526     {
00527         //
00528         // Point is behind the origin
00529         //
00530         return c0;
00531     }
00532 
00533     double segmentLengthSqr = segmentDirection.MagSquared();
00534     if( dot >= segmentLengthSqr )
00535     {
00536         //
00537         // Point is behind the other target
00538         //
00539         return c1;
00540     }
00541     else
00542     {
00543         //
00544         // Point is closest to somewhere in the middle of the line
00545         //
00546         dot /= segmentLengthSqr;
00547         VectorN returnMe = c0 + segmentDirection * dot;
00548         return returnMe;
00549     }
00550 }
00551 //-----------------------------------------------------------------------------
00552 VectorN Ln( const VectorN& right )
00553 {
00554     VectorN returnMe = right;
00555     int size = returnMe.Size();
00556     int i;
00557     for( i = 0; i < size; ++i )
00558     {
00559         returnMe[ i ] = log( returnMe[ i ] );
00560     }
00561     return returnMe;
00562 }
00563 //-----------------------------------------------------------------------------

Generated on Sat Apr 1 21:30:39 2006 for Motion Planning Kernel by  doxygen 1.4.6-NO