dvm3_vector.h

00001 #ifndef dvm3_vector_h_INCLUDED
00002 #define dvm3_vector_h_INCLUDED
00003 
00004 // File:    dvm3_vector.h
00005 // Author:  Terry Gaetz
00006 
00007 /* --8<--8<--8<--8<--
00008  *
00009  * Copyright (C) 2006 Smithsonian Astrophysical Observatory
00010  *
00011  * This file is part of dvm3
00012  *
00013  * dvm3 is free software; you can redistribute it and/or
00014  * modify it under the terms of the GNU General Public License
00015  * as published by the Free Software Foundation; either version 2
00016  * of the License, or (at your option) any later version.
00017  *
00018  * dvm3.cvs 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
00021  * GNU General Public License for more details.
00022  *
00023  * You should have received a copy of the GNU General Public License
00024  * along with this program; if not, write to the 
00025  *       Free Software Foundation, Inc. 
00026  *       51 Franklin Street, Fifth Floor
00027  *       Boston, MA  02110-1301, USA
00028  *
00029  * -->8-->8-->8-->8-- */
00030 
00031 /****************************************************************************
00032  * Description: collection of methods for dvm3_Vector
00033  */
00034 
00035 #include <cfloat>                       // DBL_EPSILON
00036 #include <vm_math/vm_v3math.h>          // vm_V3Math<T_fp>
00037 #include <iosfwd>
00038 #include <cstdio>
00039 
00040 //########################################################################
00041 // dvm3_VPOD
00042 //########################################################################
00043 
00067 struct dvm3_VPOD
00068 {
00069   double x_[3];
00070 };
00073 //########################################################################
00074 // dvm3_Vector
00075 //########################################################################
00076 
00077 /* forward declaration required below */
00078 class dvm3_Matrix;
00079 
00106 class dvm3_Vector
00107 {
00108 private:
00109 
00110   dvm3_VPOD data_;
00111 
00112   friend class dvm3_Matrix;
00113   friend class dvm3_RotMat;
00114 
00115 public:
00116 
00117   // ---------------------------------------------------------------------
00125  ~dvm3_Vector();
00126 
00130   dvm3_Vector();
00131 
00139   dvm3_Vector( double x, double y, double z );
00140 
00146   dvm3_Vector( dvm3_Vector const& other );
00147     //
00148     //: copy constructor.
00149 
00158   void copy_from_cvec( double const* cv );
00159 
00168   void copy_to_cvec( double* v ) const;
00171   // ---------------------------------------------------------------------
00176 
00184   void init( double x, double y, double z );
00187   // ---------------------------------------------------------------------
00199   dvm3_Vector& operator=( dvm3_Vector const& rhs );
00200 
00208   dvm3_Vector& operator=( double rhs );
00209 
00217   dvm3_Vector& operator+=( dvm3_Vector const& rhs );
00218 
00226   dvm3_Vector& operator-=( dvm3_Vector const& rhs );
00227 
00235   dvm3_Vector& operator*=( dvm3_Vector const& rhs );
00236 
00244   dvm3_Vector& operator/=( dvm3_Vector const& rhs );
00245 
00253   dvm3_Vector& operator+=( double rhs );
00254 
00262   dvm3_Vector& operator-=( double rhs );
00263 
00271   dvm3_Vector& operator*=( double rhs );
00272 
00280   dvm3_Vector& operator/=( double rhs );
00283   // ---------------------------------------------------------------------
00291   dvm3_Vector& operator+();
00292 
00296   dvm3_Vector& operator-();
00299   // ---------------------------------------------------------------------
00311   double const& operator[](int i) const;
00312 
00320   double& operator[](int i);
00321 
00329   double  operator()(int i) const;
00330 
00338   double& operator()(int i);
00339     //
00340     //: read-write access to component [i].
00343   // ---------------------------------------------------------------------
00353   double unitize();
00354 
00360   int is_unit_vector( double const tol = 100.0 * DBL_EPSILON ) const;
00361 
00371   int is_orthogonal_to( dvm3_Vector const& other,
00372                         double const tol = 100.0 * DBL_EPSILON ) const;
00375   // ---------------------------------------------------------------------
00387   double dot( dvm3_Vector const& v ) const;
00388 
00397   void cross( dvm3_Vector const& v1, dvm3_Vector const& v2 );
00400   // ---------------------------------------------------------------------
00416   void lincomb( double c1, dvm3_Vector const& v1,
00417                 double c2, dvm3_Vector const& v2 );
00432   friend double unitize( dvm3_Vector& vu, dvm3_Vector const& vi );
00433 
00448   friend double dot( dvm3_Vector const& v1, dvm3_Vector const& v2 );
00449 
00458   friend void cross( dvm3_Vector& result, dvm3_Vector const& v1, 
00459                                           dvm3_Vector const& v2 );
00460     //
00461     //: result is vector (cross) product of v1 and v2.
00462 
00478   friend void lincomb(            dvm3_Vector&       result, 
00479                        double c1, dvm3_Vector const& v1,
00480                        double c2, dvm3_Vector const& v2 );
00481 
00496   friend dvm3_Vector operator+ (dvm3_Vector const& v1, 
00497                                 dvm3_Vector const& v2);
00498 
00507   friend dvm3_Vector operator- (dvm3_Vector const& v1,
00508                                 dvm3_Vector const& v2);
00509 
00518   friend dvm3_Vector operator* (dvm3_Vector const& v1,
00519                                 dvm3_Vector const& v2);
00520 
00521   friend dvm3_Vector operator/ (dvm3_Vector const& v1,
00522                                  dvm3_Vector const& v2);
00523     //
00524     //: component-wise division of v1 and v2.
00525 
00534   friend dvm3_Vector operator+ (double       r, dvm3_Vector const& v);
00535 
00544   friend dvm3_Vector operator- (double       r, dvm3_Vector const& v);
00545 
00554   friend dvm3_Vector operator* (double       r, dvm3_Vector const& v);
00555 
00564   friend dvm3_Vector operator/ (double       r, dvm3_Vector const& v);
00565     //
00566     //: set each component to r / component.
00567 
00576   friend dvm3_Vector operator+ (dvm3_Vector const& v, double       r);
00577 
00586   friend dvm3_Vector operator- (dvm3_Vector const& v, double       r);
00587 
00596   friend dvm3_Vector operator* (dvm3_Vector const& v, double       r);
00597 
00606   friend dvm3_Vector operator/ (dvm3_Vector const& v, double       r);
00609   // ---------------------------------------------------------------------
00621   std::ostream& print_on( std::ostream& os, char const pre[] = "", 
00622                                             char const post[] = "" ) const;
00623 
00629   friend std::ostream& operator<<( std::ostream& os, dvm3_Vector const& );
00630     //
00631     //: formatted output.
00632 
00641   void
00642   cprint_on( FILE* of, 
00643              char const prefix[] = "", char const postfix[] = "" );
00653   friend void 
00654   dyad_product(dvm3_Matrix&, const dvm3_Vector&, const dvm3_Vector&);
00655 
00659   friend void
00660   mvmult(dvm3_Vector&, const dvm3_Matrix&, const dvm3_Vector&);
00661 
00665   friend void
00666   mtvmult(dvm3_Vector&, const dvm3_Matrix&, const dvm3_Vector&);
00667 };
00668 
00669 //########################################################################
00670 //########################################################################
00671 //
00672 //    #    #    #  #          #    #    #  ######   ####
00673 //    #    ##   #  #          #    ##   #  #       #
00674 //    #    # #  #  #          #    # #  #  #####    ####
00675 //    #    #  # #  #          #    #  # #  #            #
00676 //    #    #   ##  #          #    #   ##  #       #    #
00677 //    #    #    #  ######     #    #    #  ######   ####
00678 //
00679 //########################################################################
00680 //########################################################################
00681 
00682 inline dvm3_Vector::
00683 ~dvm3_Vector()
00684 {}
00685 
00686 inline dvm3_Vector::
00687 dvm3_Vector()
00688 {}
00689 
00690 inline dvm3_Vector::
00691 dvm3_Vector( double x, double y, double z )
00692 {
00693   vm_V3Math<double>::set( data_.x_, x, y, z );
00694 }
00695 
00696 inline dvm3_Vector::
00697 dvm3_Vector( dvm3_Vector const& other )
00698   : data_( other.data_ )
00699 {}
00700 
00701 inline void dvm3_Vector::
00702 init( double x, double y, double z )
00703 { vm_V3Math<double>::set( data_.x_, x, y, z ); }
00704 
00705 inline dvm3_Vector& dvm3_Vector::
00706 operator=( dvm3_Vector const& rhs )
00707 { vm_V3Math<double>::copy( data_.x_, rhs.data_.x_ );  return *this; }
00708 
00709 inline dvm3_Vector& dvm3_Vector::
00710 operator=( double rhs )
00711 { vm_V3Math<double>::set( data_.x_, rhs );   return *this; }
00712 
00713 // This routine copies the source C-style vector to this DVector3
00714 // using memcpy.  It is assumed that the source C vector points at storage
00715 // containing at least 3 doubles
00716 
00717 inline void dvm3_Vector::
00718 copy_from_cvec( double const* vs )
00719 { vm_V3Math<double>::copy( data_.x_, vs ); }
00720 
00721 // This routine copies the source C-style vector to the destination DVector3
00722 // using memcpy.  It is assumed that the C vector points at storage
00723 // containing at least 3 doubles
00724 
00725 inline void dvm3_Vector::
00726 copy_to_cvec( double* vd ) const
00727 { vm_V3Math<double>::copy( vd, data_.x_ ); }
00728 
00729 #define _tpl_Op_EQ_(_OPNAM_,_OPEQ_) \
00730   inline dvm3_Vector& dvm3_Vector::operator _OPEQ_ ( dvm3_Vector const& v ) \
00731   { vm_V3Math<double>::_OPNAM_( data_.x_, v.data_.x_ );  return *this; } \
00732   inline dvm3_Vector& dvm3_Vector::operator _OPEQ_ ( double r ) \
00733   { vm_V3Math<double>::_OPNAM_( data_.x_, r );  return *this; }
00734   _tpl_Op_EQ_(add_eq,+=)
00735   _tpl_Op_EQ_(sub_eq,-=)
00736   _tpl_Op_EQ_(mul_eq,*=)
00737   _tpl_Op_EQ_(div_eq,/=)
00738 #undef _tpl_Op_EQ_
00739 
00740 inline dvm3_Vector& dvm3_Vector::operator+()
00741 { return *this; }
00742 
00743 inline dvm3_Vector& dvm3_Vector::operator-()
00744 { vm_V3Math<double>::negate(data_.x_);  return *this; }
00745 
00746 inline double const& dvm3_Vector::
00747 operator[](int i) const
00748 { return data_.x_[i]; }
00749 
00750 inline double& dvm3_Vector::
00751 operator[](int i)
00752 { return data_.x_[i]; }
00753 
00754 inline double dvm3_Vector::
00755 operator()(int i) const
00756 { return data_.x_[i]; }
00757 
00758 inline double& dvm3_Vector::
00759 operator()(int i)
00760 { return data_.x_[i]; }
00761 
00762 inline double dvm3_Vector::
00763 dot( dvm3_Vector const& v ) const
00764 { return vm_V3Math<double>::dot( data_.x_, v.data_.x_ ); }
00765 
00766 inline double
00767 dot( dvm3_Vector const& v1, dvm3_Vector const& v2 )
00768 { return vm_V3Math<double>::dot( v1.data_.x_, v2.data_.x_ ); }
00769 
00770 inline void dvm3_Vector::
00771 cross( dvm3_Vector const& v1, dvm3_Vector const& v2 )
00772 { vm_V3Math<double>::cross( data_.x_, v1.data_.x_, v2.data_.x_ ); }
00773 
00774 inline void
00775 cross( dvm3_Vector& result, dvm3_Vector const& v1,
00776                              dvm3_Vector const& v2 )
00777 { vm_V3Math<double>::cross( result.data_.x_, v1.data_.x_, v2.data_.x_ ); }
00778 
00779 inline double dvm3_Vector::
00780 unitize()
00781 { return vm_V3Math<double>::unitize( data_.x_ ); }
00782 
00783 inline double
00784 unitize( dvm3_Vector       &vu,    // normalized version of vi
00785          dvm3_Vector const &vi     // input vector
00786 )
00787 { return vm_V3Math<double>::unitize( vu.data_.x_, vi.data_.x_ ); }
00788 
00789 inline int dvm3_Vector::
00790 is_unit_vector( double const tol ) const
00791 { return vm_V3Math<double>::is_unit_vector( data_.x_, tol ); }
00792 
00793 inline int dvm3_Vector::
00794 is_orthogonal_to( dvm3_Vector const& other, double const tol ) const
00795 { return vm_V3Math<double>::are_orthogonal( data_.x_, other.data_.x_, tol ); }
00796 
00797 inline void dvm3_Vector::
00798 lincomb( double              c1,       // first scale factor
00799          dvm3_Vector const& v1,       // first vector
00800          double              c2,       // second scale factor
00801          dvm3_Vector const& v2        // second vector
00802        )
00803 { vm_V3Math<double>::lincomb( data_.x_, c1, v1.data_.x_, c2, v2.data_.x_ ); }
00804 
00805 inline void
00806 lincomb( dvm3_Vector& result, double c1, dvm3_Vector const& v1,
00807                                double c2, dvm3_Vector const& v2 )
00808 { 
00809   vm_V3Math<double>::lincomb( result.data_.x_, c1, 
00810                                v1.data_.x_, c2, v2.data_.x_ );
00811 }
00812 
00813 #define _tpl_Op_(_OP_) \
00814   inline dvm3_Vector operator _OP_ ( dvm3_Vector const& v1,  \
00815                                       dvm3_Vector const& v2 ) \
00816   { return dvm3_Vector( v1.data_.x_[0] _OP_ v2.data_.x_[0], \
00817                         v1.data_.x_[1] _OP_ v2.data_.x_[1], \
00818                         v1.data_.x_[2] _OP_ v2.data_.x_[2] ); } \
00819   inline dvm3_Vector operator _OP_ ( double r,  dvm3_Vector const& v2 ) \
00820   { return dvm3_Vector( r _OP_ v2.data_.x_[0], r _OP_ v2.data_.x_[1], \
00821                         r _OP_ v2.data_.x_[2] ); } \
00822   inline dvm3_Vector operator _OP_ ( dvm3_Vector const& v1, double r ) \
00823   { return dvm3_Vector( v1.data_.x_[0] _OP_ r, v1.data_.x_[1] _OP_ r, \
00824                         v1.data_.x_[2] _OP_ r ); }
00825   _tpl_Op_(+)
00826   _tpl_Op_(-)
00827   _tpl_Op_(*)
00828   _tpl_Op_(/)
00829 #undef _tpl_Op_
00830 
00831 inline std::ostream& dvm3_Vector::
00832 print_on( std::ostream& os, char const prefix[], char const postfix[] ) const
00833 { return vm_V3Math<double>::print_on( os, data_.x_, prefix, postfix ); }
00834 
00835 inline std::ostream&
00836 operator<<( std::ostream& os, const dvm3_Vector& v )
00837 {
00838   return v.print_on( os, "[", "]" );
00839 }
00840 
00841 inline void dvm3_Vector::
00842 cprint_on( FILE* of, char const prefix[], char const postfix[] )
00843 { vm_V3Math<double>::cprint_on( of, data_.x_, prefix, postfix ); }
00844 
00845 #endif

Generated on Tue Dec 2 15:44:47 2008 for dvm3 by  doxygen 1.5.6