GLC_lib  2.5.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
glc_vector3d.h
Go to the documentation of this file.
1 /****************************************************************************
2 
3  This file is part of the GLC-lib library.
4  Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net)
5  http://glc-lib.sourceforge.net
6 
7  GLC-lib is free software; you can redistribute it and/or modify
8  it under the terms of the GNU Lesser General Public License as published by
9  the Free Software Foundation; either version 3 of the License, or
10  (at your option) any later version.
11 
12  GLC-lib is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  GNU Lesser General Public License for more details.
16 
17  You should have received a copy of the GNU Lesser General Public License
18  along with GLC-lib; if not, write to the Free Software
19  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 
21 *****************************************************************************/
22 
24 
25 #ifndef GLC_VECTOR3D_H_
26 #define GLC_VECTOR3D_H_
27 
28 #include <QDataStream>
29 
30 #include "glc_utils_maths.h"
31 #include "glc_vector3df.h"
32 #include "glc_vector2d.h"
33 #include "../glc_config.h"
34 
37 
41 
42 
44 {
45  friend class GLC_Vector4d;
46  friend class GLC_Matrix4x4;
47 
49  inline friend GLC_Vector3d operator - (const GLC_Vector3d &Vect)
50  {return GLC_Vector3d(-Vect.m_Vector[0], -Vect.m_Vector[1], -Vect.m_Vector[2]);}
51 
53  inline friend GLC_Vector3d operator*(double s, const GLC_Vector3d &v)
54  {return GLC_Vector3d(s * v.m_Vector[0], s * v.m_Vector[1], s * v.m_Vector[2]);}
55 
57 
59 
60 public:
62 
67  inline GLC_Vector3d();
68 
70  inline GLC_Vector3d(double x, double y, double z);
71 
73  inline GLC_Vector3d(const GLC_Vector3d &vector)
74  {memcpy(m_Vector, vector.m_Vector, sizeof(double) * 3);}
75 
77  inline GLC_Vector3d(const GLC_Vector3df &vector);
78 
80  inline GLC_Vector3d(const GLC_Vector2d &vector);
81 
83 
85 
87 
88 public:
90  inline double x() const
91  {return m_Vector[0];}
92 
94  inline double y() const
95  {return m_Vector[1];}
96 
98  inline double z() const
99  {return m_Vector[2];}
100 
102  inline const double *data() const
103  {return m_Vector;}
104 
106  inline bool isNull() const
107  {return (qAbs(m_Vector[0]) < glc::EPSILON) && (qAbs(m_Vector[1]) < glc::EPSILON) && (qAbs(m_Vector[2]) < glc::EPSILON);}
108 
110  inline double length() const
111  {return sqrt(m_Vector[0] * m_Vector[0] + m_Vector[1] * m_Vector[1] + m_Vector[2] * m_Vector[2]);}
112 
114 
115  inline GLC_Vector2d toVector2d(const GLC_Vector3d& mask) const;
116 
118  inline double angleWithVect(GLC_Vector3d Vect) const;
119 
121  inline double signedAngleWithVect(GLC_Vector3d Vect, const GLC_Vector3d& dir) const;
122 
124  inline GLC_Vector3df toVector3df() const
125  {return GLC_Vector3df(static_cast<float>(m_Vector[0]), static_cast<float>(m_Vector[1]), static_cast<float>(m_Vector[2]));}
126 
128  inline QString toString() const;
129 
131  inline GLC_Vector3d inverted() const
132  {return GLC_Vector3d(*this).invert();}
133 
135 
137 
139 
140 public:
142  inline GLC_Vector3d operator + (const GLC_Vector3d &vector) const
143  {return GLC_Vector3d(m_Vector[0] + vector.m_Vector[0], m_Vector[1] + vector.m_Vector[1], m_Vector[2] + vector.m_Vector[2]);}
144 
146  inline GLC_Vector3d& operator = (const GLC_Vector3d &vector)
147  {
148  if (this != &vector) memcpy(m_Vector, vector.m_Vector, sizeof(double) * 3);
149  return *this;
150  }
151 
153  inline GLC_Vector3d& operator = (const GLC_Vector3df &);
154 
156  inline GLC_Vector3d& operator += (const GLC_Vector3d &vector)
157  {
158  *this= *this + vector;
159  return *this;
160  }
161 
163  inline GLC_Vector3d operator - (const GLC_Vector3d &Vect) const
164  {return GLC_Vector3d(m_Vector[0] - Vect.m_Vector[0], m_Vector[1] - Vect.m_Vector[1], m_Vector[2] - Vect.m_Vector[2]);}
165 
167  GLC_Vector3d& operator -= (const GLC_Vector3d &Vect)
168  {
169  *this= *this - Vect;
170  return *this;
171  }
172 
174  inline GLC_Vector3d operator ^ (const GLC_Vector3d &vector) const;
175 
177  inline double operator * (const GLC_Vector3d &Vect) const
178  {return m_Vector[0] * Vect.m_Vector[0] + m_Vector[1] * Vect.m_Vector[1] + m_Vector[2] * Vect.m_Vector[2];}
179 
181  inline GLC_Vector3d operator * (double Scalaire) const
182  {return GLC_Vector3d(m_Vector[0] * Scalaire, m_Vector[1] * Scalaire, m_Vector[2] * Scalaire);}
183 
184 
186  inline bool operator == (const GLC_Vector3d &vector) const;
187 
189  inline bool operator > (const GLC_Vector3d &vector) const;
190 
192  inline bool operator < (const GLC_Vector3d &vector) const;
193 
195  inline bool operator != (const GLC_Vector3d &Vect) const
196  {return !(*this == Vect);}
197 
199 
201 
203 
204 public:
206  inline GLC_Vector3d& setX(const double &dX)
207  {
208  m_Vector[0]= dX;
209  return *this;
210  }
211 
213  inline GLC_Vector3d& setY(const double &dY)
214  {
215  m_Vector[1]= dY;
216  return *this;
217  }
218 
220  inline GLC_Vector3d& setZ(const double &dZ)
221  {
222  m_Vector[2]= dZ;
223  return *this;
224  }
225 
227  inline GLC_Vector3d& setVect(double, double, double);
228 
230  GLC_Vector3d& setVect(const GLC_Vector3d &vector)
231  {
232  memcpy(m_Vector, vector.m_Vector, sizeof(double) * 3);
233  return *this;
234  }
235 
237  inline GLC_Vector3d& setLength(double lenght);
238 
241  {return setLength(1.0);}
242 
244  inline GLC_Vector3d& invert();
245 
247 
248 
250 //Private attributes
252 private:
258  double m_Vector[3];
259 
260 }; //class GLC_Vector3d
261 
262 // Vector constant in glc namespace
263 namespace glc
264 {
265  // Axis definition
268  const GLC_Vector3d X_AXIS(1.0, 0.0, 0.0);
269 
272  const GLC_Vector3d Y_AXIS(0.0, 1.0, 0.0);
273 
276  const GLC_Vector3d Z_AXIS(0.0, 0.0, 1.0);
277 };
278 
280 typedef GLC_Vector3d GLC_Point3d;
281 
283 inline QDataStream &operator<<(QDataStream & stream, const GLC_Vector3d & vector)
284 {
285  stream << vector.x() << vector.y() << vector.z();
286  return stream;
287 }
288 
290 inline QDataStream &operator>>(QDataStream &stream, GLC_Vector3d &vector)
291 {
292  double x, y, z;
293  stream >> x >> y >> z;
294  vector.setVect(x, y, z);
295  return stream;
296 }
297 
299 inline double getDeterminant3x3(const double *Mat3x3)
300 {
301  double Determinant;
302 
303  Determinant= Mat3x3[0] * ( Mat3x3[4] * Mat3x3[8] - Mat3x3[7] * Mat3x3[5]);
304  Determinant+= - Mat3x3[3] * ( Mat3x3[1] * Mat3x3[8] - Mat3x3[7] * Mat3x3[2]);
305  Determinant+= Mat3x3[6] * ( Mat3x3[1] * Mat3x3[5] - Mat3x3[4] * Mat3x3[2]);
306 
307  return Determinant;
308 }
309 
311 // inline method implementation
313 
315 {
316  m_Vector[0]= 0.0;
317  m_Vector[1]= 0.0;
318  m_Vector[2]= 0.0;
319 }
320 
321 GLC_Vector3d::GLC_Vector3d(double x, double y, double z)
322 {
323  m_Vector[0]= x;
324  m_Vector[1]= y;
325  m_Vector[2]= z;
326 }
327 
329 {
330  m_Vector[0]= static_cast<double>(vector.m_Vector[0]);
331  m_Vector[1]= static_cast<double>(vector.m_Vector[1]);
332  m_Vector[2]= static_cast<double>(vector.m_Vector[2]);
333 }
334 
336 {
337  m_Vector[0]= vector.x();
338  m_Vector[1]= vector.y();
339  m_Vector[2]= 0.0;
340 }
341 
343 {
344  m_Vector[0]= static_cast<double>(Vect.m_Vector[0]);
345  m_Vector[1]= static_cast<double>(Vect.m_Vector[1]);
346  m_Vector[2]= static_cast<double>(Vect.m_Vector[2]);
347 
348  return *this;
349 }
350 
352 {
353  GLC_Vector3d vectResult;
354  vectResult.m_Vector[0]= m_Vector[1] * vector.m_Vector[2] - m_Vector[2] * vector.m_Vector[1];
355  vectResult.m_Vector[1]= m_Vector[2] * vector.m_Vector[0] - m_Vector[0] * vector.m_Vector[2];
356  vectResult.m_Vector[2]= m_Vector[0] * vector.m_Vector[1] - m_Vector[1] * vector.m_Vector[0];
357 
358  return vectResult;
359 }
360 
361 bool GLC_Vector3d::operator == (const GLC_Vector3d &vector) const
362 {
363  bool bResult= qFuzzyCompare(m_Vector[0], vector.m_Vector[0]);
364  bResult= bResult && qFuzzyCompare(m_Vector[1], vector.m_Vector[1]);
365  bResult= bResult && qFuzzyCompare(m_Vector[2], vector.m_Vector[2]);
366 
367  return bResult;
368 }
369 
370 bool GLC_Vector3d::operator > (const GLC_Vector3d &vector) const
371 {
372  bool result= m_Vector[0] > vector.m_Vector[0];
373  result= result && (m_Vector[1] > vector.m_Vector[1]);
374  result= result && (m_Vector[2] > vector.m_Vector[2]);
375  return result;
376 }
377 
378 bool GLC_Vector3d::operator < (const GLC_Vector3d &vector) const
379 {
380  bool result= m_Vector[0] < vector.m_Vector[0];
381  result= result && (m_Vector[1] < vector.m_Vector[1]);
382  result= result && (m_Vector[2] < vector.m_Vector[2]);
383  return result;
384 }
385 
386 GLC_Vector3d& GLC_Vector3d::setVect(double x, double y, double z)
387 {
388  m_Vector[0]= x;
389  m_Vector[1]= y;
390  m_Vector[2]= z;
391 
392  return *this;
393 }
394 
395 inline GLC_Vector3d& GLC_Vector3d::setLength(double lenght)
396 {
397  const double currentLenght= sqrt( m_Vector[0] * m_Vector[0] + m_Vector[1] * m_Vector[1] + m_Vector[2] * m_Vector[2]);
398 
399  if (qAbs(currentLenght) > glc::EPSILON)
400  {
401  const double Coef = lenght / currentLenght;
402 
403  m_Vector[0] = m_Vector[0] * Coef;
404  m_Vector[1] = m_Vector[1] * Coef;
405  m_Vector[2] = m_Vector[2] * Coef;
406  }
407  return *this;
408 }
409 
411 {
412  m_Vector[0]= - m_Vector[0];
413  m_Vector[1]= - m_Vector[1];
414  m_Vector[2]= - m_Vector[2];
415  return *this;
416 }
417 
419 {
420  GLC_Vector2d resultVect;
421  if (mask.m_Vector[0] == 0.0)
422  {
423  resultVect.setX(m_Vector[0]);
424  if (mask.m_Vector[1] == 0.0) resultVect.setY(m_Vector[1]);
425  else resultVect.setY(m_Vector[2]);
426  }
427  else resultVect.setVect(m_Vector[1], m_Vector[2]);
428 
429  return resultVect;
430 }
431 
433 {
434  GLC_Vector3d ThisVect(*this);
435  ThisVect.normalize();
436  Vect.normalize();
437  // Rotation axis
438  const GLC_Vector3d VectAxeRot(ThisVect ^ Vect);
439  // Check if the rotation axis vector is null
440  if (!VectAxeRot.isNull())
441  {
442  return acos(ThisVect * Vect);
443  }
444  else return 0.0;
445 }
446 
448 {
449  double angle= 0.0;
450 
451  GLC_Vector3d ThisVect(*this);
452  ThisVect.normalize();
453  Vect.normalize();
454  if (Vect == ThisVect.inverted())
455  {
456  angle= glc::PI;
457  }
458  else if (Vect != ThisVect)
459  {
460  // Rotation axis
461  const GLC_Vector3d VectAxeRot(ThisVect ^ Vect);
462  // Check if the rotation axis vector is null
463  if (!VectAxeRot.isNull())
464  {
465  double mat3x3[9];
466  mat3x3[0]= ThisVect.m_Vector[0];
467  mat3x3[1]= ThisVect.m_Vector[1];
468  mat3x3[2]= ThisVect.m_Vector[2];
469 
470  mat3x3[3]= Vect.m_Vector[0];
471  mat3x3[4]= Vect.m_Vector[1];
472  mat3x3[5]= Vect.m_Vector[2];
473 
474  mat3x3[6]= dir.m_Vector[0];
475  mat3x3[7]= dir.m_Vector[1];
476  mat3x3[8]= dir.m_Vector[2];
477 
478  double det= getDeterminant3x3(mat3x3);
479 
480  double sign= 1.0;
481  if (det != 0) sign= fabs(det) / det;
482  angle= acos(ThisVect * Vect) * sign;
483  }
484  }
485 
486  return angle;
487 }
488 
489 QString GLC_Vector3d::toString() const
490 {
491  QString result("[");
492 
493  result+= QString::number(m_Vector[0]) + QString(" , ");
494  result+= QString::number(m_Vector[1]) + QString(" , ");
495  result+= QString::number(m_Vector[2]) + QString("]");
496 
497  return result;
498 }
499 
500 #endif /*GLC_VECTOR3D_H_*/

©2005-2013 Laurent Ribon