MOAB: Mesh Oriented datABase  (version 5.4.1)
CartVect.hpp
Go to the documentation of this file.
00001 #ifndef MB_CART_VECT_HPP
00002 #define MB_CART_VECT_HPP
00003
00004 #include <cmath>
00005 #include <iosfwd>
00006 #include <cfloat>
00007
00008 namespace moab
00009 {
00010
00011 /**
00012  * \brief Cartesian Vector
00013  */
00014 class CartVect
00015 {
00016   private:
00017     double d[3];
00018
00019   public:
00020     inline CartVect() {}
00021     /**Initialze all three values to same scalar (typically zero)*/
00022     explicit inline CartVect( double v )
00023     {
00024         d[0] = d[1] = d[2] = v;
00025     }
00026     inline CartVect( double i, double j, double k )
00027     {
00028         d[0] = i;
00029         d[1] = j;
00030         d[2] = k;
00031     }
00032     /**Initialze from array*/
00033     explicit inline CartVect( const double a[3] )
00034     {
00035         d[0] = a[0];
00036         d[1] = a[1];
00037         d[2] = a[2];
00038     }
00039     inline CartVect& operator=( const double v[3] )
00040     {
00041         d[0] = v[0];
00042         d[1] = v[1];
00043         d[2] = v[2];
00044         return *this;
00045     }
00046
00047     inline double& operator[]( unsigned i )
00048     {
00049         return d[i];
00050     }
00051     inline double operator[]( unsigned i ) const
00052     {
00053         return d[i];
00054     }
00055
00056     inline CartVect& operator+=( const CartVect& v )
00057     {
00058         d[0] += v.d[0];
00059         d[1] += v.d[1];
00060         d[2] += v.d[2];
00061         return *this;
00062     }
00063     inline CartVect& operator-=( const CartVect& v )
00064     {
00065         d[0] -= v.d[0];
00066         d[1] -= v.d[1];
00067         d[2] -= v.d[2];
00068         return *this;
00069     }
00070     /** Assign cross product to this */
00071     inline CartVect& operator*=( const CartVect& v );
00072
00073     inline CartVect& operator+=( double s )
00074     {
00075         d[0] += s;
00076         d[1] += s;
00077         d[2] += s;
00078         return *this;
00079     }
00080     inline CartVect& operator-=( double s )
00081     {
00082         d[0] -= s;
00083         d[1] -= s;
00084         d[2] -= s;
00085         return *this;
00086     }
00087     inline CartVect& operator*=( double s )
00088     {
00089         d[0] *= s;
00090         d[1] *= s;
00091         d[2] *= s;
00092         return *this;
00093     }
00094     inline CartVect& operator/=( double s )
00095     {
00096         d[0] /= s;
00097         d[1] /= s;
00098         d[2] /= s;
00099         return *this;
00100     }
00101     inline bool operator==( const CartVect& v ) const
00102     {
00103         return d[0] == v[0] && d[1] == v[1] && d[2] == v[2];
00104     }
00105     inline bool operator==( double val ) const
00106     {
00107         return d[0] == val && d[1] == val && d[2] == val;
00108     }
00109
00110     inline double length() const;  //!< vector length
00111
00112     inline double length_squared() const;
00113
00114     inline void normalize();  //!< make unit length, or 0 if length < DBL_MIN
00115
00116     inline void flip();  //!< flip direction
00117
00118     /** per-element scalar multiply (this[0] *= v[0], this[1] *= v[1], ...) */
00119     inline void scale( const CartVect& v )
00120     {
00121         d[0] *= v.d[0];
00122         d[1] *= v.d[1];
00123         d[2] *= v.d[2];
00124     }
00125
00126     // get pointer to array of three doubles
00127     inline double* array()
00128     {
00129         return d;
00130     }
00131     inline const double* array() const
00132     {
00133         return d;
00134     }
00135
00136     /** initialize double array from this */
00137     inline void get( double v[3] ) const
00138     {
00139         v[0] = d[0];
00140         v[1] = d[1];
00141         v[2] = d[2];
00142     }
00143
00144     /** initialize float array from this */
00145     inline void get( float v[3] ) const
00146     {
00147         v[0] = static_cast< float >( d[0] );
00148         v[1] = static_cast< float >( d[1] );
00149         v[2] = static_cast< float >( d[2] );
00150     }
00151 };
00152
00153 inline CartVect operator+( const CartVect& u, const CartVect& v )
00154 {
00155     return CartVect( u[0] + v[0], u[1] + v[1], u[2] + v[2] );
00156 }
00157
00158 inline CartVect operator-( const CartVect& u, const CartVect& v )
00159 {
00160     return CartVect( u[0] - v[0], u[1] - v[1], u[2] - v[2] );
00161 }
00162
00163 /** cross product */
00164 inline CartVect operator*( const CartVect& u, const CartVect& v )
00165 {
00166     return CartVect( u[1] * v[2] - u[2] * v[1], u[2] * v[0] - u[0] * v[2], u[0] * v[1] - u[1] * v[0] );
00167 }
00168
00169 //! Dot product
00170 inline double operator%( const CartVect& u, const CartVect& v )
00171 {
00172     return u[0] * v[0] + u[1] * v[1] + u[2] * v[2];
00173 }
00174
00175 inline CartVect& CartVect::operator*=( const CartVect& v )
00176 {
00177     return *this = *this * v;
00178 }
00179
00180 inline double CartVect::length() const
00181 {
00182     return std::sqrt( *this % *this );
00183 }
00184
00185 inline double CartVect::length_squared() const
00186 {
00187     return d[0] * d[0] + d[1] * d[1] + d[2] * d[2];
00188 }
00189
00190 inline void CartVect::normalize()
00191 {
00192     double tmp = length();
00193     if( tmp < DBL_MIN )
00194         d[0] = d[1] = d[2] = 0;
00195     else
00196         *this /= tmp;
00197 }
00198
00199 inline void CartVect::flip()
00200 {
00201     d[0] = -d[0];
00202     d[1] = -d[1];
00203     d[2] = -d[2];
00204 }
00205
00206 //! Interior angle between two vectors
00207 inline double angle( const CartVect& u, const CartVect& v )
00208 {
00209     double tmp = ( u % v ) / std::sqrt( ( u % u ) * ( v % v ) );
00210     if( tmp > 1. ) tmp = 1.;
00211     if( tmp < -1. ) tmp = -1.;
00212     return std::acos( tmp );
00213 }
00214
00215 inline CartVect operator-( const CartVect& v )
00216 {
00217     return CartVect( -v[0], -v[1], -v[2] );
00218 }
00219 inline CartVect operator+( const CartVect& v, double s )
00220 {
00221     return CartVect( v[0] + s, v[1] + s, v[2] + s );
00222 }
00223 inline CartVect operator-( const CartVect& v, double s )
00224 {
00225     return CartVect( v[0] - s, v[1] - s, v[2] - s );
00226 }
00227 inline CartVect operator*( const CartVect& v, double s )
00228 {
00229     return CartVect( v[0] * s, v[1] * s, v[2] * s );
00230 }
00231 inline CartVect operator/( const CartVect& v, double s )
00232 {
00233     return CartVect( v[0] / s, v[1] / s, v[2] / s );
00234 }
00235 inline CartVect operator+( double s, const CartVect& v )
00236 {
00237     return CartVect( v[0] + s, v[1] + s, v[2] + s );
00238 }
00239 inline CartVect operator-( double s, const CartVect& v )
00240 {
00241     return CartVect( v[0] - s, v[1] - s, v[2] - s );
00242 }
00243 inline CartVect operator*( double s, const CartVect& v )
00244 {
00245     return CartVect( v[0] * s, v[1] * s, v[2] * s );
00246 }
00247
00248 //! Get unit vector in same direction
00249 inline CartVect unit( const CartVect& v )
00250 {
00251     const double len = v.length();
00252     return CartVect( v[0] / len, v[1] / len, v[2] / len );
00253 }
00254
00255 std::ostream& operator<<( std::ostream& s, const CartVect& v );
00256
00257 }  // namespace moab
00258
00259 #endif