![]() |
Tulip
4.6.0
Better Visualization Through Research
|
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