Tulip  4.6.0
Better Visualization Through Research
library/tulip-core/include/tulip/Vector.h
00001 /*
00002  *
00003  * This file is part of Tulip (www.tulip-software.org)
00004  *
00005  * Authors: David Auber and the Tulip development Team
00006  * from LaBRI, University of Bordeaux
00007  *
00008  * Tulip is free software; you can redistribute it and/or modify
00009  * it under the terms of the GNU Lesser General Public License
00010  * as published by the Free Software Foundation, either version 3
00011  * of the License, or (at your option) any later version.
00012  *
00013  * Tulip is distributed in the hope that it will be useful,
00014  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00016  * See the GNU General Public License for more details.
00017  *
00018  */
00019 ///@cond DOXYGEN_HIDDEN
00020 
00021 //@TLPGEOLICENCE#
00022 
00023 #ifndef _TLP_VECTOR_H
00024 #define _TLP_VECTOR_H
00025 
00026 #include <cassert>
00027 #include <tulip/Array.h>
00028 #include <tulip/tuliphash.h>
00029 #include <cmath>
00030 #include <limits>
00031 #include <cstring>
00032 
00033 #define VECTOR Vector<TYPE,SIZE,OTYPE,DTYPE>
00034 #define TEMPLATEVECTOR template <typename TYPE, unsigned int SIZE, typename OTYPE, typename DTYPE>
00035 
00036 namespace tlp {
00037 
00038 template<typename TYPE, typename OTYPE>
00039 inline OTYPE tlpsqr(const TYPE a) {
00040   return static_cast<OTYPE>(a) * static_cast<OTYPE>(a);
00041 }
00042 
00043 template<typename TYPE, typename OTYPE>
00044 inline TYPE tlpsqrt(const OTYPE a) {
00045   return static_cast<TYPE>(sqrt(a));
00046 }
00047 
00048 template<>
00049 inline double tlpsqrt<double, long double>(long double a) {
00050   return static_cast<double>(sqrtl(a));
00051 }
00052 
00053 
00054 /**
00055  * @ingroup Structures
00056  * \brief class for mathematical vector
00057  *
00058  * Enables to create a Vector of TYPE (must be a numeric basic type) with a
00059  * fixed size and provides Mathematical operation. Mathematical
00060  * operators must be defined for TYPE. Out of bound accesses are only checked
00061  * in debug mode. The OTYPE is used for temporary computation to prevent overflow,
00062  * by default OTYPE is a double.
00063  *
00064  * \author : David Auber auber@tulip-software.org
00065  * \version 0.0.1 24/01/2003
00066  */
00067 template <typename TYPE, unsigned int SIZE, typename OTYPE = double, typename DTYPE = TYPE>
00068 class Vector:public Array<TYPE,SIZE> {
00069 public:
00070   inline VECTOR() {
00071     memset( &((*this)[0]), 0, SIZE * sizeof(TYPE) );
00072   }
00073   inline VECTOR(const Vector<TYPE, SIZE, OTYPE> &v) {
00074     set(v);
00075   }
00076 
00077   inline VECTOR(const Vector<TYPE, SIZE + 1, OTYPE> &v) {
00078     set(v);
00079   }
00080 
00081   explicit inline VECTOR(const TYPE x) {
00082     fill(x);
00083     /*
00084     if (int(SIZE) - 1 > 0)
00085         memset( &((*this)[1]), 0, (SIZE - 1) * sizeof(TYPE) );
00086     set(x);
00087     */
00088   }
00089 
00090   explicit inline VECTOR(const TYPE x, const TYPE y) {
00091     if (int(SIZE) - 2 > 0)
00092       memset( &((*this)[2]), 0, (SIZE - 2) * sizeof(TYPE) );
00093 
00094     set(x,y);
00095   }
00096 
00097   explicit inline VECTOR(const TYPE x, const TYPE y, const TYPE z) {
00098     if (int(SIZE) - 3 > 0)
00099       memset( &((*this)[3]), 0, (SIZE - 3) * sizeof(TYPE) );
00100 
00101     set(x, y, z);
00102   }
00103   explicit inline VECTOR(const Vector<TYPE, 2, OTYPE> &v, const TYPE z) {
00104     set(v, z);
00105   }
00106   explicit inline VECTOR(const TYPE x, const TYPE y, const TYPE z, const TYPE w) {
00107     set(x, y, z, w);
00108   }
00109   explicit inline VECTOR(const Vector<TYPE, 2, OTYPE> &v, const TYPE z, const TYPE w) {
00110     set(v, z, w);
00111   }
00112   explicit inline VECTOR(const Vector<TYPE, 3, OTYPE> &v, const TYPE w) {
00113     set(v, w);
00114   }
00115 
00116   inline void set(const TYPE x) {
00117     (*this)[0] = x;
00118   }
00119   inline void set(const TYPE x, const TYPE y) {
00120     assert(SIZE>1);
00121     (*this)[0] = x;
00122     (*this)[1] = y;
00123   }
00124   inline void set(const TYPE x, const TYPE y, const TYPE z) {
00125     assert(SIZE>2);
00126     (*this)[0] = x;
00127     (*this)[1] = y;
00128     (*this)[2] = z;
00129   }
00130   inline void set(const TYPE x, const TYPE y, const TYPE z, const TYPE w) {
00131     assert(SIZE>3);
00132     (*this)[0] = x;
00133     (*this)[1] = y;
00134     (*this)[2] = z;
00135     (*this)[3] = w;
00136   }
00137   inline void set(const Vector<TYPE, 2, OTYPE> &v, const TYPE z) {
00138     assert(SIZE>2);
00139     memcpy( &((*this)[0]), (void*)&(v.array[0]), 2 * sizeof(TYPE) );
00140     (*this)[2] = z;
00141   }
00142   inline void set(const Vector<TYPE, 2, OTYPE> &v, const TYPE z, const TYPE w) {
00143     assert(SIZE>3);
00144     memcpy( &((*this)[0]), (void*)&(v.array[0]), 2 * sizeof(TYPE) );
00145     (*this)[2] = z;
00146     (*this)[3] = w;
00147   }
00148   inline void set(const Vector<TYPE, 3, OTYPE> &v, const TYPE w) {
00149     assert(SIZE>3);
00150     memcpy( &((*this)[0]), (void*)&(v.array[0]), 3 * sizeof(TYPE) );
00151     (*this)[3] = w;
00152   }
00153   inline void set(const Vector<TYPE, SIZE, OTYPE> &v) {
00154     memcpy(&((*this)[0]), (void*)&(v.array[0]), SIZE * sizeof(TYPE) );
00155   }
00156   inline void set(const Vector<TYPE, SIZE + 1, OTYPE> &v) {
00157     memcpy(&((*this)[0]), &(v.array[0]), SIZE * sizeof(TYPE) );
00158   }
00159   inline void get(TYPE &x) const {
00160     x = (*this)[0];
00161   }
00162   inline void get(TYPE &x,TYPE &y) const {
00163     assert(SIZE>1);
00164     x = (*this)[0];
00165     y = (*this)[1];
00166   }
00167   inline void get(TYPE &x,TYPE &y,TYPE &z) const {
00168     assert(SIZE>2);
00169     x = (*this)[0];
00170     y = (*this)[1];
00171     z = (*this)[2];
00172   }
00173   inline void get(TYPE &x,TYPE &y,TYPE &z,TYPE &w) const {
00174     assert(SIZE>3);
00175     x = (*this)[0];
00176     y = (*this)[1];
00177     z = (*this)[2];
00178     w = (*this)[3];
00179   }
00180 
00181   //convenient accessor for coordinates
00182   inline TYPE x() const {
00183     return (*this)[0];
00184   }
00185   inline TYPE y() const {
00186     assert(SIZE>1);
00187     return (*this)[1];
00188   }
00189   inline TYPE z() const {
00190     assert(SIZE>2);
00191     return (*this)[2];
00192   }
00193   inline TYPE w() const {
00194     assert(SIZE>3);
00195     return (*this)[3];
00196   }
00197 
00198   inline TYPE& x() {
00199     return (*this)[0];
00200   }
00201   inline TYPE& y() {
00202     assert(SIZE>1);
00203     return (*this)[1];
00204   }
00205   inline TYPE& z() {
00206     assert(SIZE>2);
00207     return (*this)[2];
00208   }
00209   inline TYPE& w() {
00210     assert(SIZE>3);
00211     return (*this)[3];
00212   }
00213 
00214   inline TYPE width()  const {
00215     return x();
00216   }
00217   inline TYPE height() const {
00218     return y();
00219   }
00220   inline TYPE depth()  const {
00221     return z();
00222   }
00223 
00224   inline TYPE& width()  {
00225     return x();
00226   }
00227   inline TYPE& height() {
00228     return y();
00229   }
00230   inline TYPE& depth()  {
00231     return z();
00232   }
00233 
00234   inline TYPE r() const {
00235     return x();
00236   }
00237   inline TYPE g() const {
00238     return y();
00239   }
00240   inline TYPE b() const {
00241     return z();
00242   }
00243   inline TYPE a() const {
00244     return w();
00245   }
00246 
00247   inline TYPE& r() {
00248     return x();
00249   }
00250   inline TYPE& g() {
00251     return y();
00252   }
00253   inline TYPE& b() {
00254     return z();
00255   }
00256   inline TYPE& a() {
00257     return w();
00258   }
00259 
00260   inline TYPE s() const {
00261     return x();
00262   }
00263   inline TYPE t() const {
00264     return y();
00265   }
00266   inline TYPE p() const {
00267     return z();
00268   }
00269   inline TYPE q() const {
00270     return w();
00271   }
00272 
00273   inline TYPE& s() {
00274     return x();
00275   }
00276   inline TYPE& t() {
00277     return y();
00278   }
00279   inline TYPE& p() {
00280     return z();
00281   }
00282   inline TYPE& q() {
00283     return w();
00284   }
00285 
00286   inline void setX(TYPE xx) {
00287     x() = xx;
00288   }
00289   inline void setY(TYPE yy) {
00290     y() = yy;
00291   }
00292   inline void setZ(TYPE zz) {
00293     z() = zz;
00294   }
00295 
00296   inline TYPE getX() const {
00297     return x();
00298   }
00299   inline TYPE getY() const {
00300     return y();
00301   }
00302   inline TYPE getZ() const {
00303     return z();
00304   }
00305 
00306   inline void setW(const TYPE width) {
00307     x() = width;
00308   }
00309 
00310   inline void setH(const TYPE height) {
00311     y() = height;
00312   }
00313 
00314   inline void setD(const TYPE depth) {
00315     z() = depth;
00316   }
00317 
00318   inline TYPE getW() const {
00319     return x();
00320   }
00321   inline TYPE getH() const {
00322     return y();
00323   }
00324   inline TYPE getD() const {
00325     return z();
00326   }
00327 
00328 
00329 
00330 //    inline VECTOR & operator*=(const OTYPE );
00331   inline VECTOR & operator*=(const TYPE );
00332   inline VECTOR & operator*=(const VECTOR &);
00333 //    inline VECTOR & operator/=(const OTYPE );
00334   inline VECTOR & operator/=(const TYPE );
00335   inline VECTOR & operator/=(const VECTOR &);
00336 //    inline VECTOR & operator+=(const OTYPE );
00337   inline VECTOR & operator+=(const TYPE );
00338   inline VECTOR & operator+=(const VECTOR &);
00339 //    inline VECTOR & operator-=(const OTYPE );
00340   inline VECTOR & operator-=(const TYPE );
00341   inline VECTOR & operator-=(const VECTOR &);
00342   inline VECTOR & operator^=(const VECTOR &);
00343 
00344   inline bool operator>(const VECTOR &) const;
00345   inline bool operator<(const VECTOR &) const;
00346   inline bool operator!=(const VECTOR &) const;
00347   inline bool operator==(const VECTOR &) const;
00348   inline VECTOR & fill(const TYPE obj);
00349   inline TYPE norm () const;
00350   inline TYPE length () const {
00351     return norm();
00352   }
00353   inline VECTOR & normalize () {
00354     OTYPE tmp = 0;
00355 
00356     for (unsigned int i=0; i<SIZE; ++i)
00357       tmp += tlpsqr<TYPE, OTYPE>((*this)[i]);
00358 
00359     if (tmp < sqrt(std::numeric_limits<TYPE>::epsilon())) {
00360       return *this;
00361     }
00362 
00363     for (unsigned int i=0; i<SIZE; ++i) {
00364       if ((*this)[i] < 0.)
00365         (*this)[i] = -tlpsqrt<TYPE, OTYPE>(tlpsqr<TYPE, OTYPE>((*this)[i]) / tmp);
00366       else
00367         (*this)[i] = tlpsqrt<TYPE, OTYPE>(tlpsqr<TYPE, OTYPE>((*this)[i]) / tmp);
00368     }
00369 
00370     return *this;
00371   }
00372   inline DTYPE dist (const VECTOR &) const;
00373   inline TYPE dotProduct(const VECTOR &) const;
00374 };
00375 
00376 TEMPLATEVECTOR
00377 inline TYPE dotProduct(const VECTOR &a, const VECTOR &b) {
00378   return a.dotProduct(b);
00379 }
00380 
00381 TEMPLATEVECTOR
00382 inline TYPE dist(const VECTOR &a, const VECTOR &b) {
00383   return a.dist(b);
00384 }
00385 
00386 
00387 /**
00388   * Return the minimun of each dimension of the two vectors
00389   * for instance for a 2 vectors of dim 2 :
00390   * min(V1, V2) = (min(V1[0], v2[0]), min(V1[1], v2[1))
00391   */
00392 TEMPLATEVECTOR
00393 inline VECTOR minVector(const VECTOR &u, const VECTOR &v) {
00394   VECTOR tmp;
00395 
00396   for(unsigned int i = 0; i<SIZE; ++i)
00397     tmp[i] = std::min(u[i], v[i]);
00398 
00399   return tmp;
00400 }
00401 /**
00402   * Return the maximum of each dimension of the two vectors
00403   * for instance for a 2 vectors of dim 2 :
00404   * max(V1, V2) = (max(V1[0], v2[0]), max(V1[1], v2[1))
00405   */
00406 TEMPLATEVECTOR
00407 inline VECTOR maxVector(const VECTOR &u, const VECTOR &v)  {
00408   VECTOR tmp;
00409 
00410   for(unsigned int i = 0; i<SIZE; ++i)
00411     tmp[i] = std::max(u[i], v[i]);
00412 
00413   return tmp;
00414 }
00415 
00416 TEMPLATEVECTOR
00417 inline VECTOR operator*(const VECTOR &, const VECTOR &);
00418 TEMPLATEVECTOR
00419 inline VECTOR operator*(const TYPE  , const VECTOR &);
00420 TEMPLATEVECTOR
00421 inline VECTOR operator*(const VECTOR &, const TYPE );
00422 
00423 //TEMPLATEVECTOR
00424 //inline VECTOR operator*(const OTYPE  , const VECTOR &);
00425 //TEMPLATEVECTOR
00426 //inline VECTOR operator*(const VECTOR &, const OTYPE );
00427 
00428 TEMPLATEVECTOR
00429 inline VECTOR operator+(const VECTOR &, const VECTOR &);
00430 TEMPLATEVECTOR
00431 inline VECTOR operator+(const VECTOR &, const TYPE );
00432 //TEMPLATEVECTOR
00433 //inline VECTOR operator+(const VECTOR &, const OTYPE );
00434 
00435 TEMPLATEVECTOR
00436 inline VECTOR operator-(const VECTOR &, const VECTOR &);
00437 TEMPLATEVECTOR
00438 inline VECTOR operator-(const VECTOR &, const TYPE );
00439 //TEMPLATEVECTOR
00440 //inline VECTOR operator-(const VECTOR &, const OTYPE );
00441 
00442 TEMPLATEVECTOR
00443 inline VECTOR operator/(const VECTOR &, const VECTOR &);
00444 TEMPLATEVECTOR
00445 inline VECTOR operator/(const VECTOR &, const TYPE );
00446 //TEMPLATEVECTOR
00447 //inline VECTOR operator/(const VECTOR &, const OTYPE );
00448 
00449 TEMPLATEVECTOR
00450 inline VECTOR operator^(const VECTOR &, const VECTOR &);
00451 TEMPLATEVECTOR
00452 inline VECTOR operator-(const VECTOR&);
00453 /**
00454   * @brief typedef for 2D vector of unsigned int
00455   */
00456 typedef Vector<unsigned int, 2> Vec2ui;
00457 /**
00458   * @brief typedef for 3D vector of unsigned int
00459   */
00460 typedef Vector<unsigned int, 3> Vec3ui;
00461 /**
00462   * @brief typedef for 4D vector of unsigned int
00463   */
00464 typedef Vector<unsigned int, 4> Vec4ui;
00465 /**
00466   * @brief typedef for 2D vector of int
00467   */
00468 typedef Vector<int, 2> Vec2i;
00469 /**
00470   * @brief typedef for 3D vector of int
00471   */
00472 typedef Vector<int, 3> Vec3i;
00473 /**
00474   * @brief typedef for 4D vector of int
00475   */
00476 typedef Vector<int, 4> Vec4i;
00477 /**
00478   * @brief typedef for 2D vector of double
00479   */
00480 typedef Vector<double, 2, long double> Vec2d;
00481 /**
00482   * @brief typedef for 3D vector of double
00483   */
00484 typedef Vector<double, 3, long double> Vec3d;
00485 /**
00486   * @brief typedef for 4D vector of double
00487   */
00488 typedef Vector<double, 4, long double> Vec4d;
00489 /**
00490   * @brief typedef for 2D vector of float
00491   */
00492 typedef Vector<float,  2, double> Vec2f;
00493 /**
00494   * @brief typedef for 3D vector of float
00495   */
00496 typedef Vector<float,  3, double> Vec3f;
00497 /**
00498   * @brief typedef for 4D vector of float
00499   */
00500 typedef Vector<float,  4, double> Vec4f;
00501 }
00502 
00503 #ifdef _MSC_VER
00504 //template<unsigned int SIZE>
00505 static double sqrt(tlp::Vector<float, 5>& v) {
00506   return sqrt((double)v[0]);
00507 }
00508 
00509 template class TLP_SCOPE tlp::Vector<unsigned char, 4>;
00510 
00511 #endif
00512 
00513 TLP_BEGIN_HASH_NAMESPACE {
00514   TEMPLATEVECTOR
00515   size_t hash_vector(const tlp::VECTOR &v) {
00516     size_t seed = 0;
00517 
00518     for (unsigned int i = 0 ; i < SIZE ; ++i) {
00519       hash_combine(seed, v[i]);
00520     }
00521 
00522     return seed;
00523   }
00524 
00525   template <>
00526   struct hash<tlp::Vec2ui> {
00527     inline std::size_t operator()(const tlp::Vec2ui &v) const {
00528       return hash_vector(v);
00529     }
00530   };
00531 
00532   template <>
00533   struct hash<tlp::Vec3ui> {
00534     inline std::size_t operator()(const tlp::Vec3ui &v) const {
00535       return hash_vector(v);
00536     }
00537   };
00538 
00539   template <>
00540   struct hash<tlp::Vec4ui> {
00541     inline std::size_t operator()(const tlp::Vec4ui &v) const {
00542       return hash_vector(v);
00543     }
00544   };
00545 
00546   template <>
00547   struct hash<tlp::Vec2i> {
00548     inline std::size_t operator()(const tlp::Vec2i &v) const {
00549       return hash_vector(v);
00550     }
00551   };
00552 
00553   template <>
00554   struct hash<tlp::Vec3i> {
00555     inline std::size_t operator()(const tlp::Vec3i &v) const {
00556       return hash_vector(v);
00557     }
00558   };
00559 
00560   template <>
00561   struct hash<tlp::Vec4i> {
00562     inline std::size_t operator()(const tlp::Vec4i &v) const {
00563       return hash_vector(v);
00564     }
00565   };
00566 
00567   template <>
00568   struct hash<tlp::Vec2d> {
00569     inline std::size_t operator()(const tlp::Vec2d &v) const {
00570       return hash_vector(v);
00571     }
00572   };
00573 
00574   template <>
00575   struct hash<tlp::Vec3d> {
00576     inline std::size_t operator()(const tlp::Vec3f &v) const {
00577       return hash_vector(v);
00578     }
00579   };
00580 
00581   template <>
00582   struct hash<tlp::Vec4d> {
00583     inline std::size_t operator()(const tlp::Vec4d &v) const {
00584       return hash_vector(v);
00585     }
00586   };
00587 
00588   template <>
00589   struct hash<tlp::Vec2f> {
00590     inline std::size_t operator()(const tlp::Vec2f &v) const {
00591       return hash_vector(v);
00592     }
00593   };
00594 
00595   template <>
00596   struct hash<tlp::Vec3f> {
00597     inline std::size_t operator()(const tlp::Vec3f &v) const {
00598       return hash_vector(v);
00599     }
00600   };
00601 
00602   template <>
00603   struct hash<tlp::Vec4f> {
00604     inline std::size_t operator()(const tlp::Vec4f &v) const {
00605       return hash_vector(v);
00606     }
00607   };
00608 
00609 
00610 } TLP_END_HASH_NAMESPACE
00611 
00612 #include "cxx/Vector.cxx"
00613 
00614 // fix for bug #3598871: allow use of VECTOR keyword in other software
00615 #undef VECTOR
00616 #undef TEMPLATEVECTOR
00617 
00618 #endif
00619 ///@endcond
 All Classes Files Functions Variables Enumerations Enumerator Properties