Go to the documentation of this file.00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 #ifndef QGLVIEWER_VEC_H
00024 #define QGLVIEWER_VEC_H
00025 
00026 #include <math.h>
00027 #include <iostream>
00028 
00029 #if QT_VERSION >= 0x040000
00030 # include <QDomElement>
00031 #else
00032 # include <qdom.h>
00033 #endif
00034 
00035 
00036 #include "config.h" 
00037 
00038 namespace qglviewer {
00039 
00069 class QGLVIEWER_EXPORT Vec
00070 {
00071 
00072   
00073   
00074 #if defined (Q_OS_IRIX) || defined (Q_OS_AIX) || defined (Q_OS_HPUX)
00075 # define QGLVIEWER_UNION_NOT_SUPPORTED
00076 #endif
00077 
00078 public:
00080 #if defined (DOXYGEN) || defined (QGLVIEWER_UNION_NOT_SUPPORTED)
00081   double x, y, z;
00082 #else
00083   union
00084   {
00085     struct { double x, y, z; };
00086     double v_[3];
00087   };
00088 #endif
00089 
00093   Vec() : x(0.0), y(0.0), z(0.0) {}
00094 
00096   Vec(double X, double Y, double Z) : x(X), y(Y), z(Z) {}
00097 
00114   template <class C>
00115   explicit Vec(const C& c) : x(c[0]), y(c[1]), z(c[2]) {}
00116   
00117 
00118   
00119   
00120 
00122   Vec& operator=(const Vec& v)
00123   {
00124     x = v.x;   y = v.y;   z = v.z;
00125     return *this;
00126   }
00127 
00129   void setValue(double X, double Y, double Z)
00130   { x=X; y=Y; z=Z; }
00131 
00132   
00133   
00134   
00135   
00136   
00137   
00138   
00139   
00141 
00145   double operator[](int i) const {
00146 #ifdef QGLVIEWER_UNION_NOT_SUPPORTED
00147     return (&x)[i];
00148 #else
00149     return v_[i];
00150 #endif
00151   }
00152 
00154   double& operator[](int i) {
00155 #ifdef QGLVIEWER_UNION_NOT_SUPPORTED
00156     return (&x)[i];
00157 #else
00158     return v_[i];
00159 #endif
00160   }
00161 
00162 #ifndef DOXYGEN
00163 
00164   const double* address() const { qWarning("Vec::address() is deprecated, use operator const double* instead."); return operator const double*(); };
00165 #endif
00166 
00175   operator const double*() const {
00176 #ifdef QGLVIEWER_UNION_NOT_SUPPORTED
00177     return &x;
00178 #else
00179     return v_;
00180 #endif
00181   }
00182 
00186   operator double*() {
00187 #ifdef QGLVIEWER_UNION_NOT_SUPPORTED
00188     return &x;
00189 #else
00190     return v_;
00191 #endif
00192   }
00193 
00203   operator const float*() const {
00204         static float* const result = new float[3];
00205         result[0] = (float)x;
00206         result[1] = (float)y;
00207         result[2] = (float)z;
00208         return result;
00209   }
00211 
00215   friend Vec operator+(const Vec &a, const Vec &b)
00216   {
00217     return Vec(a.x+b.x, a.y+b.y, a.z+b.z);
00218   }
00219 
00221   friend Vec operator-(const Vec &a, const Vec &b)
00222   {
00223     return Vec(a.x-b.x, a.y-b.y, a.z-b.z);
00224   }
00225 
00227   friend Vec operator-(const Vec &a)
00228   {
00229     return Vec(-a.x, -a.y, -a.z);
00230   }
00231 
00233   friend Vec operator*(const Vec &a, double k)
00234   {
00235     return Vec(a.x*k, a.y*k, a.z*k);
00236   }
00237 
00239   friend Vec operator*(double k, const Vec &a)
00240   {
00241     return a*k;
00242   }
00243 
00248   friend Vec operator/(const Vec &a, double k)
00249   {
00250 #ifndef QT_NO_DEBUG
00251     if (fabs(k) < 1.0E-10)
00252       qWarning("Vec::operator / : dividing by a null value (%f)", k);
00253 #endif
00254     return Vec(a.x/k, a.y/k, a.z/k);
00255   }
00256 
00258   friend bool operator!=(const Vec &a, const Vec &b)
00259   {
00260     return !(a==b);
00261   }
00262 
00264   friend bool operator==(const Vec &a, const Vec &b)
00265   {
00266     const double epsilon = 1.0E-10f;
00267     return (a-b).squaredNorm() < epsilon;
00268   }
00269 
00271   Vec& operator+=(const Vec &a)
00272   {
00273     x += a.x; y += a.y; z += a.z;
00274     return *this;
00275   }
00276 
00278   Vec& operator-=(const Vec &a)
00279   {
00280     x -= a.x; y -= a.y; z -= a.z;
00281     return *this;
00282   }
00283 
00285   Vec& operator*=(double k)
00286   {
00287     x *= k; y *= k; z *= k;
00288     return *this;
00289   }
00290 
00295   Vec& operator/=(double k)
00296   {
00297 #ifndef QT_NO_DEBUG
00298     if (fabs(k)<1.0E-10)
00299       qWarning("Vec::operator /= : dividing by a null value (%f)", k);
00300 #endif
00301     x /= k; y /= k; z /= k;
00302     return *this;
00303   }
00304 
00306   friend double operator*(const Vec &a, const Vec &b)
00307   {
00308     return a.x*b.x + a.y*b.y + a.z*b.z;
00309   }
00310 
00312   friend Vec operator^(const Vec &a, const Vec &b)
00313   {
00314     return cross(a,b);
00315   }
00316 
00318   friend Vec cross(const Vec &a, const Vec &b)
00319   {
00320     return Vec(a.y*b.z - a.z*b.y,
00321                a.z*b.x - a.x*b.z,
00322                a.x*b.y - a.y*b.x);
00323   }
00324 
00325   Vec orthogonalVec() const;
00327 
00330 #ifndef DOXYGEN
00331 
00332   double sqNorm() const { return x*x + y*y + z*z; }
00333 #endif
00334 
00336   double squaredNorm() const { return x*x + y*y + z*z; }
00337 
00339   double norm() const { return sqrt(x*x + y*y + z*z); }
00340 
00344   double normalize()
00345   {
00346     const double n = norm();
00347 #ifndef QT_NO_DEBUG
00348     if (n < 1.0E-10)
00349       qWarning("Vec::normalize: normalizing a null vector (norm=%f)", n);
00350 #endif
00351     *this /= n;
00352     return n;
00353   }
00354 
00356   Vec unit() const
00357   {
00358     Vec v = *this;
00359     v.normalize();
00360     return v;
00361   }
00363 
00366   void projectOnAxis(const Vec& direction);
00367   void projectOnPlane(const Vec& normal);
00369 
00372   explicit Vec(const QDomElement& element);
00373   QDomElement domElement(const QString& name, QDomDocument& document) const;
00374   void initFromDOMElement(const QDomElement& element);
00376 
00377 #ifdef DOXYGEN
00378 
00385   std::ostream& operator<<(std::ostream& o, const qglviewer::Vec&);
00387 #endif
00388 };
00389 
00390 } 
00391 
00392 std::ostream& operator<<(std::ostream& o, const qglviewer::Vec&);
00393 
00394 #endif // QGLVIEWER_VEC_H