vec.h
1 /****************************************************************************
2 
3  Copyright (C) 2002-2008 Gilles Debunne. All rights reserved.
4 
5  This file is part of the QGLViewer library version 2.3.10.
6 
7  http://www.libqglviewer.com - contact@libqglviewer.com
8 
9  This file may be used under the terms of the GNU General Public License
10  versions 2.0 or 3.0 as published by the Free Software Foundation and
11  appearing in the LICENSE file included in the packaging of this file.
12  In addition, as a special exception, Gilles Debunne gives you certain
13  additional rights, described in the file GPL_EXCEPTION in this package.
14 
15  libQGLViewer uses dual licensing. Commercial/proprietary software must
16  purchase a libQGLViewer Commercial License.
17 
18  This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
19  WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
20 
21 *****************************************************************************/
22 
23 #ifndef QGLVIEWER_VEC_H
24 #define QGLVIEWER_VEC_H
25 
26 #include <math.h>
27 #include <iostream>
28 
29 #if QT_VERSION >= 0x040000
30 # include <QDomElement>
31 #else
32 # include <qdom.h>
33 #endif
34 
35 // Included by all files as vec.h is at the end of the include hierarchy
36 #include "config.h" // Specific configuration options.
37 
38 namespace qglviewer {
39 
69 class QGLVIEWER_EXPORT Vec
70 {
71 
72  // If your compiler complains the "The class "qglviewer::Vec" has no member "x"."
73  // Add your architecture Q_OS_XXXX flag (see qglobal.h) in this list.
74 #if defined (Q_OS_IRIX) || defined (Q_OS_AIX) || defined (Q_OS_HPUX)
75 # define QGLVIEWER_UNION_NOT_SUPPORTED
76 #endif
77 
78 public:
80 #if defined (DOXYGEN) || defined (QGLVIEWER_UNION_NOT_SUPPORTED)
81  double x, y, z;
82 #else
83  union
84  {
85  struct { double x, y, z; };
86  double v_[3];
87  };
88 #endif
89 
93  Vec() : x(0.0), y(0.0), z(0.0) {}
94 
96  Vec(double X, double Y, double Z) : x(X), y(Y), z(Z) {}
97 
114  template <class C>
115  explicit Vec(const C& c) : x(c[0]), y(c[1]), z(c[2]) {}
116  // Should NOT be explicit to prevent conflicts with operator<<.
117 
118  // ! Copy constructor
119  // Vec(const Vec& v) : x(v.x), y(v.y), z(v.z) {}
120 
122  Vec& operator=(const Vec& v)
123  {
124  x = v.x; y = v.y; z = v.z;
125  return *this;
126  }
127 
129  void setValue(double X, double Y, double Z)
130  { x=X; y=Y; z=Z; }
131 
132  // Universal equal operator which allows the use of any type in place of Vec,
133  // as long as the [] operator is implemented (v[0]=v.x, v[1]=v.y, v[2]=v.z).
134  // template <class C>
135  // Vec& operator=(const C& c)
136  // {
137  // x=c[0]; y=c[1]; z=c[2];
138  // return *this;
139  // }
141 
145  double operator[](int i) const {
146 #ifdef QGLVIEWER_UNION_NOT_SUPPORTED
147  return (&x)[i];
148 #else
149  return v_[i];
150 #endif
151  }
152 
154  double& operator[](int i) {
155 #ifdef QGLVIEWER_UNION_NOT_SUPPORTED
156  return (&x)[i];
157 #else
158  return v_[i];
159 #endif
160  }
161 
162 #ifndef DOXYGEN
163 
164  const double* address() const { qWarning("Vec::address() is deprecated, use operator const double* instead."); return operator const double*(); };
165 #endif
166 
175  operator const double*() const {
176 #ifdef QGLVIEWER_UNION_NOT_SUPPORTED
177  return &x;
178 #else
179  return v_;
180 #endif
181  }
182 
186  operator double*() {
187 #ifdef QGLVIEWER_UNION_NOT_SUPPORTED
188  return &x;
189 #else
190  return v_;
191 #endif
192  }
193 
203  operator const float*() const {
204  static float* const result = new float[3];
205  result[0] = (float)x;
206  result[1] = (float)y;
207  result[2] = (float)z;
208  return result;
209  }
211 
215  friend Vec operator+(const Vec &a, const Vec &b)
216  {
217  return Vec(a.x+b.x, a.y+b.y, a.z+b.z);
218  }
219 
221  friend Vec operator-(const Vec &a, const Vec &b)
222  {
223  return Vec(a.x-b.x, a.y-b.y, a.z-b.z);
224  }
225 
227  friend Vec operator-(const Vec &a)
228  {
229  return Vec(-a.x, -a.y, -a.z);
230  }
231 
233  friend Vec operator*(const Vec &a, double k)
234  {
235  return Vec(a.x*k, a.y*k, a.z*k);
236  }
237 
239  friend Vec operator*(double k, const Vec &a)
240  {
241  return a*k;
242  }
243 
248  friend Vec operator/(const Vec &a, double k)
249  {
250 #ifndef QT_NO_DEBUG
251  if (fabs(k) < 1.0E-10)
252  qWarning("Vec::operator / : dividing by a null value (%f)", k);
253 #endif
254  return Vec(a.x/k, a.y/k, a.z/k);
255  }
256 
258  friend bool operator!=(const Vec &a, const Vec &b)
259  {
260  return !(a==b);
261  }
262 
264  friend bool operator==(const Vec &a, const Vec &b)
265  {
266  const double epsilon = 1.0E-10f;
267  return (a-b).squaredNorm() < epsilon;
268  }
269 
271  Vec& operator+=(const Vec &a)
272  {
273  x += a.x; y += a.y; z += a.z;
274  return *this;
275  }
276 
278  Vec& operator-=(const Vec &a)
279  {
280  x -= a.x; y -= a.y; z -= a.z;
281  return *this;
282  }
283 
285  Vec& operator*=(double k)
286  {
287  x *= k; y *= k; z *= k;
288  return *this;
289  }
290 
295  Vec& operator/=(double k)
296  {
297 #ifndef QT_NO_DEBUG
298  if (fabs(k)<1.0E-10)
299  qWarning("Vec::operator /= : dividing by a null value (%f)", k);
300 #endif
301  x /= k; y /= k; z /= k;
302  return *this;
303  }
304 
306  friend double operator*(const Vec &a, const Vec &b)
307  {
308  return a.x*b.x + a.y*b.y + a.z*b.z;
309  }
310 
312  friend Vec operator^(const Vec &a, const Vec &b)
313  {
314  return cross(a,b);
315  }
316 
318  friend Vec cross(const Vec &a, const Vec &b)
319  {
320  return Vec(a.y*b.z - a.z*b.y,
321  a.z*b.x - a.x*b.z,
322  a.x*b.y - a.y*b.x);
323  }
324 
325  Vec orthogonalVec() const;
327 
330 #ifndef DOXYGEN
331 
332  double sqNorm() const { return x*x + y*y + z*z; }
333 #endif
334 
336  double squaredNorm() const { return x*x + y*y + z*z; }
337 
339  double norm() const { return sqrt(x*x + y*y + z*z); }
340 
344  double normalize()
345  {
346  const double n = norm();
347 #ifndef QT_NO_DEBUG
348  if (n < 1.0E-10)
349  qWarning("Vec::normalize: normalizing a null vector (norm=%f)", n);
350 #endif
351  *this /= n;
352  return n;
353  }
354 
356  Vec unit() const
357  {
358  Vec v = *this;
359  v.normalize();
360  return v;
361  }
363 
366  void projectOnAxis(const Vec& direction);
367  void projectOnPlane(const Vec& normal);
369 
372  explicit Vec(const QDomElement& element);
373  QDomElement domElement(const QString& name, QDomDocument& document) const;
374  void initFromDOMElement(const QDomElement& element);
376 
377 #ifdef DOXYGEN
378 
385  std::ostream& operator<<(std::ostream& o, const qglviewer::Vec&);
387 #endif
388 };
389 
390 } // namespace
391 
392 std::ostream& operator<<(std::ostream& o, const qglviewer::Vec&);
393 
394 #endif // QGLVIEWER_VEC_H