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