vector4.h

Go to the documentation of this file.
00001 // -*- Mode: C++; tab-width: 2; -*-
00002 // vi: set ts=2:
00003 //
00004 // $Id: vector4.h,v 1.53 2004/07/05 20:57:29 oliver Exp $
00005 //
00006 
00007 #ifndef BALL_MATHS_VECTOR4_H
00008 #define BALL_MATHS_VECTOR4_H
00009 
00010 #ifndef BALL_COMMON_EXCEPTION_H
00011 # include <BALL/COMMON/exception.h>
00012 #endif
00013 
00014 #ifndef BALL_MATHS_ANGLE_H
00015 # include <BALL/MATHS/angle.h>
00016 #endif
00017 
00018 #ifdef BALL_HAS_IEEEFP_H
00019 # include <ieeefp.h>
00020 #endif 
00021 
00022 namespace BALL 
00023 {
00028 
00029   template <typename T>
00030   class TVector4;
00031   
00035 
00036   template <typename T>
00037   BALL_INLINE
00038   TVector4<T> operator + (const TVector4<T>& a, const TVector4<T>& b);
00039 
00040   template <typename T>
00041   BALL_INLINE
00042   TVector4<T> operator - (const TVector4<T>& a, const TVector4<T>& b);
00043   
00044   template <typename T>
00045   std::istream& operator >> (std::istream& s, TVector4<T>& vector);
00046 
00047   template <typename T>
00048   std::ostream& operator << (std::ostream& s, const TVector4<T>& vector);
00049     
00053   template <typename T>
00054   class TVector4
00055   {
00056     public:
00057 
00058     BALL_CREATE(TVector4<T>)
00059 
00060     
00063 
00068     TVector4();
00069 
00076     TVector4(const T* ptr)
00077     throw(Exception::NullPointer);
00078 
00084       explicit TVector4(const T& value);
00085 
00093     TVector4(const T& x, const T& y, const T& z, const T& h = (T)1);
00094 
00099     TVector4(const TVector4& vector);
00100 
00105     virtual ~TVector4();
00106 
00110     virtual void clear()
00111     {
00112       x = y = z = h = (T)0;
00113     }
00114 
00116 
00119   
00126     void set(const T* ptr)
00127       throw(Exception::NullPointer);
00128 
00135     void set(const T& rx, const T& ry, const T& rz, const T& rh = (T)1);
00136 
00140     void set(const TVector4& vector);
00141 
00147     TVector4& operator = (const T* ptr)
00148     throw(Exception::NullPointer);
00149 
00154     TVector4& operator = (const TVector4& vector);
00155 
00160     TVector4& operator = (T value);
00161 
00168     void get(T* ptr) const
00169       throw(Exception::NullPointer);
00170 
00177     void get(T& rx, T& ry, T& rz, T& rh) const;
00178 
00183     void get(TVector4& vector) const;
00184 
00188     void swap(TVector4& vector);
00189 
00191 
00194 
00200     T getLength() const;
00201 
00207     T getSquareLength() const;
00208 
00215     TVector4& normalize()
00216       throw(Exception::DivisionByZero);
00217 
00220     static const TVector4& getZero();
00221 
00224     static const TVector4& getUnit();
00225 
00229     void set(const T& value = (T)1);
00230 
00234     T& operator [] (Position position)
00235       throw(Exception::IndexOverflow);
00236 
00240     const T& operator [] (Position position) const
00241       throw(Exception::IndexOverflow);
00242 
00244 
00247 
00250     TVector4 operator + () const;
00251 
00254     TVector4 operator - () const;
00255 
00260     TVector4& operator += (const TVector4& vector);
00261 
00266     TVector4& operator -= (const TVector4& vector);
00267 
00273     TVector4 operator * (const T& scalar);
00274 
00280     TVector4& operator *= (const T& scalar);
00281 
00288     TVector4 operator / (const T& scalar)
00289       throw(Exception::DivisionByZero);
00290 
00296     TVector4& operator /= (const T& scalar)
00297       throw(Exception::DivisionByZero);
00298 
00303     T operator * (const TVector4& vector) const;
00304 
00309     T getDistance(const TVector4& vector) const;
00310 
00317     T getSquareDistance(const TVector4& vector) const
00318       ;
00319 
00321 
00324       
00330     bool operator == (const TVector4& vector) const
00331       ;
00332 
00338     bool operator != (const TVector4& vector) const
00339       ;
00340 
00343     bool isOrthogonalTo(const TVector4& vector) const
00344       ;
00345 
00347 
00350 
00355     bool isValid() const
00356       ;
00357 
00364     void dump(std::ostream& s = std::cout, Size depth = 0) const
00365       ;
00366 
00368 
00372 
00375     T x;
00376 
00379     T y;
00380 
00383     T z;
00384 
00387     T h;
00388 
00390   };
00392   
00393   template <typename T>
00394   TVector4<T>::TVector4()
00395     
00396     : x(0),
00397       y(0),
00398       z(0),
00399       h(0)
00400   {
00401   }
00402 
00403   template <typename T>
00404   TVector4<T>::TVector4(const T* ptr)
00405     throw(Exception::NullPointer)
00406   {
00407     if (ptr == 0)
00408     {
00409       throw Exception::NullPointer(__FILE__, __LINE__);
00410     }
00411     
00412     x = *ptr++;
00413     y = *ptr++;
00414     z = *ptr++;
00415     h = *ptr;
00416   }
00417 
00418 
00419   template <typename T>
00420   TVector4<T>::TVector4(const T& value)
00421     
00422     : x(value),
00423       y(value),
00424       z(value),
00425       h(value)
00426   {
00427   }                                                                                                                                                                                
00428 
00429   template <typename T>
00430   TVector4<T>::TVector4(const T& x, const T& y, const T& z, const T& h)
00431     
00432     : x(x),
00433       y(y),
00434       z(z),
00435       h(h)
00436   {
00437   }
00438 
00439   template <typename T>
00440   TVector4<T>::TVector4(const TVector4<T>& v)
00441     
00442     : x(v.x),
00443       y(v.y),
00444       z(v.z),
00445       h(v.h)
00446   {
00447   }
00448 
00449   template <typename T>
00450   TVector4<T>::~TVector4()
00451     
00452   {
00453   }
00454 
00455   template <typename T>
00456   BALL_INLINE 
00457   void TVector4<T>::set(const T* ptr)
00458     throw(Exception::NullPointer)
00459   {
00460     if (ptr == 0)
00461     {
00462       throw Exception::NullPointer(__FILE__, __LINE__);
00463     }
00464     x = *ptr++;
00465     y = *ptr++;
00466     z = *ptr++;
00467     h = *ptr;
00468   }
00469 
00470   template <typename T>
00471   BALL_INLINE 
00472   void TVector4<T>::set(const T& rx, const T& ry, const T& rz, const T& rh)
00473     
00474   {
00475     x = rx;
00476     y = ry;
00477     z = rz;
00478     h = rh;
00479   }
00480 
00481   template <typename T>
00482   BALL_INLINE 
00483   void TVector4<T>::set(const TVector4<T>& v)
00484     
00485   {
00486     x = v.x;
00487     y = v.y;
00488     z = v.z;
00489     h = v.h;
00490   }
00491 
00492   template <typename T>
00493   BALL_INLINE 
00494   TVector4<T>& TVector4<T>::operator = (const T* ptr)
00495     throw(Exception::NullPointer)
00496   {
00497     if (ptr == 0)
00498     {
00499       throw Exception::NullPointer(__FILE__, __LINE__);
00500     }
00501     x = *ptr++;
00502     y = *ptr++;
00503     z = *ptr++;
00504     h = *ptr;
00505 
00506     return *this;
00507   }
00508 
00509   template <typename T>
00510   BALL_INLINE 
00511   TVector4<T>& TVector4<T>::operator = (const TVector4<T>& v)
00512     
00513   {
00514     x = v.x;
00515     y = v.y;
00516     z = v.z;
00517     h = v.h;
00518 
00519     return *this;
00520   }
00521 
00522   template <typename T>
00523   BALL_INLINE 
00524   TVector4<T>& TVector4<T>::operator = (T value)
00525     
00526   {
00527     x = value;
00528     y = value;
00529     z = value;
00530     h = value;
00531 
00532     return *this;
00533   }
00534 
00535   template <typename T>
00536   BALL_INLINE 
00537   void TVector4<T>::get(T* ptr) const
00538     throw(Exception::NullPointer)
00539   {
00540     if (ptr == 0)
00541     {
00542       throw Exception::NullPointer(__FILE__, __LINE__);
00543     }
00544     *ptr++ = x;
00545     *ptr++ = y;
00546     *ptr++ = z;
00547     *ptr   = h;
00548   }
00549 
00550   template <typename T>
00551   BALL_INLINE 
00552   void TVector4<T>::get(T& rx, T& ry, T& rz, T& rh) const
00553     
00554   {
00555     rx = x;
00556     ry = y;
00557     rz = z;
00558     rh = h;
00559   }
00560 
00561   template <typename T>
00562   BALL_INLINE 
00563   void TVector4<T>::get(TVector4<T>& v) const
00564     
00565   {
00566     v.x = x;
00567     v.y = y;
00568     v.z = z;
00569     v.h = h;
00570   }
00571 
00572   template <typename T>
00573   void TVector4<T>::swap(TVector4<T>& v)
00574     
00575   {
00576     T temp = x;
00577     x = v.x;
00578     v.x = temp;
00579 
00580     temp = y;
00581     y = v.y;
00582     v.y = temp;
00583 
00584     temp = z;
00585     z = v.z;
00586     v.z = temp;
00587 
00588     temp = h;
00589     h = v.h;
00590     v.h = temp;
00591   }
00592 
00593   template <typename T>
00594   BALL_INLINE 
00595   T TVector4<T>::getLength() const
00596     
00597   {
00598     return (T)sqrt(x * x + y * y + z * z + h * h);
00599   }
00600 
00601   template <typename T>
00602   BALL_INLINE 
00603   T TVector4<T>::getSquareLength() const
00604     
00605   {
00606     return (T)(x * x + y * y + z * z + h * h);
00607   }
00608 
00609   template <typename T>
00610 
00611   BALL_INLINE
00612   TVector4<T>& TVector4<T>::normalize()
00613     throw(Exception::DivisionByZero)
00614   {
00615     T len = (T)sqrt(x * x + y * y + z * z + h * h);
00616 
00617     if (Maths::isZero(len))
00618     {
00619       throw Exception::DivisionByZero(__FILE__, __LINE__);    
00620     }
00621     
00622     x /= len;
00623     y /= len;
00624     z /= len;
00625     h /= len;
00626 
00627     return *this;
00628   }
00629 
00630   template <typename T>
00631   BALL_INLINE 
00632   const TVector4<T>& TVector4<T>::getZero()
00633     
00634   {
00635     static const TVector4<T> null4(0, 0, 0, 0);
00636     return null4;
00637   }
00638 
00639   template <typename T>
00640   BALL_INLINE 
00641   const TVector4<T>& TVector4<T>::getUnit()
00642     
00643   {
00644     static const TVector4<T> unit_vector(1, 1, 1, 1);
00645     return unit_vector;
00646   }
00647 
00648   template <typename T>
00649   BALL_INLINE 
00650   void TVector4<T>::set(const T& value)
00651     
00652   {
00653     x = y = z = h = value;
00654   }
00655 
00656   template <typename T>
00657   BALL_INLINE 
00658   T& TVector4<T>::operator [] (Position pos)
00659     throw(Exception::IndexOverflow)
00660   {
00661     if (pos > 3)
00662     {
00663       throw Exception::IndexOverflow(__FILE__, __LINE__);
00664     }
00665     switch (pos) 
00666     {
00667       case 0: return x;
00668       case 1: return y;
00669       case 2: return z;
00670       case 3:
00671       default:
00672         return h;
00673     }
00674   }
00675 
00676   template <typename T>
00677   BALL_INLINE 
00678   const T& TVector4<T>::operator [] (Position pos) const
00679     throw(Exception::IndexOverflow)
00680   {
00681     if (pos > 3)
00682     {
00683       throw Exception::IndexOverflow(__FILE__, __LINE__);
00684     }
00685     switch (pos) 
00686     {
00687       case 0: return x;
00688       case 1: return y;
00689       case 2: return z;
00690       case 3:
00691       default:
00692         return h;
00693     }
00694   }
00695 
00696   template <typename T>
00697   BALL_INLINE 
00698   TVector4<T> TVector4<T>::operator + () const
00699     
00700   {
00701     return *this;
00702   }
00703 
00704   template <typename T>
00705   BALL_INLINE 
00706   TVector4<T> TVector4<T>::operator - () const
00707     
00708   {
00709     return TVector4<T>(-x, -y, -z, -h);
00710   }
00711 
00712   template <typename T>
00713   BALL_INLINE 
00714   TVector4<T>& TVector4<T>::operator += (const TVector4<T>& v)
00715     
00716   {
00717     x += v.x;
00718     y += v.y;
00719     z += v.z;
00720     h += v.h;
00721 
00722     return *this;
00723   }
00724 
00725   template <typename T>
00726   BALL_INLINE 
00727   TVector4<T>& TVector4<T>::operator -= (const TVector4<T> &v)
00728     
00729   {
00730     x -= v.x;
00731     y -= v.y;
00732     z -= v.z;
00733     h -= v.h;
00734 
00735     return *this;
00736   }
00737 
00738   template <typename T>
00739   BALL_INLINE 
00740   TVector4<T> TVector4<T>::operator * (const T& scalar)
00741     
00742   {
00743     return TVector4<T>(x * scalar, y * scalar, z * scalar, h * scalar);
00744   }
00745 
00746   template <typename T>
00747   BALL_INLINE 
00748   TVector4<T>& TVector4<T>::operator *= (const T &scalar)
00749     
00750   {
00751     x *= scalar;
00752     y *= scalar;
00753     z *= scalar;
00754     h *= scalar;
00755 
00756     return *this;
00757   }
00758 
00759   template <typename T>
00760   TVector4<T>TVector4<T>::operator / (const T &scalar)
00761     throw(Exception::DivisionByZero)
00762   {
00763     if (Maths::isZero(scalar))
00764     {
00765       throw Exception::DivisionByZero(__FILE__, __LINE__);
00766     }
00767     return TVector4<T>(x / scalar, y / scalar, z / scalar, h / scalar); 
00768   }
00769 
00770   template <typename T>
00771   TVector4<T>& TVector4<T>::operator /= (const T& scalar)
00772     throw(Exception::DivisionByZero)
00773   {
00774     if (Maths::isZero(scalar))
00775     {
00776       throw Exception::DivisionByZero(__FILE__, __LINE__);
00777     }
00778     x /= scalar;
00779     y /= scalar;
00780     z /= scalar;
00781     h /= scalar;
00782 
00783     return *this;
00784   }
00785 
00786   template <typename T>
00787   BALL_INLINE 
00788   T TVector4<T>::operator * (const TVector4<T>& v) const
00789     
00790   {
00791     return (x * v.x + y * v.y + z * v.z + h * v.h);
00792   }
00793 
00794   template <typename T>
00795   BALL_INLINE 
00796   T TVector4<T>::getDistance(const TVector4<T> &v) const
00797     
00798   {
00799     T da = x - v.x;
00800     T db = y - v.y;
00801     T dc = z - v.z;
00802     T dd = h - v.h;
00803     
00804     return (T)sqrt(da * da + db * db + dc * dc + dd * dd); 
00805   }
00806 
00807   template <typename T>
00808   BALL_INLINE 
00809   T TVector4<T>::getSquareDistance(const TVector4<T> &v) const
00810     
00811   {
00812     T da = x - v.x;
00813     T db = y - v.y;
00814     T dc = z - v.z;
00815     T dd = h - v.h;
00816     
00817     return (da * da + db * db + dc * dc + dd * dd); 
00818   }
00819 
00820   template <typename T>
00821   BALL_INLINE 
00822   bool TVector4<T>::operator == (const TVector4<T>& v) const
00823     
00824   {
00825     return (Maths::isEqual(x, v.x) && Maths::isEqual(y, v.y) 
00826                   && Maths::isEqual(z, v.z) && Maths::isEqual(h, v.h));
00827   }
00828 
00829   template <typename T>
00830   BALL_INLINE 
00831   bool TVector4<T>::operator != (const TVector4<T>& v) const
00832     
00833   {
00834     return (Maths::isNotEqual(x, v.x) || Maths::isNotEqual(y, v.y)
00835                   || Maths::isNotEqual(z, v.z) || Maths::isNotEqual(h, v.h));
00836   }
00837 
00838   template <typename T>
00839   BALL_INLINE 
00840   bool TVector4<T>::isOrthogonalTo(const TVector4<T>& v) const
00841     
00842   {
00843     return Maths::isZero(*this * v);
00844   }
00845 
00846   template <typename T>
00847   BALL_INLINE 
00848   bool TVector4<T>::isValid() const
00849     
00850   {
00851     return true;
00852   }
00853 
00854   template <typename T>
00855   void TVector4<T>::dump(std::ostream& s, Size depth) const
00856     
00857   {
00858     BALL_DUMP_STREAM_PREFIX(s);
00859 
00860     BALL_DUMP_HEADER(s, this, this);
00861 
00862     BALL_DUMP_DEPTH(s, depth);
00863     s << "x= " << x 
00864       << ", y = " << y
00865       << ", z = " << z
00866       << ", h = " << h << std::endl;
00867 
00868     BALL_DUMP_STREAM_SUFFIX(s);
00869   }
00870 
00873   typedef TVector4<float> Vector4;
00874 
00877   template <typename T>
00878   BALL_INLINE 
00879   TVector4<T> operator + (const TVector4<T>& a, const TVector4<T>& b)
00880     
00881   {
00882     return TVector4<T>(a.x + b.x, a.y + b.y, a.z + b.z, a.h + b.h);
00883   }
00884 
00888   template <typename T>
00889   BALL_INLINE 
00890   TVector4<T> operator - (const TVector4<T>& a, const TVector4<T>& b)
00891     
00892   {
00893     return TVector4<T>(a.x - b.x, a.y - b.y, a.z - b.z, a.h - b.h);
00894   }
00895 
00899   template <typename T>
00900   BALL_INLINE 
00901   TVector4<T> operator * (const T& scalar, const TVector4<T>& v)
00902     
00903   {
00904     return TVector4<T>(scalar * v.x, scalar * v.y, scalar * v.z, scalar * v.h);
00905   }
00906 
00910   template <typename T>
00911   BALL_INLINE 
00912   TVector4<T> operator * (const TVector4<T>& v, const T& scalar)
00913     
00914   {
00915     return TVector4<T>(scalar * v.x, scalar * v.y, scalar * v.z, scalar * v.h);
00916   }
00917 
00918 
00923   template <typename T>
00924   std::istream& operator >> (std::istream& s, TVector4<T>& v)
00925     
00926   {
00927     char c;
00928     s >> c >> v.x >> v.y >> v.z >> v.h >>c;  
00929     return s;
00930   }
00931 
00938   template <typename T>
00939   std::ostream& operator << (std::ostream& s, const TVector4<T>& v)
00940     
00941   {
00942     s << '(' <<v.x << ' ' << v.y << ' ' << v.z << ' ' << v.h << ')';
00943     
00944     return s;
00945   }
00946 } // namespace BALL
00947 
00948 #endif // BALL_MATHS_VECTOR4_H