vec.h
1 /****************************************************************************
2 
3  Copyright (C) 2002-2013 Gilles Debunne. All rights reserved.
4 
5  This file is part of the QGLViewer library version 2.5.2.
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 # include <QDomElement>
30 
31 // Included by all files as vec.h is at the end of the include hierarchy
32 #include "config.h" // Specific configuration options.
33 
34 namespace qglviewer {
35 
65 class QGLVIEWER_EXPORT Vec
66 {
67 
68  // If your compiler complains the "The class "qglviewer::Vec" has no member "x"."
69  // Add your architecture Q_OS_XXXX flag (see qglobal.h) in this list.
70 #if defined (Q_OS_IRIX) || defined (Q_OS_AIX) || defined (Q_OS_HPUX)
71 # define QGLVIEWER_UNION_NOT_SUPPORTED
72 #endif
73 
74 public:
76 #if defined (DOXYGEN) || defined (QGLVIEWER_UNION_NOT_SUPPORTED)
77  double x, y, z;
78 #else
79  union
80  {
81  struct { double x, y, z; };
82  double v_[3];
83  };
84 #endif
85 
89  Vec() : x(0.0), y(0.0), z(0.0) {}
90 
92  Vec(double X, double Y, double Z) : x(X), y(Y), z(Z) {}
93 
110  template <class C>
111  explicit Vec(const C& c) : x(c[0]), y(c[1]), z(c[2]) {}
112  // Should NOT be explicit to prevent conflicts with operator<<.
113 
114  // ! Copy constructor
115  // Vec(const Vec& v) : x(v.x), y(v.y), z(v.z) {}
116 
118  Vec& operator=(const Vec& v)
119  {
120  x = v.x; y = v.y; z = v.z;
121  return *this;
122  }
123 
125  void setValue(double X, double Y, double Z)
126  { x=X; y=Y; z=Z; }
127 
128  // Universal equal operator which allows the use of any type in place of Vec,
129  // as long as the [] operator is implemented (v[0]=v.x, v[1]=v.y, v[2]=v.z).
130  // template <class C>
131  // Vec& operator=(const C& c)
132  // {
133  // x=c[0]; y=c[1]; z=c[2];
134  // return *this;
135  // }
137 
141  double operator[](int i) const {
142 #ifdef QGLVIEWER_UNION_NOT_SUPPORTED
143  return (&x)[i];
144 #else
145  return v_[i];
146 #endif
147  }
148 
150  double& operator[](int i) {
151 #ifdef QGLVIEWER_UNION_NOT_SUPPORTED
152  return (&x)[i];
153 #else
154  return v_[i];
155 #endif
156  }
157 
158 #ifndef DOXYGEN
159 
160  const double* address() const { qWarning("Vec::address() is deprecated, use operator const double* instead."); return operator const double*(); }
161 #endif
162 
171  operator const double*() const {
172 #ifdef QGLVIEWER_UNION_NOT_SUPPORTED
173  return &x;
174 #else
175  return v_;
176 #endif
177  }
178 
182  operator double*() {
183 #ifdef QGLVIEWER_UNION_NOT_SUPPORTED
184  return &x;
185 #else
186  return v_;
187 #endif
188  }
189 
199  operator const float*() const {
200  static float* const result = new float[3];
201  result[0] = (float)x;
202  result[1] = (float)y;
203  result[2] = (float)z;
204  return result;
205  }
207 
211  friend Vec operator+(const Vec &a, const Vec &b)
212  {
213  return Vec(a.x+b.x, a.y+b.y, a.z+b.z);
214  }
215 
217  friend Vec operator-(const Vec &a, const Vec &b)
218  {
219  return Vec(a.x-b.x, a.y-b.y, a.z-b.z);
220  }
221 
223  friend Vec operator-(const Vec &a)
224  {
225  return Vec(-a.x, -a.y, -a.z);
226  }
227 
229  friend Vec operator*(const Vec &a, double k)
230  {
231  return Vec(a.x*k, a.y*k, a.z*k);
232  }
233 
235  friend Vec operator*(double k, const Vec &a)
236  {
237  return a*k;
238  }
239 
244  friend Vec operator/(const Vec &a, double k)
245  {
246 #ifndef QT_NO_DEBUG
247  if (fabs(k) < 1.0E-10)
248  qWarning("Vec::operator / : dividing by a null value (%f)", k);
249 #endif
250  return Vec(a.x/k, a.y/k, a.z/k);
251  }
252 
254  friend bool operator!=(const Vec &a, const Vec &b)
255  {
256  return !(a==b);
257  }
258 
260  friend bool operator==(const Vec &a, const Vec &b)
261  {
262  const double epsilon = 1.0E-10f;
263  return (a-b).squaredNorm() < epsilon;
264  }
265 
267  Vec& operator+=(const Vec &a)
268  {
269  x += a.x; y += a.y; z += a.z;
270  return *this;
271  }
272 
274  Vec& operator-=(const Vec &a)
275  {
276  x -= a.x; y -= a.y; z -= a.z;
277  return *this;
278  }
279 
281  Vec& operator*=(double k)
282  {
283  x *= k; y *= k; z *= k;
284  return *this;
285  }
286 
291  Vec& operator/=(double k)
292  {
293 #ifndef QT_NO_DEBUG
294  if (fabs(k)<1.0E-10)
295  qWarning("Vec::operator /= : dividing by a null value (%f)", k);
296 #endif
297  x /= k; y /= k; z /= k;
298  return *this;
299  }
300 
302  friend double operator*(const Vec &a, const Vec &b)
303  {
304  return a.x*b.x + a.y*b.y + a.z*b.z;
305  }
306 
308  friend Vec operator^(const Vec &a, const Vec &b)
309  {
310  return cross(a,b);
311  }
312 
314  friend Vec cross(const Vec &a, const Vec &b)
315  {
316  return Vec(a.y*b.z - a.z*b.y,
317  a.z*b.x - a.x*b.z,
318  a.x*b.y - a.y*b.x);
319  }
320 
321  Vec orthogonalVec() const;
323 
326 #ifndef DOXYGEN
327 
328  double sqNorm() const { return x*x + y*y + z*z; }
329 #endif
330 
332  double squaredNorm() const { return x*x + y*y + z*z; }
333 
335  double norm() const { return sqrt(x*x + y*y + z*z); }
336 
340  double normalize()
341  {
342  const double n = norm();
343 #ifndef QT_NO_DEBUG
344  if (n < 1.0E-10)
345  qWarning("Vec::normalize: normalizing a null vector (norm=%f)", n);
346 #endif
347  *this /= n;
348  return n;
349  }
350 
352  Vec unit() const
353  {
354  Vec v = *this;
355  v.normalize();
356  return v;
357  }
359 
362  void projectOnAxis(const Vec& direction);
363  void projectOnPlane(const Vec& normal);
365 
368  explicit Vec(const QDomElement& element);
369  QDomElement domElement(const QString& name, QDomDocument& document) const;
370  void initFromDOMElement(const QDomElement& element);
372 
373 #ifdef DOXYGEN
374 
381  std::ostream& operator<<(std::ostream& o, const qglviewer::Vec&);
383 #endif
384 };
385 
386 } // namespace
387 
388 std::ostream& operator<<(std::ostream& o, const qglviewer::Vec&);
389 
390 #endif // QGLVIEWER_VEC_H
friend Vec operator*(double k, const Vec &a)
Returns the product of a scalar with the vector.
Definition: vec.h:235
friend Vec operator^(const Vec &a, const Vec &b)
Cross product of the two vectors.
Definition: vec.h:308
double squaredNorm() const
Returns the squared norm of the Vec.
Definition: vec.h:332
double sqNorm() const
This method is deprecated since version 2.0.
Definition: vec.h:328
friend Vec operator-(const Vec &a, const Vec &b)
Returns the difference of the two vectors.
Definition: vec.h:217
Vec(double X, double Y, double Z)
Standard constructor with the x, y and z values.
Definition: vec.h:92
double norm() const
Returns the norm of the vector.
Definition: vec.h:335
Vec & operator*=(double k)
Multiply the vector by a scalar k.
Definition: vec.h:281
Vec()
Default constructor.
Definition: vec.h:89
double & operator[](int i)
Bracket operator returning an l-value.
Definition: vec.h:150
Vec & operator-=(const Vec &a)
Subtracts a to the vector.
Definition: vec.h:274
Vec & operator+=(const Vec &a)
Adds a to the vector.
Definition: vec.h:267
The Vec class represents 3D positions and 3D vectors.
Definition: vec.h:65
friend bool operator!=(const Vec &a, const Vec &b)
Returns true only when the two vector are not equal (see operator==()).
Definition: vec.h:254
double operator[](int i) const
Bracket operator, with a constant return value.
Definition: vec.h:141
friend Vec operator/(const Vec &a, double k)
Returns the division of the vector with a scalar.
Definition: vec.h:244
Vec & operator/=(double k)
Divides the vector by a scalar k.
Definition: vec.h:291
const double * address() const
This method is deprecated since version 2.0.
Definition: vec.h:160
Vec unit() const
Returns a unitary (normalized) representation of the vector.
Definition: vec.h:352
friend double operator*(const Vec &a, const Vec &b)
Dot product of the two Vec.
Definition: vec.h:302
void setValue(double X, double Y, double Z)
Set the current value.
Definition: vec.h:125
Vec(const C &c)
Universal explicit converter from any class to Vec.
Definition: vec.h:111
friend Vec operator-(const Vec &a)
Unary minus operator.
Definition: vec.h:223
friend Vec cross(const Vec &a, const Vec &b)
Cross product of the two Vec.
Definition: vec.h:314
double normalize()
Normalizes the Vec and returns its original norm.
Definition: vec.h:340
friend bool operator==(const Vec &a, const Vec &b)
Returns true when the squaredNorm() of the difference vector is lower than 1E-10. ...
Definition: vec.h:260
Vec & operator=(const Vec &v)
Equal operator.
Definition: vec.h:118
friend Vec operator*(const Vec &a, double k)
Returns the product of the vector with a scalar.
Definition: vec.h:229
friend Vec operator+(const Vec &a, const Vec &b)
Returns the sum of the two vectors.
Definition: vec.h:211