glc_vector3d.h

Go to the documentation of this file.
00001 /****************************************************************************
00002 
00003  This file is part of the GLC-lib library.
00004  Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net)
00005  http://glc-lib.sourceforge.net
00006 
00007  GLC-lib is free software; you can redistribute it and/or modify
00008  it under the terms of the GNU Lesser General Public License as published by
00009  the Free Software Foundation; either version 3 of the License, or
00010  (at your option) any later version.
00011 
00012  GLC-lib is distributed in the hope that it will be useful,
00013  but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  GNU Lesser General Public License for more details.
00016 
00017  You should have received a copy of the GNU Lesser General Public License
00018  along with GLC-lib; if not, write to the Free Software
00019  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
00020 
00021 *****************************************************************************/
00022 
00024 
00025 #ifndef GLC_VECTOR3D_H_
00026 #define GLC_VECTOR3D_H_
00027 
00028 #include <QDataStream>
00029 
00030 #include "glc_utils_maths.h"
00031 #include "glc_vector3df.h"
00032 #include "glc_vector2d.h"
00033 #include "../glc_config.h"
00034 
00037 
00041 
00042 
00043 class GLC_LIB_EXPORT GLC_Vector3d
00044 {
00045         friend class GLC_Vector4d;
00046         friend class GLC_Matrix4x4;
00047 
00049         inline friend GLC_Vector3d operator - (const GLC_Vector3d &Vect)
00050         {return GLC_Vector3d(-Vect.m_Vector[0], -Vect.m_Vector[1], -Vect.m_Vector[2]);}
00051 
00053         inline friend GLC_Vector3d operator*(double s, const GLC_Vector3d &v)
00054         {return GLC_Vector3d(s * v.m_Vector[0], s * v.m_Vector[1], s * v.m_Vector[2]);}
00055 
00057 
00059 
00060 public:
00062 
00067         inline GLC_Vector3d();
00068 
00070         inline GLC_Vector3d(double x, double y, double z);
00071 
00073         inline GLC_Vector3d(const GLC_Vector3d &vector)
00074         {memcpy(m_Vector, vector.m_Vector, sizeof(double) * 3);}
00075 
00077         inline GLC_Vector3d(const GLC_Vector3df &vector);
00078 
00080         inline GLC_Vector3d(const GLC_Vector2d &vector);
00081 
00083 
00085 
00087 
00088 public:
00090         inline double x() const
00091         {return m_Vector[0];}
00092 
00094         inline double y() const
00095         {return m_Vector[1];}
00096 
00098         inline double z() const
00099         {return m_Vector[2];}
00100 
00102         inline const double *data() const
00103         {return m_Vector;}
00104 
00106         inline bool isNull() const
00107         {return (m_Vector[0] == 0.0f) && (m_Vector[1] == 0.0f) && (m_Vector[2] == 0.0f);}
00108 
00110         inline double length() const
00111         {return sqrt(m_Vector[0] * m_Vector[0] + m_Vector[1] * m_Vector[1] + m_Vector[2] * m_Vector[2]);}
00112 
00114 
00115         inline GLC_Vector2d toVector2d(const GLC_Vector3d& mask) const;
00116 
00118         inline double angleWithVect(GLC_Vector3d Vect) const;
00119 
00121         inline double signedAngleWithVect(GLC_Vector3d Vect, const GLC_Vector3d& dir) const;
00122 
00124         inline GLC_Vector3df toVector3df() const
00125         {return GLC_Vector3df(static_cast<float>(m_Vector[0]), static_cast<float>(m_Vector[1]), static_cast<float>(m_Vector[2]));}
00126 
00128         inline QString toString() const;
00129 
00131         inline GLC_Vector3d inverted() const
00132         {return GLC_Vector3d(*this).invert();}
00133 
00135 
00137 
00139 
00140 public:
00142         inline GLC_Vector3d operator + (const GLC_Vector3d &vector) const
00143         {return GLC_Vector3d(m_Vector[0] + vector.m_Vector[0], m_Vector[1] + vector.m_Vector[1], m_Vector[2] + vector.m_Vector[2]);}
00144 
00146         inline GLC_Vector3d& operator = (const GLC_Vector3d &vector)
00147         {
00148                 if (this != &vector) memcpy(m_Vector, vector.m_Vector, sizeof(double) * 3);
00149                 return *this;
00150         }
00151 
00153         inline GLC_Vector3d& operator = (const GLC_Vector3df &);
00154 
00156         inline GLC_Vector3d& operator += (const GLC_Vector3d &vector)
00157         {
00158                 *this= *this + vector;
00159                 return *this;
00160         }
00161 
00163         inline GLC_Vector3d operator - (const GLC_Vector3d &Vect) const
00164         {return GLC_Vector3d(m_Vector[0] - Vect.m_Vector[0], m_Vector[1] - Vect.m_Vector[1], m_Vector[2] - Vect.m_Vector[2]);}
00165 
00167         GLC_Vector3d& operator -= (const GLC_Vector3d &Vect)
00168         {
00169                 *this= *this - Vect;
00170                 return *this;
00171         }
00172 
00174         inline GLC_Vector3d operator ^ (const GLC_Vector3d &vector) const;
00175 
00177         inline double operator * (const GLC_Vector3d &Vect) const
00178         {return m_Vector[0] * Vect.m_Vector[0] + m_Vector[1] * Vect.m_Vector[1] + m_Vector[2] * Vect.m_Vector[2];}
00179 
00181         inline GLC_Vector3d operator * (double Scalaire) const
00182         {return GLC_Vector3d(m_Vector[0] * Scalaire, m_Vector[1] * Scalaire, m_Vector[2] * Scalaire);}
00183 
00184 
00186         inline bool operator == (const GLC_Vector3d &vector) const;
00187 
00189         inline bool operator > (const GLC_Vector3d &vector) const;
00190 
00192         inline bool operator < (const GLC_Vector3d &vector) const;
00193 
00195         inline bool operator != (const GLC_Vector3d &Vect) const
00196         {return !(*this == Vect);}
00197 
00199 
00201 
00203 
00204 public:
00206         inline GLC_Vector3d& setX(const double &dX)
00207         {
00208                 m_Vector[0]= dX;
00209                 return *this;
00210         }
00211 
00213         inline GLC_Vector3d& setY(const double &dY)
00214         {
00215                 m_Vector[1]= dY;
00216                 return *this;
00217         }
00218 
00220         inline GLC_Vector3d& setZ(const double &dZ)
00221         {
00222                 m_Vector[2]= dZ;
00223                 return *this;
00224         }
00225 
00227         inline GLC_Vector3d& setVect(double, double, double);
00228 
00230         GLC_Vector3d& setVect(const GLC_Vector3d &vector)
00231         {
00232                 memcpy(m_Vector, vector.m_Vector, sizeof(double) * 3);
00233                 return *this;
00234         }
00235 
00237         inline GLC_Vector3d& setLength(double);
00238 
00240         inline GLC_Vector3d& normalize()
00241         {return setLength(1.0);}
00242 
00244         inline GLC_Vector3d& invert();
00245 
00247 
00248 
00250 //Private attributes
00252 private:
00258         double m_Vector[3];
00259 
00260 }; //class GLC_Vector3d
00261 
00262 // Vector constant in glc namespace
00263 namespace glc
00264 {
00265         // Axis definition
00268         const GLC_Vector3d X_AXIS(1.0, 0.0, 0.0);
00269 
00272         const GLC_Vector3d Y_AXIS(0.0, 1.0, 0.0);
00273 
00276         const GLC_Vector3d Z_AXIS(0.0, 0.0, 1.0);
00277 };
00278 
00280 typedef GLC_Vector3d GLC_Point3d;
00281 
00283 inline QDataStream &operator<<(QDataStream & stream, const GLC_Vector3d & vector)
00284 {
00285         stream << vector.x() << vector.y() << vector.z();
00286         return stream;
00287 }
00288 
00290 inline QDataStream &operator>>(QDataStream &stream, GLC_Vector3d &vector)
00291 {
00292         double x, y, z;
00293         stream >> x >> y >> z;
00294         vector.setVect(x, y, z);
00295         return stream;
00296 }
00297 
00299 inline double getDeterminant3x3(const double *Mat3x3)
00300 {
00301         double Determinant;
00302 
00303         Determinant= Mat3x3[0] * ( Mat3x3[4] * Mat3x3[8] - Mat3x3[7] * Mat3x3[5]);
00304         Determinant+= - Mat3x3[3] * ( Mat3x3[1] * Mat3x3[8] - Mat3x3[7] * Mat3x3[2]);
00305         Determinant+= Mat3x3[6] * ( Mat3x3[1] * Mat3x3[5] - Mat3x3[4] * Mat3x3[2]);
00306 
00307         return Determinant;
00308 }
00309 
00311 // inline method implementation
00313 
00314 GLC_Vector3d::GLC_Vector3d()
00315 {
00316         m_Vector[0]= 0.0;
00317         m_Vector[1]= 0.0;
00318         m_Vector[2]= 0.0;
00319 }
00320 
00321 GLC_Vector3d::GLC_Vector3d(double x, double y, double z)
00322 {
00323         m_Vector[0]= x;
00324         m_Vector[1]= y;
00325         m_Vector[2]= z;
00326 }
00327 
00328 GLC_Vector3d::GLC_Vector3d(const GLC_Vector3df &vector)
00329 {
00330         m_Vector[0]= static_cast<double>(vector.m_Vector[0]);
00331         m_Vector[1]= static_cast<double>(vector.m_Vector[1]);
00332         m_Vector[2]= static_cast<double>(vector.m_Vector[2]);
00333 }
00334 
00335 GLC_Vector3d::GLC_Vector3d(const GLC_Vector2d &vector)
00336 {
00337         m_Vector[0]= vector.getX();
00338         m_Vector[1]= vector.getY();
00339         m_Vector[2]= 0.0;
00340 }
00341 
00342 GLC_Vector3d& GLC_Vector3d::operator = (const GLC_Vector3df &Vect)
00343 {
00344         m_Vector[0]= static_cast<double>(Vect.m_Vector[0]);
00345         m_Vector[1]= static_cast<double>(Vect.m_Vector[1]);
00346         m_Vector[2]= static_cast<double>(Vect.m_Vector[2]);
00347 
00348         return *this;
00349 }
00350 
00351 GLC_Vector3d GLC_Vector3d::operator ^ (const GLC_Vector3d &vector) const
00352 {
00353         GLC_Vector3d vectResult;
00354         vectResult.m_Vector[0]= m_Vector[1] * vector.m_Vector[2] - m_Vector[2] * vector.m_Vector[1];
00355         vectResult.m_Vector[1]= m_Vector[2] * vector.m_Vector[0] - m_Vector[0] * vector.m_Vector[2];
00356         vectResult.m_Vector[2]= m_Vector[0] * vector.m_Vector[1] - m_Vector[1] * vector.m_Vector[0];
00357 
00358         return vectResult;
00359 }
00360 
00361 bool GLC_Vector3d::operator == (const GLC_Vector3d &vector) const
00362 {
00363         bool bResult= qFuzzyCompare(m_Vector[0], vector.m_Vector[0]);
00364         bResult= bResult && qFuzzyCompare(m_Vector[1], vector.m_Vector[1]);
00365         bResult= bResult && qFuzzyCompare(m_Vector[2], vector.m_Vector[2]);
00366 
00367         return bResult;
00368 }
00369 
00370 bool GLC_Vector3d::operator > (const GLC_Vector3d &vector) const
00371 {
00372         bool result= m_Vector[0] > vector.m_Vector[0];
00373         result= result && (m_Vector[1] > vector.m_Vector[1]);
00374         result= result && (m_Vector[2] > vector.m_Vector[2]);
00375         return result;
00376 }
00377 
00378 bool GLC_Vector3d::operator < (const GLC_Vector3d &vector) const
00379 {
00380         bool result= m_Vector[0] < vector.m_Vector[0];
00381         result= result && (m_Vector[1] < vector.m_Vector[1]);
00382         result= result && (m_Vector[2] < vector.m_Vector[2]);
00383         return result;
00384 }
00385 
00386 GLC_Vector3d& GLC_Vector3d::setVect(double x, double y, double z)
00387 {
00388         m_Vector[0]= x;
00389         m_Vector[1]= y;
00390         m_Vector[2]= z;
00391 
00392         return *this;
00393 }
00394 
00395 inline GLC_Vector3d& GLC_Vector3d::setLength(double norme)
00396 {
00397         const double normCur= sqrt( m_Vector[0] * m_Vector[0] + m_Vector[1] * m_Vector[1] + m_Vector[2] * m_Vector[2]);
00398 
00399         if (normCur != 0.0f)
00400         {
00401                 const double Coef = norme / normCur;
00402 
00403                 m_Vector[0] = m_Vector[0] * Coef;
00404                 m_Vector[1] = m_Vector[1] * Coef;
00405                 m_Vector[2] = m_Vector[2] * Coef;
00406         }
00407         return *this;
00408 }
00409 
00410 GLC_Vector3d& GLC_Vector3d::invert()
00411 {
00412         m_Vector[0]= - m_Vector[0];
00413         m_Vector[1]= - m_Vector[1];
00414         m_Vector[2]= - m_Vector[2];
00415         return *this;
00416 }
00417 
00418 GLC_Vector2d GLC_Vector3d::toVector2d(const GLC_Vector3d& mask) const
00419 {
00420         GLC_Vector2d resultVect;
00421         if (mask.m_Vector[0] == 0.0)
00422         {
00423                 resultVect.setX(m_Vector[0]);
00424                 if (mask.m_Vector[1] == 0.0) resultVect.setY(m_Vector[1]);
00425                 else resultVect.setY(m_Vector[2]);
00426         }
00427         else resultVect.setVect(m_Vector[1], m_Vector[2]);
00428 
00429         return resultVect;
00430 }
00431 
00432 double GLC_Vector3d::angleWithVect(GLC_Vector3d Vect) const
00433 {
00434         GLC_Vector3d ThisVect(*this);
00435         ThisVect.normalize();
00436         Vect.normalize();
00437         // Rotation axis
00438         const GLC_Vector3d VectAxeRot(ThisVect ^ Vect);
00439         // Check if the rotation axis vector is null
00440         if (!VectAxeRot.isNull())
00441         {
00442                 return acos(ThisVect * Vect);
00443         }
00444         else return 0.0;
00445 }
00446 
00447 double GLC_Vector3d::signedAngleWithVect(GLC_Vector3d Vect, const GLC_Vector3d& dir) const
00448 {
00449         double angle= 0.0;
00450 
00451         GLC_Vector3d ThisVect(*this);
00452         ThisVect.normalize();
00453         Vect.normalize();
00454         if (Vect == ThisVect.inverted())
00455         {
00456                 angle= glc::PI;
00457         }
00458         else if (Vect != ThisVect)
00459         {
00460                 // Rotation axis
00461                 const GLC_Vector3d VectAxeRot(ThisVect ^ Vect);
00462                 // Check if the rotation axis vector is null
00463                 if (!VectAxeRot.isNull())
00464                 {
00465                         double mat3x3[9];
00466                         mat3x3[0]= ThisVect.m_Vector[0];
00467                         mat3x3[1]= ThisVect.m_Vector[1];
00468                         mat3x3[2]= ThisVect.m_Vector[2];
00469 
00470                         mat3x3[3]= Vect.m_Vector[0];
00471                         mat3x3[4]= Vect.m_Vector[1];
00472                         mat3x3[5]= Vect.m_Vector[2];
00473 
00474                         mat3x3[6]= dir.m_Vector[0];
00475                         mat3x3[7]= dir.m_Vector[1];
00476                         mat3x3[8]= dir.m_Vector[2];
00477 
00478                         double det= getDeterminant3x3(mat3x3);
00479 
00480                         double sign= 1.0;
00481                         if (det != 0) sign= fabs(det) / det;
00482                         angle= acos(ThisVect * Vect) * sign;
00483                 }
00484         }
00485 
00486         return angle;
00487 }
00488 
00489 QString GLC_Vector3d::toString() const
00490 {
00491         QString result("[");
00492 
00493         result+= QString::number(m_Vector[0]) + QString(" , ");
00494         result+= QString::number(m_Vector[1]) + QString(" , ");
00495         result+= QString::number(m_Vector[2]) + QString("]");
00496 
00497         return result;
00498 }
00499 
00500 #endif /*GLC_VECTOR3D_H_*/

SourceForge.net Logo

©2005-2011 Laurent Ribon