Blender V2.61 - r43446
|
00001 00004 /****************************************************************************** 00005 * Copyright 2007 Nils Thuerey 00006 * Basic vector class 00007 *****************************************************************************/ 00008 #ifndef BASICVECTOR_H 00009 #define BASICVECTOR_H 00010 00011 #include <math.h> 00012 #include <stdlib.h> 00013 #include <stdio.h> 00014 #include <iostream> 00015 #include <sstream> 00016 00017 // use which fp-precision? 1=float, 2=double 00018 #ifndef FLOATINGPOINT_PRECISION 00019 #if DDF_DEBUG==1 00020 #define FLOATINGPOINT_PRECISION 2 00021 #else // DDF_DEBUG==1 00022 #define FLOATINGPOINT_PRECISION 1 00023 #endif // DDF_DEBUG==1 00024 #endif 00025 00026 // VECTOR_EPSILON is the minimal vector length 00027 // In order to be able to discriminate floating point values near zero, and 00028 // to be sure not to fail a comparison because of roundoff errors, use this 00029 // value as a threshold. 00030 00031 #if FLOATINGPOINT_PRECISION==1 00032 typedef float Real; 00033 #define FP_REAL_MAX __FLT_MAX__ 00034 #define VECTOR_EPSILON (1e-5f) 00035 #else 00036 typedef double Real; 00037 #define FP_REAL_MAX __DBL_MAX__ 00038 #define VECTOR_EPSILON (1e-10) 00039 #endif 00040 00041 00042 // hardcoded limits for now... 00043 // for e.g. MSVC compiler... 00044 // some of these defines can be needed 00045 // for linux systems as well (e.g. FLT_MAX) 00046 #ifndef __FLT_MAX__ 00047 # ifdef FLT_MAX // try to use it instead 00048 # define __FLT_MAX__ FLT_MAX 00049 # else // FLT_MAX 00050 # define __FLT_MAX__ 3.402823466e+38f 00051 # endif // FLT_MAX 00052 #endif // __FLT_MAX__ 00053 #ifndef __DBL_MAX__ 00054 # ifdef DBL_MAX // try to use it instead 00055 # define __DBL_MAX__ DBL_MAX 00056 # else // DBL_MAX 00057 # define __DBL_MAX__ 1.7976931348623158e+308 00058 # endif // DBL_MAX 00059 #endif // __DBL_MAX__ 00060 00061 #ifndef FLT_MAX 00062 #define FLT_MAX __FLT_MAX__ 00063 #endif 00064 00065 #ifndef DBL_MAX 00066 #define DBL_MAX __DBL_MAX__ 00067 #endif 00068 00069 #ifndef M_PI 00070 # define M_PI 3.1415926536 00071 # define M_E 2.7182818284 00072 #endif 00073 00074 00075 00076 namespace BasicVector { 00077 00078 00079 // basic inlined vector class 00080 template<class Scalar> 00081 class Vector3Dim 00082 { 00083 public: 00084 // Constructor 00085 inline Vector3Dim(); 00086 // Copy-Constructor 00087 inline Vector3Dim(const Vector3Dim<Scalar> &v ); 00088 inline Vector3Dim(const float *); 00089 inline Vector3Dim(const double *); 00090 // construct a vector from one Scalar 00091 inline Vector3Dim(Scalar); 00092 // construct a vector from three Scalars 00093 inline Vector3Dim(Scalar, Scalar, Scalar); 00094 00095 // get address of array for OpenGL 00096 Scalar *getAddress() { return value; } 00097 00098 // Assignment operator 00099 inline const Vector3Dim<Scalar>& operator= (const Vector3Dim<Scalar>& v); 00100 // Assignment operator 00101 inline const Vector3Dim<Scalar>& operator= (Scalar s); 00102 // Assign and add operator 00103 inline const Vector3Dim<Scalar>& operator+= (const Vector3Dim<Scalar>& v); 00104 // Assign and add operator 00105 inline const Vector3Dim<Scalar>& operator+= (Scalar s); 00106 // Assign and sub operator 00107 inline const Vector3Dim<Scalar>& operator-= (const Vector3Dim<Scalar>& v); 00108 // Assign and sub operator 00109 inline const Vector3Dim<Scalar>& operator-= (Scalar s); 00110 // Assign and mult operator 00111 inline const Vector3Dim<Scalar>& operator*= (const Vector3Dim<Scalar>& v); 00112 // Assign and mult operator 00113 inline const Vector3Dim<Scalar>& operator*= (Scalar s); 00114 // Assign and div operator 00115 inline const Vector3Dim<Scalar>& operator/= (const Vector3Dim<Scalar>& v); 00116 // Assign and div operator 00117 inline const Vector3Dim<Scalar>& operator/= (Scalar s); 00118 00119 00120 // unary operator 00121 inline Vector3Dim<Scalar> operator- () const; 00122 00123 // binary operator add 00124 inline Vector3Dim<Scalar> operator+ (const Vector3Dim<Scalar>&) const; 00125 // binary operator add 00126 inline Vector3Dim<Scalar> operator+ (Scalar) const; 00127 // binary operator sub 00128 inline Vector3Dim<Scalar> operator- (const Vector3Dim<Scalar>&) const; 00129 // binary operator sub 00130 inline Vector3Dim<Scalar> operator- (Scalar) const; 00131 // binary operator mult 00132 inline Vector3Dim<Scalar> operator* (const Vector3Dim<Scalar>&) const; 00133 // binary operator mult 00134 inline Vector3Dim<Scalar> operator* (Scalar) const; 00135 // binary operator div 00136 inline Vector3Dim<Scalar> operator/ (const Vector3Dim<Scalar>&) const; 00137 // binary operator div 00138 inline Vector3Dim<Scalar> operator/ (Scalar) const; 00139 00140 // Projection normal to a vector 00141 inline Vector3Dim<Scalar> getOrthogonalntlVector3Dim() const; 00142 // Project into a plane 00143 inline const Vector3Dim<Scalar>& projectNormalTo(const Vector3Dim<Scalar> &v); 00144 00145 // minimize 00146 inline const Vector3Dim<Scalar> &minimize(const Vector3Dim<Scalar> &); 00147 // maximize 00148 inline const Vector3Dim<Scalar> &maximize(const Vector3Dim<Scalar> &); 00149 00150 // access operator 00151 inline Scalar& operator[](unsigned int i); 00152 // access operator 00153 inline const Scalar& operator[](unsigned int i) const; 00154 00156 union { 00157 struct { 00158 Scalar value[3]; 00159 }; 00160 struct { 00161 Scalar x; 00162 Scalar y; 00163 Scalar z; 00164 }; 00165 struct { 00166 Scalar X; 00167 Scalar Y; 00168 Scalar Z; 00169 }; 00170 }; 00171 protected: 00172 00173 }; 00174 00175 00176 00177 00178 00179 //------------------------------------------------------------------------------ 00180 // VECTOR inline FUNCTIONS 00181 //------------------------------------------------------------------------------ 00182 00183 00184 00185 /************************************************************************* 00186 Constructor. 00187 */ 00188 template<class Scalar> 00189 inline Vector3Dim<Scalar>::Vector3Dim( void ) 00190 { 00191 value[0] = value[1] = value[2] = 0; 00192 } 00193 00194 00195 00196 /************************************************************************* 00197 Copy-Constructor. 00198 */ 00199 template<class Scalar> 00200 inline Vector3Dim<Scalar>::Vector3Dim( const Vector3Dim<Scalar> &v ) 00201 { 00202 value[0] = v.value[0]; 00203 value[1] = v.value[1]; 00204 value[2] = v.value[2]; 00205 } 00206 template<class Scalar> 00207 inline Vector3Dim<Scalar>::Vector3Dim( const float *fvalue) 00208 { 00209 value[0] = (Scalar)fvalue[0]; 00210 value[1] = (Scalar)fvalue[1]; 00211 value[2] = (Scalar)fvalue[2]; 00212 } 00213 template<class Scalar> 00214 inline Vector3Dim<Scalar>::Vector3Dim( const double *fvalue) 00215 { 00216 value[0] = (Scalar)fvalue[0]; 00217 value[1] = (Scalar)fvalue[1]; 00218 value[2] = (Scalar)fvalue[2]; 00219 } 00220 00221 00222 00223 /************************************************************************* 00224 Constructor for a vector from a single Scalar. All components of 00225 the vector get the same value. 00226 \param s The value to set 00227 \return The new vector 00228 */ 00229 template<class Scalar> 00230 inline Vector3Dim<Scalar>::Vector3Dim(Scalar s ) 00231 { 00232 value[0]= s; 00233 value[1]= s; 00234 value[2]= s; 00235 } 00236 00237 00238 /************************************************************************* 00239 Constructor for a vector from three Scalars. 00240 \param s1 The value for the first vector component 00241 \param s2 The value for the second vector component 00242 \param s3 The value for the third vector component 00243 \return The new vector 00244 */ 00245 template<class Scalar> 00246 inline Vector3Dim<Scalar>::Vector3Dim(Scalar s1, Scalar s2, Scalar s3) 00247 { 00248 value[0]= s1; 00249 value[1]= s2; 00250 value[2]= s3; 00251 } 00252 00253 00254 00255 /************************************************************************* 00256 Copy a Vector3Dim componentwise. 00257 \param v vector with values to be copied 00258 \return Reference to self 00259 */ 00260 template<class Scalar> 00261 inline const Vector3Dim<Scalar>& 00262 Vector3Dim<Scalar>::operator=( const Vector3Dim<Scalar> &v ) 00263 { 00264 value[0] = v.value[0]; 00265 value[1] = v.value[1]; 00266 value[2] = v.value[2]; 00267 return *this; 00268 } 00269 00270 00271 /************************************************************************* 00272 Copy a Scalar to each component. 00273 \param s The value to copy 00274 \return Reference to self 00275 */ 00276 template<class Scalar> 00277 inline const Vector3Dim<Scalar>& 00278 Vector3Dim<Scalar>::operator=(Scalar s) 00279 { 00280 value[0] = s; 00281 value[1] = s; 00282 value[2] = s; 00283 return *this; 00284 } 00285 00286 00287 /************************************************************************* 00288 Add another Vector3Dim componentwise. 00289 \param v vector with values to be added 00290 \return Reference to self 00291 */ 00292 template<class Scalar> 00293 inline const Vector3Dim<Scalar>& 00294 Vector3Dim<Scalar>::operator+=( const Vector3Dim<Scalar> &v ) 00295 { 00296 value[0] += v.value[0]; 00297 value[1] += v.value[1]; 00298 value[2] += v.value[2]; 00299 return *this; 00300 } 00301 00302 00303 /************************************************************************* 00304 Add a Scalar value to each component. 00305 \param s Value to add 00306 \return Reference to self 00307 */ 00308 template<class Scalar> 00309 inline const Vector3Dim<Scalar>& 00310 Vector3Dim<Scalar>::operator+=(Scalar s) 00311 { 00312 value[0] += s; 00313 value[1] += s; 00314 value[2] += s; 00315 return *this; 00316 } 00317 00318 00319 /************************************************************************* 00320 Subtract another vector componentwise. 00321 \param v vector of values to subtract 00322 \return Reference to self 00323 */ 00324 template<class Scalar> 00325 inline const Vector3Dim<Scalar>& 00326 Vector3Dim<Scalar>::operator-=( const Vector3Dim<Scalar> &v ) 00327 { 00328 value[0] -= v.value[0]; 00329 value[1] -= v.value[1]; 00330 value[2] -= v.value[2]; 00331 return *this; 00332 } 00333 00334 00335 /************************************************************************* 00336 Subtract a Scalar value from each component. 00337 \param s Value to subtract 00338 \return Reference to self 00339 */ 00340 template<class Scalar> 00341 inline const Vector3Dim<Scalar>& 00342 Vector3Dim<Scalar>::operator-=(Scalar s) 00343 { 00344 value[0]-= s; 00345 value[1]-= s; 00346 value[2]-= s; 00347 return *this; 00348 } 00349 00350 00351 /************************************************************************* 00352 Multiply with another vector componentwise. 00353 \param v vector of values to multiply with 00354 \return Reference to self 00355 */ 00356 template<class Scalar> 00357 inline const Vector3Dim<Scalar>& 00358 Vector3Dim<Scalar>::operator*=( const Vector3Dim<Scalar> &v ) 00359 { 00360 value[0] *= v.value[0]; 00361 value[1] *= v.value[1]; 00362 value[2] *= v.value[2]; 00363 return *this; 00364 } 00365 00366 00367 /************************************************************************* 00368 Multiply each component with a Scalar value. 00369 \param s Value to multiply with 00370 \return Reference to self 00371 */ 00372 template<class Scalar> 00373 inline const Vector3Dim<Scalar>& 00374 Vector3Dim<Scalar>::operator*=(Scalar s) 00375 { 00376 value[0] *= s; 00377 value[1] *= s; 00378 value[2] *= s; 00379 return *this; 00380 } 00381 00382 00383 /************************************************************************* 00384 Divide by another Vector3Dim componentwise. 00385 \param v vector of values to divide by 00386 \return Reference to self 00387 */ 00388 template<class Scalar> 00389 inline const Vector3Dim<Scalar>& 00390 Vector3Dim<Scalar>::operator/=( const Vector3Dim<Scalar> &v ) 00391 { 00392 value[0] /= v.value[0]; 00393 value[1] /= v.value[1]; 00394 value[2] /= v.value[2]; 00395 return *this; 00396 } 00397 00398 00399 /************************************************************************* 00400 Divide each component by a Scalar value. 00401 \param s Value to divide by 00402 \return Reference to self 00403 */ 00404 template<class Scalar> 00405 inline const Vector3Dim<Scalar>& 00406 Vector3Dim<Scalar>::operator/=(Scalar s) 00407 { 00408 value[0] /= s; 00409 value[1] /= s; 00410 value[2] /= s; 00411 return *this; 00412 } 00413 00414 00415 //------------------------------------------------------------------------------ 00416 // unary operators 00417 //------------------------------------------------------------------------------ 00418 00419 00420 /************************************************************************* 00421 Build componentwise the negative this vector. 00422 \return The new (negative) vector 00423 */ 00424 template<class Scalar> 00425 inline Vector3Dim<Scalar> 00426 Vector3Dim<Scalar>::operator-() const 00427 { 00428 return Vector3Dim<Scalar>(-value[0], -value[1], -value[2]); 00429 } 00430 00431 00432 00433 //------------------------------------------------------------------------------ 00434 // binary operators 00435 //------------------------------------------------------------------------------ 00436 00437 00438 /************************************************************************* 00439 Build a vector with another vector added componentwise. 00440 \param v The second vector to add 00441 \return The sum vector 00442 */ 00443 template<class Scalar> 00444 inline Vector3Dim<Scalar> 00445 Vector3Dim<Scalar>::operator+( const Vector3Dim<Scalar> &v ) const 00446 { 00447 return Vector3Dim<Scalar>(value[0]+v.value[0], 00448 value[1]+v.value[1], 00449 value[2]+v.value[2]); 00450 } 00451 00452 00453 /************************************************************************* 00454 Build a vector with a Scalar value added to each component. 00455 \param s The Scalar value to add 00456 \return The sum vector 00457 */ 00458 template<class Scalar> 00459 inline Vector3Dim<Scalar> 00460 Vector3Dim<Scalar>::operator+(Scalar s) const 00461 { 00462 return Vector3Dim<Scalar>(value[0]+s, 00463 value[1]+s, 00464 value[2]+s); 00465 } 00466 00467 00468 /************************************************************************* 00469 Build a vector with another vector subtracted componentwise. 00470 \param v The second vector to subtract 00471 \return The difference vector 00472 */ 00473 template<class Scalar> 00474 inline Vector3Dim<Scalar> 00475 Vector3Dim<Scalar>::operator-( const Vector3Dim<Scalar> &v ) const 00476 { 00477 return Vector3Dim<Scalar>(value[0]-v.value[0], 00478 value[1]-v.value[1], 00479 value[2]-v.value[2]); 00480 } 00481 00482 00483 /************************************************************************* 00484 Build a vector with a Scalar value subtracted componentwise. 00485 \param s The Scalar value to subtract 00486 \return The difference vector 00487 */ 00488 template<class Scalar> 00489 inline Vector3Dim<Scalar> 00490 Vector3Dim<Scalar>::operator-(Scalar s ) const 00491 { 00492 return Vector3Dim<Scalar>(value[0]-s, 00493 value[1]-s, 00494 value[2]-s); 00495 } 00496 00497 00498 00499 /************************************************************************* 00500 Build a vector with another vector multiplied by componentwise. 00501 \param v The second vector to muliply with 00502 \return The product vector 00503 */ 00504 template<class Scalar> 00505 inline Vector3Dim<Scalar> 00506 Vector3Dim<Scalar>::operator*( const Vector3Dim<Scalar>& v) const 00507 { 00508 return Vector3Dim<Scalar>(value[0]*v.value[0], 00509 value[1]*v.value[1], 00510 value[2]*v.value[2]); 00511 } 00512 00513 00514 /************************************************************************* 00515 Build a Vector3Dim with a Scalar value multiplied to each component. 00516 \param s The Scalar value to multiply with 00517 \return The product vector 00518 */ 00519 template<class Scalar> 00520 inline Vector3Dim<Scalar> 00521 Vector3Dim<Scalar>::operator*(Scalar s) const 00522 { 00523 return Vector3Dim<Scalar>(value[0]*s, value[1]*s, value[2]*s); 00524 } 00525 00526 00527 /************************************************************************* 00528 Build a vector divided componentwise by another vector. 00529 \param v The second vector to divide by 00530 \return The ratio vector 00531 */ 00532 template<class Scalar> 00533 inline Vector3Dim<Scalar> 00534 Vector3Dim<Scalar>::operator/(const Vector3Dim<Scalar>& v) const 00535 { 00536 return Vector3Dim<Scalar>(value[0]/v.value[0], 00537 value[1]/v.value[1], 00538 value[2]/v.value[2]); 00539 } 00540 00541 00542 00543 /************************************************************************* 00544 Build a vector divided componentwise by a Scalar value. 00545 \param s The Scalar value to divide by 00546 \return The ratio vector 00547 */ 00548 template<class Scalar> 00549 inline Vector3Dim<Scalar> 00550 Vector3Dim<Scalar>::operator/(Scalar s) const 00551 { 00552 return Vector3Dim<Scalar>(value[0]/s, 00553 value[1]/s, 00554 value[2]/s); 00555 } 00556 00557 00558 00559 00560 00561 /************************************************************************* 00562 Get a particular component of the vector. 00563 \param i Number of Scalar to get 00564 \return Reference to the component 00565 */ 00566 template<class Scalar> 00567 inline Scalar& 00568 Vector3Dim<Scalar>::operator[]( unsigned int i ) 00569 { 00570 return value[i]; 00571 } 00572 00573 00574 /************************************************************************* 00575 Get a particular component of a constant vector. 00576 \param i Number of Scalar to get 00577 \return Reference to the component 00578 */ 00579 template<class Scalar> 00580 inline const Scalar& 00581 Vector3Dim<Scalar>::operator[]( unsigned int i ) const 00582 { 00583 return value[i]; 00584 } 00585 00586 00587 00588 //------------------------------------------------------------------------------ 00589 // BLITZ compatibility functions 00590 //------------------------------------------------------------------------------ 00591 00592 00593 00594 /************************************************************************* 00595 Compute the scalar product with another vector. 00596 \param v The second vector to work with 00597 \return The value of the scalar product 00598 */ 00599 template<class Scalar> 00600 inline Scalar dot(const Vector3Dim<Scalar> &t, const Vector3Dim<Scalar> &v ) 00601 { 00602 //return t.value[0]*v.value[0] + t.value[1]*v.value[1] + t.value[2]*v.value[2]; 00603 return ((t[0]*v[0]) + (t[1]*v[1]) + (t[2]*v[2])); 00604 } 00605 00606 00607 /************************************************************************* 00608 Calculate the cross product of this and another vector 00609 */ 00610 template<class Scalar> 00611 inline Vector3Dim<Scalar> cross(const Vector3Dim<Scalar> &t, const Vector3Dim<Scalar> &v) 00612 { 00613 Vector3Dim<Scalar> cp( 00614 ((t[1]*v[2]) - (t[2]*v[1])), 00615 ((t[2]*v[0]) - (t[0]*v[2])), 00616 ((t[0]*v[1]) - (t[1]*v[0])) ); 00617 return cp; 00618 } 00619 00620 00621 00622 00623 /************************************************************************* 00624 Compute a vector that is orthonormal to self. Nothing else can be assumed 00625 for the direction of the new vector. 00626 \return The orthonormal vector 00627 */ 00628 template<class Scalar> 00629 Vector3Dim<Scalar> 00630 Vector3Dim<Scalar>::getOrthogonalntlVector3Dim() const 00631 { 00632 // Determine the component with max. absolute value 00633 int max= (fabs(value[0]) > fabs(value[1])) ? 0 : 1; 00634 max= (fabs(value[max]) > fabs(value[2])) ? max : 2; 00635 00636 /************************************************************************* 00637 Choose another axis than the one with max. component and project 00638 orthogonal to self 00639 */ 00640 Vector3Dim<Scalar> vec(0.0); 00641 vec[(max+1)%3]= 1; 00642 vec.normalize(); 00643 vec.projectNormalTo(this->getNormalized()); 00644 return vec; 00645 } 00646 00647 00648 /************************************************************************* 00649 Projects the vector into a plane normal to the given vector, which must 00650 have unit length. Self is modified. 00651 \param v The plane normal 00652 \return The projected vector 00653 */ 00654 template<class Scalar> 00655 inline const Vector3Dim<Scalar>& 00656 Vector3Dim<Scalar>::projectNormalTo(const Vector3Dim<Scalar> &v) 00657 { 00658 Scalar sprod = dot(*this,v); 00659 value[0]= value[0] - v.value[0] * sprod; 00660 value[1]= value[1] - v.value[1] * sprod; 00661 value[2]= value[2] - v.value[2] * sprod; 00662 return *this; 00663 } 00664 00665 00666 00667 //------------------------------------------------------------------------------ 00668 // Other helper functions 00669 //------------------------------------------------------------------------------ 00670 00671 00672 00673 /************************************************************************* 00674 Minimize the vector, i.e. set each entry of the vector to the minimum 00675 of both values. 00676 \param pnt The second vector to compare with 00677 \return Reference to the modified self 00678 */ 00679 template<class Scalar> 00680 inline const Vector3Dim<Scalar> & 00681 Vector3Dim<Scalar>::minimize(const Vector3Dim<Scalar> &pnt) 00682 { 00683 for (unsigned int i = 0; i < 3; i++) 00684 value[i] = MIN(value[i],pnt[i]); 00685 return *this; 00686 } 00687 00688 00689 00690 /************************************************************************* 00691 Maximize the vector, i.e. set each entry of the vector to the maximum 00692 of both values. 00693 \param pnt The second vector to compare with 00694 \return Reference to the modified self 00695 */ 00696 template<class Scalar> 00697 inline const Vector3Dim<Scalar> & 00698 Vector3Dim<Scalar>::maximize(const Vector3Dim<Scalar> &pnt) 00699 { 00700 for (unsigned int i = 0; i < 3; i++) 00701 value[i] = MAX(value[i],pnt[i]); 00702 return *this; 00703 } 00704 00705 00706 00707 00708 00709 00710 /************************************************************************/ 00711 // HELPER FUNCTIONS, independent of implementation 00712 /************************************************************************/ 00713 00714 #define VECTOR_TYPE Vector3Dim<Scalar> 00715 00716 00717 /************************************************************************* 00718 Compute the length (norm) of the vector. 00719 \return The value of the norm 00720 */ 00721 template<class Scalar> 00722 inline Scalar norm( const VECTOR_TYPE &v) 00723 { 00724 Scalar l = v[0]*v[0] + v[1]*v[1] + v[2]*v[2]; 00725 return (fabs(l-1.) < VECTOR_EPSILON*VECTOR_EPSILON) ? 1. : sqrt(l); 00726 } 00727 00728 // for e.g. min max operator 00729 inline Real normHelper(const Vector3Dim<Real> &v) { 00730 return norm(v); 00731 } 00732 inline Real normHelper(const Real &v) { 00733 return (0. < v) ? v : -v ; 00734 } 00735 inline Real normHelper(const int &v) { 00736 return (0 < v) ? (Real)(v) : (Real)(-v) ; 00737 } 00738 00739 00740 /************************************************************************* 00741 Same as getNorm but doesnt sqrt 00742 */ 00743 template<class Scalar> 00744 inline Scalar normNoSqrt( const VECTOR_TYPE &v) 00745 { 00746 return v[0]*v[0] + v[1]*v[1] + v[2]*v[2]; 00747 } 00748 00749 00750 /************************************************************************* 00751 Compute a normalized vector based on this vector. 00752 \return The new normalized vector 00753 */ 00754 template<class Scalar> 00755 inline VECTOR_TYPE getNormalized( const VECTOR_TYPE &v) 00756 { 00757 Scalar l = v[0]*v[0] + v[1]*v[1] + v[2]*v[2]; 00758 if (fabs(l-1.) < VECTOR_EPSILON*VECTOR_EPSILON) 00759 return v; /* normalized "enough"... */ 00760 else if (l > VECTOR_EPSILON*VECTOR_EPSILON) 00761 { 00762 Scalar fac = 1./sqrt(l); 00763 return VECTOR_TYPE(v[0]*fac, v[1]*fac, v[2]*fac); 00764 } 00765 else 00766 return VECTOR_TYPE((Scalar)0); 00767 } 00768 00769 00770 /************************************************************************* 00771 Compute the norm of the vector and normalize it. 00772 \return The value of the norm 00773 */ 00774 template<class Scalar> 00775 inline Scalar normalize( VECTOR_TYPE &v) 00776 { 00777 Scalar norm; 00778 Scalar l = v[0]*v[0] + v[1]*v[1] + v[2]*v[2]; 00779 if (fabs(l-1.) < VECTOR_EPSILON*VECTOR_EPSILON) { 00780 norm = 1.; 00781 } else if (l > VECTOR_EPSILON*VECTOR_EPSILON) { 00782 norm = sqrt(l); 00783 Scalar fac = 1./norm; 00784 v[0] *= fac; 00785 v[1] *= fac; 00786 v[2] *= fac; 00787 } else { 00788 v[0]= v[1]= v[2]= 0; 00789 norm = 0.; 00790 } 00791 return (Scalar)norm; 00792 } 00793 00794 00795 /************************************************************************* 00796 Compute a vector, that is self (as an incoming 00797 vector) reflected at a surface with a distinct normal vector. Note 00798 that the normal is reversed, if the scalar product with it is positive. 00799 \param n The surface normal 00800 \return The new reflected vector 00801 */ 00802 template<class Scalar> 00803 inline VECTOR_TYPE reflectVector(const VECTOR_TYPE &t, const VECTOR_TYPE &n) 00804 { 00805 VECTOR_TYPE nn= (dot(t, n) > 0.0) ? (n*-1.0) : n; 00806 return ( t - nn * (2.0 * dot(nn, t)) ); 00807 } 00808 00809 00810 00811 /************************************************************************* 00812 * My own refraction calculation 00813 * Taken from Glassner's book, section 5.2 (Heckberts method) 00814 */ 00815 template<class Scalar> 00816 inline VECTOR_TYPE refractVector(const VECTOR_TYPE &t, const VECTOR_TYPE &normal, Scalar nt, Scalar nair, int &refRefl) 00817 { 00818 Scalar eta = nair / nt; 00819 Scalar n = -dot(t, normal); 00820 Scalar tt = 1.0 + eta*eta* (n*n-1.0); 00821 if(tt<0.0) { 00822 // we have total reflection! 00823 refRefl = 1; 00824 } else { 00825 // normal reflection 00826 tt = eta*n - sqrt(tt); 00827 return( t*eta + normal*tt ); 00828 } 00829 return t; 00830 } 00831 00832 00833 /************************************************************************* 00834 Test two ntlVector3Dims for equality based on the equality of their 00835 values within a small threshold. 00836 \param c The second vector to compare 00837 \return TRUE if both are equal 00838 \sa getEpsilon() 00839 */ 00840 template<class Scalar> 00841 inline bool equal(const VECTOR_TYPE &v, const VECTOR_TYPE &c) 00842 { 00843 return (ABS(v[0]-c[0]) + 00844 ABS(v[1]-c[1]) + 00845 ABS(v[2]-c[2]) < VECTOR_EPSILON); 00846 } 00847 00848 00849 /************************************************************************* 00850 * Assume this vector is an RGB color, and convert it to HSV 00851 */ 00852 template<class Scalar> 00853 inline void rgbToHsv( VECTOR_TYPE &V ) 00854 { 00855 Scalar h=0,s=0,v=0; 00856 Scalar maxrgb, minrgb, delta; 00857 // convert to hsv... 00858 maxrgb = V[0]; 00859 int maxindex = 1; 00860 if(V[2] > maxrgb){ maxrgb = V[2]; maxindex = 2; } 00861 if(V[1] > maxrgb){ maxrgb = V[1]; maxindex = 3; } 00862 minrgb = V[0]; 00863 if(V[2] < minrgb) minrgb = V[2]; 00864 if(V[1] < minrgb) minrgb = V[1]; 00865 00866 v = maxrgb; 00867 delta = maxrgb-minrgb; 00868 00869 if(maxrgb > 0) s = delta/maxrgb; 00870 else s = 0; 00871 00872 h = 0; 00873 if(s > 0) { 00874 if(maxindex == 1) { 00875 h = ((V[1]-V[2])/delta) + 0.0; } 00876 if(maxindex == 2) { 00877 h = ((V[2]-V[0])/delta) + 2.0; } 00878 if(maxindex == 3) { 00879 h = ((V[0]-V[1])/delta) + 4.0; } 00880 h *= 60.0; 00881 if(h < 0.0) h += 360.0; 00882 } 00883 00884 V[0] = h; 00885 V[1] = s; 00886 V[2] = v; 00887 } 00888 00889 /************************************************************************* 00890 * Assume this vector is HSV and convert to RGB 00891 */ 00892 template<class Scalar> 00893 inline void hsvToRgb( VECTOR_TYPE &V ) 00894 { 00895 Scalar h = V[0], s = V[1], v = V[2]; 00896 Scalar r=0,g=0,b=0; 00897 Scalar p,q,t, fracth; 00898 int floorh; 00899 // ...and back to rgb 00900 if(s == 0) { 00901 r = g = b = v; } 00902 else { 00903 h /= 60.0; 00904 floorh = (int)h; 00905 fracth = h - floorh; 00906 p = v * (1.0 - s); 00907 q = v * (1.0 - (s * fracth)); 00908 t = v * (1.0 - (s * (1.0 - fracth))); 00909 switch (floorh) { 00910 case 0: r = v; g = t; b = p; break; 00911 case 1: r = q; g = v; b = p; break; 00912 case 2: r = p; g = v; b = t; break; 00913 case 3: r = p; g = q; b = v; break; 00914 case 4: r = t; g = p; b = v; break; 00915 case 5: r = v; g = p; b = q; break; 00916 } 00917 } 00918 00919 V[0] = r; 00920 V[1] = g; 00921 V[2] = b; 00922 } 00923 00924 //------------------------------------------------------------------------------ 00925 // STREAM FUNCTIONS 00926 //------------------------------------------------------------------------------ 00927 00928 00929 00931 //extern const char *globVecFormatStr; 00932 #if 0 00933 static const char *globVecFormatStr = "[%6.4f,%6.4f,%6.4f]"; 00934 #endif 00935 00936 /************************************************************************* 00937 Outputs the object in human readable form using the format 00938 [x,y,z] 00939 */ 00940 template<class Scalar> 00941 std::ostream& 00942 operator<<( std::ostream& os, const BasicVector::Vector3Dim<Scalar>& i ) 00943 { 00944 #if 0 00945 char buf[256]; 00946 #if _WIN32 00947 sprintf(buf,globVecFormatStr, (double)i[0],(double)i[1],(double)i[2]); 00948 #else 00949 snprintf(buf,256,globVecFormatStr, (double)i[0],(double)i[1],(double)i[2]); 00950 #endif 00951 os << std::string(buf); 00952 #endif 00953 return os; 00954 } 00955 00956 00957 /************************************************************************* 00958 Reads the contents of the object from a stream using the same format 00959 as the output operator. 00960 */ 00961 template<class Scalar> 00962 std::istream& 00963 operator>>( std::istream& is, BasicVector::Vector3Dim<Scalar>& i ) 00964 { 00965 char c; 00966 char dummy[3]; 00967 is >> c >> i[0] >> dummy >> i[1] >> dummy >> i[2] >> c; 00968 return is; 00969 } 00970 00971 00972 /**************************************************************************/ 00973 // typedefs! 00974 /**************************************************************************/ 00975 00976 /* get minimal vector length value that can be discriminated. */ 00977 inline Real getVecEpsilon() { return (Real)VECTOR_EPSILON; } 00978 00979 // a 3D integer vector 00980 typedef Vector3Dim<int> Vec3Int; 00981 00982 // a 3D vector 00983 typedef Vector3Dim<Real> Vec3; 00984 00985 00986 }; // namespace 00987 00988 00989 #endif /* BASICVECTOR_H */