00001 #ifndef __VMML__VECTOR__HPP__
00002 #define __VMML__VECTOR__HPP__
00003
00004 #include <vmmlib/exception.hpp>
00005 #include <vmmlib/vmmlib_config.hpp>
00006 #include <vmmlib/details.hpp>
00007
00008 #include <iostream>
00009 #include <iomanip>
00010 #include <vector>
00011 #include <cstring>
00012
00013 namespace vmml
00014 {
00015 typedef unsigned char uint8_t;
00016
00017 template< size_t M, typename float_t = double >
00018 class vector
00019 {
00020 public:
00021 typedef float_t float_type;
00022 typedef float_t value_type;
00023 typedef float_t* iterator;
00024 typedef const float_t* const_iterator;
00025
00026 static const size_t DIMENSION = M;
00027
00028
00029 inline iterator begin();
00030 inline iterator end();
00031 inline const_iterator begin() const;
00032 inline const_iterator end() const;
00033
00034
00035 inline float_t& operator()( size_t index );
00036 inline const float_t& operator()( size_t index ) const;
00037 inline float_t& operator[]( size_t index );
00038 inline const float_t& operator[]( size_t index ) const;
00039
00040 inline float_t& at( size_t index );
00041 inline const float_t& at( size_t index ) const;
00042
00043
00044 inline float_t& x();
00045 inline float_t& y();
00046 inline float_t& z();
00047 inline float_t& w();
00048 inline const float_t& x() const;
00049 inline const float_t& y() const;
00050 inline const float_t& z() const;
00051 inline const float_t& w() const;
00052
00053 bool operator==( const vector& other ) const;
00054 bool operator!=( const vector& other ) const;
00055 bool isEqualTo( const vector& other, float_t tolerance = 1e-15 ) const;
00056
00057
00058 const vector& operator=( const float_t* c_array );
00059
00060 float_t operator=( float_t filler );
00061
00062 const vector& operator=( const vector& other );
00063
00064
00065 template< typename other_float_t >
00066 void operator=( const vector< M, other_float_t >& other );
00067
00068 vector operator*( const vector& other ) const;
00069 vector operator/( const vector& other ) const;
00070 vector operator+( const vector& other ) const;
00071 vector operator-( const vector& other ) const;
00072
00073 void operator*=( const vector& other );
00074 void operator/=( const vector& other );
00075 void operator+=( const vector& other );
00076 void operator-=( const vector& other );
00077
00078 vector operator*( const float_t other ) const;
00079 vector operator/( const float_t other ) const;
00080 vector operator+( const float_t other ) const;
00081 vector operator-( const float_t other ) const;
00082
00083 void operator*=( const float_t other );
00084 void operator/=( const float_t other );
00085 void operator+=( const float_t other );
00086 void operator-=( const float_t other );
00087
00088 vector operator-() const;
00089
00090 void invert();
00091
00092
00093 vector() {};
00094 vector( float_t a );
00095
00096
00097
00098
00099 vector( float_t x, float_t y );
00100 vector( float_t x, float_t y, float_t z );
00101 vector( float_t x, float_t y, float_t z, float_t w );
00102
00103 void set( float_t a );
00104 void set( const vector< M-1, float_t >& v, float_t a );
00105
00106
00107
00108
00109 void set( float_t x, float_t y );
00110 void set( float_t x, float_t y, float_t z );
00111 void set( float_t x, float_t y, float_t z, float_t w );
00112
00113
00114
00115
00116
00117
00118
00119 inline vector cross( const vector& rhs ) const;
00120
00121
00122 void cross( const vector& a, const vector& b );
00123
00124
00125
00126
00127
00128 inline float_t dot( const vector& other ) const;
00129
00130
00131
00132
00133
00134 inline void normalize();
00135 vector getNormalized() const;
00136
00137
00138
00139 inline float_t norm() const;
00140 inline float_t normSquared() const;
00141 inline float_t length() const;
00142 inline float_t lengthSquared() const;
00143
00144 inline float_t distance( const vector& other ) const;
00145 inline float_t distanceSquared( const vector& other ) const;
00146
00147
00148
00149 void computeNormal( const vector& v0, const vector& v1, const vector& v2 );
00150
00151 vector computeNormal( const vector& v1, const vector& v2 ) const;
00152
00153
00154
00155 inline vector< 3, float_t > projectPointOntoSphere(
00156 const vector< 3, float_t >& point ) const;
00157
00158 inline float_t getDistanceToSphere( const vector< 3, float_t >& point ) const;
00159
00160 inline vector< 3, float_t >& getSphereCenter();
00161 inline const vector< 3, float_t >& getSphereCenter() const;
00162
00163
00164
00165 inline vector< 3, float_t > projectPointOntoPlane(
00166 const vector< 3, float_t >& point ) const;
00167 inline float_t getDistanceToPlane( const vector< 3, float_t >& point ) const;
00168
00169 void normalizePlane();
00170
00171
00172 size_t getSmallestComponentIndex() const;
00173 size_t getLargestComponentIndex() const;
00174
00175 float_t& getSmallestComponent();
00176 float_t& getLargestComponent();
00177 const float_t& getSmallestComponent() const;
00178 const float_t& getLargestComponent() const;
00179
00180
00181 void copyFrom1DimCArray( const float_t* c_array );
00182 template< typename different_float_t >
00183 void copyFrom1DimCArray( const different_float_t* c_array );
00184
00185 void scale_to_8bit_uint( vector< M, uint8_t >& scaled_vector,
00186 float_t min_value = -1.0, float_t max_value = 1.0 ) const;
00187
00188 inline static size_t size();
00189
00190 friend std::ostream& operator<< ( std::ostream& os, const vector& vector_ )
00191 {
00192 os << "(";
00193 size_t index = 0;
00194 for( ; index < M - 1; ++index )
00195 {
00196 os << vector_.at( index ) << ", ";
00197 }
00198 os << vector_.at( index ) << ") ";
00199 return os;
00200 }
00201
00202
00203
00204 float_t array[ M ]
00205 #ifndef VMMLIB_DONT_FORCE_ALIGNMENT
00206 #ifdef _GCC
00207 __attribute__((aligned(16)))
00208 #endif
00209 #endif
00210 ;
00211
00212
00213 static const vector FORWARD;
00214 static const vector BACKWARD;
00215 static const vector UP;
00216 static const vector DOWN;
00217 static const vector LEFT;
00218 static const vector RIGHT;
00219
00220 static const vector ONE;
00221 static const vector ZERO;
00222
00223
00224 static const vector UNIT_X;
00225 static const vector UNIT_Y;
00226 static const vector UNIT_Z;
00227
00228 };
00229
00230
00231
00232
00233
00234 #ifndef VMMLIB_NO_TYPEDEFS
00235 typedef vector< 2, float > vec2f;
00236 typedef vector< 2, double > vec2d;
00237 typedef vector< 3, float > vec3f;
00238 typedef vector< 3, double > vec3d;
00239 typedef vector< 4, float > vec4f;
00240 typedef vector< 4, double > vec4d;
00241 #endif
00242
00243 template< size_t M, typename float_t >
00244 const vector< M, float_t > vector< M, float_t >::FORWARD( 0, 0, -1 );
00245 template< size_t M, typename float_t >
00246 const vector< M, float_t > vector< M, float_t >::BACKWARD( 0, 0, 1 );
00247 template< size_t M, typename float_t >
00248 const vector< M, float_t > vector< M, float_t >::UP( 0, 1, 0 );
00249 template< size_t M, typename float_t >
00250 const vector< M, float_t > vector< M, float_t >::DOWN( 0, -1, 0 );
00251 template< size_t M, typename float_t >
00252 const vector< M, float_t > vector< M, float_t >::LEFT( -1, 0, 0 );
00253 template< size_t M, typename float_t >
00254 const vector< M, float_t > vector< M, float_t >::RIGHT( 1, 0, 0 );
00255 template< size_t M, typename float_t >
00256
00257 const vector< M, float_t > vector< M, float_t >::ONE( 1, 1, 1 );
00258 template< size_t M, typename float_t >
00259 const vector< M, float_t > vector< M, float_t >::ZERO( 0, 0, 0 );
00260 template< size_t M, typename float_t >
00261
00262 const vector< M, float_t > vector< M, float_t >::UNIT_X( 1, 0, 0 );
00263 template< size_t M, typename float_t >
00264 const vector< M, float_t > vector< M, float_t >::UNIT_Y( 0, 1, 0 );
00265 template< size_t M, typename float_t >
00266 const vector< M, float_t > vector< M, float_t >::UNIT_Z( 0, 0, 1 );
00267
00268
00269
00270
00271
00272
00273 template< size_t M, typename float_t >
00274 static vector< M, float_t >
00275 operator* ( float_t factor, const vector< M, float_t >& vector_ )
00276 {
00277 return vector_ * factor;
00278 }
00279
00280
00281 template< size_t M, typename float_t >
00282 inline float_t
00283 dot( const vector< M, float_t >& first, const vector< M, float_t >& second )
00284 {
00285 float_t tmp = 0.0;
00286 for( size_t index = 0; index < M; ++index )
00287 {
00288 tmp += first.at( index ) * second.at( index );
00289 }
00290 return tmp;
00291 }
00292
00293
00294 template< size_t M, typename float_t >
00295 inline vector< M, float_t >
00296 cross( const vector< M, float_t >& a, const vector< M, float_t >& b )
00297 {
00298 return a.cross( b );
00299 }
00300
00301
00302 template< size_t M, typename float_t >
00303 inline vector< M, float_t >
00304 normalize( const vector< M, float_t >& vector_ )
00305 {
00306 return vector_.getNormalized();
00307 }
00308
00309
00310 template< size_t M, typename float_t >
00311 vector< M, float_t >::vector( float_t a )
00312 {
00313 for( size_t index = 0; index < M; ++index )
00314 {
00315 at( index ) = a;
00316 }
00317
00318 }
00319
00320
00321
00322 template< size_t M, typename float_t >
00323 vector< M, float_t >::vector( float_t x, float_t y )
00324 {
00325 details::number_of_parameters_must_be_M< 2, M, vector< M, float_t > >();
00326
00327 array[ 0 ] = x;
00328 array[ 1 ] = y;
00329 }
00330
00331
00332 template< size_t M, typename float_t >
00333 vector< M, float_t >::vector( float_t x, float_t y, float_t z )
00334 {
00335 details::number_of_parameters_must_be_M< 3, M, vector< M, float_t > >();
00336
00337 array[ 0 ] = x;
00338 array[ 1 ] = y;
00339 array[ 2 ] = z;
00340 }
00341
00342
00343
00344 template< size_t M, typename float_t >
00345 vector< M, float_t >::vector( float_t x, float_t y, float_t z, float_t w )
00346 {
00347 details::number_of_parameters_must_be_M< 4, M, vector< M, float_t > >();
00348
00349 array[ 0 ] = x;
00350 array[ 1 ] = y;
00351 array[ 2 ] = z;
00352 array[ 3 ] = w;
00353
00354 }
00355
00356
00357
00358 template< size_t M, typename float_t >
00359 void
00360 vector< M, float_t >::set( float_t a )
00361 {
00362 for( size_t index = 0; index < M; ++index )
00363 {
00364 at( index ) = a;
00365 }
00366
00367 }
00368
00369
00370
00371 template< size_t M, typename float_t >
00372 void
00373 vector< M, float_t >::set( const vector< M-1, float_t >& v, float_t a )
00374 {
00375 memcpy( array, v.array, sizeof( float_t ) * (M-1) );
00376 at( M-1 ) = a;
00377 }
00378
00379
00380
00381
00382 template< size_t M, typename float_t >
00383 void
00384 vector< M, float_t >::set( float_t x, float_t y )
00385 {
00386 details::number_of_parameters_must_be_M< 2, M, vector< M, float_t > >();
00387
00388 array[ 0 ] = x;
00389 array[ 1 ] = y;
00390 }
00391
00392
00393 template< size_t M, typename float_t >
00394 void
00395 vector< M, float_t >::set( float_t x, float_t y, float_t z )
00396 {
00397 details::number_of_parameters_must_be_M< 3, M, vector< M, float_t > >();
00398
00399 array[ 0 ] = x;
00400 array[ 1 ] = y;
00401 array[ 2 ] = z;
00402 }
00403
00404
00405
00406 template< size_t M, typename float_t >
00407 void
00408 vector< M, float_t >::set( float_t x, float_t y, float_t z, float_t w )
00409 {
00410 details::number_of_parameters_must_be_M< 4, M, vector< M, float_t > >();
00411
00412 array[ 0 ] = x;
00413 array[ 1 ] = y;
00414 array[ 2 ] = z;
00415 array[ 3 ] = w;
00416
00417 }
00418
00419
00420 template< size_t M, typename float_t >
00421 inline float_t&
00422 vector< M, float_t >::operator()( size_t index )
00423 {
00424 return at( index );
00425 }
00426
00427
00428
00429 template< size_t M, typename float_t >
00430 inline const float_t&
00431 vector< M, float_t >::operator()( size_t index ) const
00432 {
00433 return at( index );
00434 }
00435
00436
00437
00438 template< size_t M, typename float_t >
00439 inline float_t&
00440 vector< M, float_t >::at( size_t index )
00441 {
00442 #ifdef VMMLIB_SAFE_ACCESSORS
00443 if ( index >= M )
00444 {
00445 VMMLIB_ERROR( "at() - index out of bounds", VMMLIB_HERE );
00446 }
00447 #endif
00448 return array[ index ];
00449 }
00450
00451
00452
00453 template< size_t M, typename float_t >
00454 inline const float_t&
00455 vector< M, float_t >::at( size_t index ) const
00456 {
00457 #ifdef VMMLIB_SAFE_ACCESSORS
00458 if ( index >= M )
00459 {
00460 VMMLIB_ERROR( "at() - index out of bounds", VMMLIB_HERE );
00461 }
00462 #endif
00463 return array[ index ];
00464 }
00465
00466
00467
00468 template< size_t M, typename float_t >
00469 inline float_t&
00470 vector< M, float_t >::operator[]( size_t index )
00471 {
00472 return at( index );
00473 }
00474
00475
00476
00477 template< size_t M, typename float_t >
00478 inline const float_t&
00479 vector< M, float_t >::operator[]( size_t index ) const
00480 {
00481 return at( index );
00482 }
00483
00484
00485
00486 template< size_t M, typename float_t >
00487 vector< M, float_t >
00488 vector< M, float_t >::operator*( const vector< M, float_t >& other ) const
00489 {
00490 vector< M, float_t > result;
00491 for( size_t index = 0; index < M; ++index )
00492 {
00493 result.at( index ) = at( index ) * other.at( index );
00494 }
00495 return result;
00496 }
00497
00498
00499
00500 template< size_t M, typename float_t >
00501 vector< M, float_t >
00502 vector< M, float_t >::operator/( const vector< M, float_t >& other ) const
00503 {
00504 vector< M, float_t > result;
00505 for( size_t index = 0; index < M; ++index )
00506 {
00507 result.at( index ) = at( index ) / other.at( index );
00508 }
00509 return result;
00510 }
00511
00512
00513
00514 template< size_t M, typename float_t >
00515 vector< M, float_t >
00516 vector< M, float_t >::operator+( const vector< M, float_t >& other ) const
00517 {
00518 vector< M, float_t > result;
00519 for( size_t index = 0; index < M; ++index )
00520 {
00521 result.at( index ) = at( index ) + other.at( index );
00522 }
00523 return result;
00524 }
00525
00526
00527
00528 template< size_t M, typename float_t >
00529 vector< M, float_t >
00530 vector< M, float_t >::operator-( const vector< M, float_t >& other ) const
00531 {
00532 vector< M, float_t > result;
00533 for( size_t index = 0; index < M; ++index )
00534 {
00535 result.at( index ) = at( index ) - other.at( index );
00536 }
00537 return result;
00538 }
00539
00540
00541
00542
00543 template< size_t M, typename float_t >
00544 void
00545 vector< M, float_t >::operator*=( const vector< M, float_t >& other )
00546 {
00547 for( size_t index = 0; index < M; ++index )
00548 {
00549 at( index ) *= other.at( index );
00550 }
00551 }
00552
00553
00554
00555 template< size_t M, typename float_t >
00556 void
00557 vector< M, float_t >::operator/=( const vector< M, float_t >& other )
00558 {
00559 for( size_t index = 0; index < M; ++index )
00560 {
00561 at( index ) /= other.at( index );
00562 }
00563 }
00564
00565
00566
00567 template< size_t M, typename float_t >
00568 void
00569 vector< M, float_t >::operator+=( const vector< M, float_t >& other )
00570 {
00571 for( size_t index = 0; index < M; ++index )
00572 {
00573 at( index ) += other.at( index );
00574 }
00575 }
00576
00577
00578
00579 template< size_t M, typename float_t >
00580 void
00581 vector< M, float_t >::operator-=( const vector< M, float_t >& other )
00582 {
00583 for( size_t index = 0; index < M; ++index )
00584 {
00585 at( index ) -= other.at( index );
00586 }
00587 }
00588
00589
00590
00591 template< size_t M, typename float_t >
00592 vector< M, float_t >
00593 vector< M, float_t >::operator*( const float_t other ) const
00594 {
00595 vector< M, float_t > result;
00596 for( size_t index = 0; index < M; ++index )
00597 {
00598 result.at( index ) = at( index ) * other;
00599 }
00600 return result;
00601 }
00602
00603
00604
00605 template< size_t M, typename float_t >
00606 vector< M, float_t >
00607 vector< M, float_t >::operator/( const float_t other ) const
00608 {
00609 vector< M, float_t > result;
00610 for( size_t index = 0; index < M; ++index )
00611 {
00612 result.at( index ) = at( index ) / other;
00613 }
00614 return result;
00615 }
00616
00617
00618
00619 template< size_t M, typename float_t >
00620 vector< M, float_t >
00621 vector< M, float_t >::operator+( const float_t other ) const
00622 {
00623 vector< M, float_t > result;
00624 for( size_t index = 0; index < M; ++index )
00625 {
00626 result.at( index ) = at( index ) + other;
00627 }
00628 return result;
00629 }
00630
00631
00632
00633 template< size_t M, typename float_t >
00634 vector< M, float_t >
00635 vector< M, float_t >::operator-( const float_t other ) const
00636 {
00637 vector< M, float_t > result;
00638 for( size_t index = 0; index < M; ++index )
00639 {
00640 result.at( index ) = at( index ) - other;
00641 }
00642 return result;
00643 }
00644
00645
00646
00647
00648 template< size_t M, typename float_t >
00649 void
00650 vector< M, float_t >::operator*=( const float_t other )
00651 {
00652 for( size_t index = 0; index < M; ++index )
00653 {
00654 at( index ) *= other;
00655 }
00656 }
00657
00658
00659
00660 template< size_t M, typename float_t >
00661 void
00662 vector< M, float_t >::operator/=( const float_t other )
00663 {
00664 for( size_t index = 0; index < M; ++index )
00665 {
00666 at( index ) /= other;
00667 }
00668 }
00669
00670
00671
00672 template< size_t M, typename float_t >
00673 void
00674 vector< M, float_t >::operator+=( const float_t other )
00675 {
00676 for( size_t index = 0; index < M; ++index )
00677 {
00678 at( index ) += other;
00679 }
00680 }
00681
00682
00683
00684 template< size_t M, typename float_t >
00685 void
00686 vector< M, float_t >::operator-=( const float_t other )
00687 {
00688 for( size_t index = 0; index < M; ++index )
00689 {
00690 at( index ) -= other;
00691 }
00692 }
00693
00694
00695
00696 template< size_t M, typename float_t >
00697 vector< M, float_t >
00698 vector< M, float_t >::operator-() const
00699 {
00700 vector< M, float_t > v;
00701 for( size_t index = 0; index < M; ++index )
00702 {
00703 v.array[ index ] = -array[ index ];
00704 }
00705 return v;
00706 }
00707
00708
00709
00710 template< size_t M, typename float_t >
00711 void
00712 vector< M, float_t >::invert()
00713 {
00714 for( size_t index = 0; index < M; ++index )
00715 {
00716 array[ index ] = -array[ index ];
00717 }
00718 }
00719
00720
00721
00722 template< size_t M, typename float_t >
00723 inline float_t&
00724 vector< M, float_t >::x()
00725 {
00726 details::number_of_parameters_must_be_at_least_M< 1, M, vector< M, float_t > >();
00727 return array[ 0 ];
00728 }
00729
00730
00731
00732 template< size_t M, typename float_t >
00733 inline float_t&
00734 vector< M, float_t >::y()
00735 {
00736 details::number_of_parameters_must_be_at_least_M< 2, M, vector< M, float_t > >();
00737 return array[ 1 ];
00738 }
00739
00740
00741
00742 template< size_t M, typename float_t >
00743 inline float_t&
00744 vector< M, float_t >::z()
00745 {
00746 details::number_of_parameters_must_be_at_least_M< 3, M, vector< M, float_t > >();
00747 return array[ 2 ];
00748 }
00749
00750
00751
00752 template< size_t M, typename float_t >
00753 inline float_t&
00754 vector< M, float_t >::w()
00755 {
00756 details::number_of_parameters_must_be_at_least_M< 4, M, vector< M, float_t > >();
00757 return array[ 3 ];
00758 }
00759
00760
00761
00762 template< size_t M, typename float_t >
00763 inline const float_t&
00764 vector< M, float_t >::x() const
00765 {
00766 details::number_of_parameters_must_be_at_least_M< 1, M, vector< M, float_t > >();
00767 return array[ 0 ];
00768 }
00769
00770
00771
00772 template< size_t M, typename float_t >
00773 inline const float_t&
00774 vector< M, float_t >::y() const
00775 {
00776 details::number_of_parameters_must_be_at_least_M< 2, M, vector< M, float_t > >();
00777 return array[ 1 ];
00778 }
00779
00780
00781
00782 template< size_t M, typename float_t >
00783 inline const float_t&
00784 vector< M, float_t >::z() const
00785 {
00786 details::number_of_parameters_must_be_at_least_M< 3, M, vector< M, float_t > >();
00787 return array[ 2 ];
00788 }
00789
00790
00791
00792 template< size_t M, typename float_t >
00793 inline const float_t&
00794 vector< M, float_t >::w() const
00795 {
00796 details::number_of_parameters_must_be_at_least_M< 4, M, vector< M, float_t > >();
00797 return array[ 3 ];
00798 }
00799
00800
00801
00802
00803 template< size_t M, typename float_t >
00804 inline vector< M, float_t >
00805 vector< M, float_t >::cross( const vector< M, float_t >& rhs ) const
00806 {
00807 vector< M, float_t > result;
00808 result.cross( *this, rhs );
00809 return result;
00810 }
00811
00812
00813
00814
00815 template< size_t M, typename float_t >
00816 void
00817 vector< M, float_t >::
00818 cross( const vector< M, float_t >& aa, const vector< M, float_t >& bb )
00819 {
00820 details::number_of_parameters_must_be_M< 3, M, vector< M, float_t > >();
00821
00822 array[ 0 ] = aa.y() * bb.z() - aa.z() * bb.y();
00823 array[ 1 ] = aa.z() * bb.x() - aa.x() * bb.z();
00824 array[ 2 ] = aa.x() * bb.y() - aa.y() * bb.x();
00825 }
00826
00827
00828
00829 template< size_t M, typename float_t >
00830 inline float_t
00831 vector< M, float_t >::dot( const vector< M, float_t >& other ) const
00832 {
00833 float_t tmp = 0.0;
00834 for( size_t index = 0; index < M; ++index )
00835 {
00836 tmp += at( index ) * other.at( index );
00837 }
00838 return tmp;
00839 }
00840
00841
00842 template< size_t M, typename float_t >
00843 inline void
00844 vector< M, float_t >::normalize()
00845 {
00846 float_t norm_reciprocal = 1.0 / norm();
00847 this->operator*=( norm_reciprocal );
00848 }
00849
00850
00851
00852 template< size_t M, typename float_t >
00853 vector< M, float_t >
00854 vector< M, float_t >::getNormalized() const
00855 {
00856 vector< M, float_t > n( *this );
00857 n.normalize();
00858 return n;
00859 }
00860
00861
00862
00863 template< size_t M, typename float_t >
00864 inline float_t
00865 vector< M, float_t >::norm() const
00866 {
00867 return details::getSquareRoot( normSquared() );
00868 }
00869
00870
00871
00872 template< size_t M, typename float_t >
00873 inline float_t
00874 vector< M, float_t >::normSquared() const
00875 {
00876 float_t tmp = 0.0;
00877 for( size_t index = 0; index < M; ++index )
00878 {
00879 tmp += at( index ) * at( index );
00880 }
00881 return tmp;
00882 }
00883
00884
00885
00886 template< size_t M, typename float_t >
00887 inline float_t
00888 vector< M, float_t >::length() const
00889 {
00890 return norm();
00891 }
00892
00893
00894
00895 template< size_t M, typename float_t >
00896 inline float_t
00897 vector< M, float_t >::lengthSquared() const
00898 {
00899 return normSquared();
00900 }
00901
00902
00903
00904 template< size_t M, typename float_t >
00905 inline float_t
00906 vector< M, float_t >::distance( const vector< M, float_t >& other ) const
00907 {
00908 return details::getSquareRoot( distanceSquared( other ) );
00909 }
00910
00911
00912
00913 template< size_t M, typename float_t >
00914 inline float_t
00915 vector< M, float_t >::distanceSquared( const vector< M, float_t >& other ) const
00916 {
00917 vector< M, float_t > tmp( *this );
00918 tmp -= other;
00919 return tmp.lengthSquared();
00920 }
00921
00922
00923
00924 template< size_t M, typename float_t >
00925 void
00926 vector< M, float_t >::computeNormal(
00927 const vector< M, float_t >& aa,
00928 const vector< M, float_t >& bb,
00929 const vector< M, float_t >& cc
00930 )
00931 {
00932 vector< M, float_t > u,v;
00933
00934 u = bb - aa;
00935 v = cc - aa;
00936 cross( u, v );
00937 normalize();
00938 }
00939
00940
00941
00942 template< size_t M, typename float_t >
00943 vector< M, float_t >
00944 vector< M, float_t >::computeNormal(
00945 const vector< M, float_t >& bb,
00946 const vector< M, float_t >& cc
00947 ) const
00948 {
00949 vector< M, float_t > tmp;
00950 tmp.computeNormal( *this, bb, cc);
00951 return tmp;
00952 }
00953
00954
00955
00956
00957 template< size_t M, typename float_t >
00958 inline vector< 3, float_t >
00959 vector< M, float_t >::
00960 projectPointOntoSphere( const vector< 3, float_t >& point ) const
00961 {
00962 details::number_of_parameters_must_be_M< 4, M, vector< M, float_t > >();
00963
00964 const vector< 3, float_t >& center = reinterpret_cast< const vector< 3, float_t >& >( *this );
00965 vector< 3, float_t > projPoint( point );
00966 projPoint -= center;
00967 projPoint.normalize();
00968 projPoint *= w();
00969 return center + projPoint;
00970 }
00971
00972
00973
00974
00975 template< size_t M, typename float_t >
00976 inline float_t
00977 vector< M, float_t >::
00978 getDistanceToSphere( const vector< 3, float_t >& point ) const
00979 {
00980 details::number_of_parameters_must_be_M< 4, M, vector< M, float_t > >();
00981
00982 const vector< 3, float_t >& center_ = reinterpret_cast< const vector< 3, float_t >& >( *this );
00983 return ( point - center_ ).length() - w();
00984 }
00985
00986
00987
00988
00989 template< size_t M, typename float_t >
00990 inline vector< 3, float_t >&
00991 vector< M, float_t >::getSphereCenter()
00992 {
00993 details::number_of_parameters_must_be_M< 4, M, vector< M, float_t > >();
00994 return reinterpret_cast< vector< 3, float_t >& >( *this );
00995 }
00996
00997
00998
00999
01000 template< size_t M, typename float_t >
01001 inline const vector< 3, float_t >&
01002 vector< M, float_t >::getSphereCenter() const
01003 {
01004 details::number_of_parameters_must_be_M< 4, M, vector< M, float_t > >();
01005 return reinterpret_cast< vector< 3, float_t >& >( *this );
01006 }
01007
01008
01009
01010
01011 template< size_t M, typename float_t >
01012 inline float_t
01013 vector< M, float_t >::getDistanceToPlane( const vector< 3, float_t >& point ) const
01014 {
01015 details::number_of_parameters_must_be_M< 4, M, vector< M, float_t > >();
01016
01017 const vector< 3, float_t >& normal = reinterpret_cast< const vector< 3, float_t >& >( *this );
01018 return normal.dot( point ) + w();
01019 }
01020
01021
01022
01023
01024 template< size_t M, typename float_t >
01025 vector< 3, float_t >
01026 vector< M, float_t >::projectPointOntoPlane( const vector< 3, float_t >& point ) const
01027 {
01028 details::number_of_parameters_must_be_M< 4, M, vector< M, float_t > >();
01029
01030 const vector< 3, float_t >& normal = reinterpret_cast< const vector< 3, float_t >& >( *this );
01031 return point - ( normal * getDistanceToPlane( point ) );
01032 }
01033
01034
01035
01036 template< size_t M, typename float_t >
01037 bool
01038 vector< M, float_t >::operator==( const vector< M, float_t >& other ) const
01039 {
01040 bool ok = true;
01041 for( size_t index = 0; ok && index < M; ++index )
01042 {
01043 ok = at( index ) == other.at( index );
01044 }
01045 return ok;
01046 }
01047
01048
01049 template< size_t M, typename float_t >
01050 bool
01051 vector< M, float_t >::operator!=( const vector< M, float_t >& other ) const
01052 {
01053 return ! this->operator==( other );
01054 }
01055
01056
01057 template< size_t M, typename float_t >
01058 bool
01059 vector< M, float_t >::
01060 isEqualTo( const vector< M, float_t >& other, float_t tolerance ) const
01061 {
01062 bool ok = true;
01063 for( size_t index = 0; ok && index < M; ++index )
01064 {
01065 if ( at( index ) > other.at( index ) )
01066 ok = abs( at( index ) - other.at( index ) ) < tolerance;
01067 else
01068 ok = abs( other.at( index ) - at( index ) ) < tolerance;
01069 }
01070 return ok;
01071
01072 }
01073
01074
01075
01076 template< size_t M, typename float_t >
01077 const vector< M, float_t >&
01078 vector< M, float_t >::operator=( const float_t* c_array )
01079 {
01080 copyFrom1DimCArray( c_array );
01081 return *this;
01082 }
01083
01084
01085
01086 template< size_t M, typename float_t >
01087 float_t
01088 vector< M, float_t >::operator=( float_t filler_value )
01089 {
01090 for( size_t index = 0; index < M; ++index )
01091 {
01092 at( index ) = filler_value;
01093 }
01094 return filler_value;
01095 }
01096
01097
01098
01099
01100 template< size_t M, typename float_t >
01101 const vector< M, float_t >&
01102 vector< M, float_t >::operator=( const vector< M, float_t >& other )
01103 {
01104 memcpy( array, other.array, M * sizeof( float_t ) );
01105 return *this;
01106 }
01107
01108
01109
01110
01111 template< size_t M, typename float_t >
01112 template< typename other_float_t >
01113 void
01114 vector< M, float_t >::operator=( const vector< M, other_float_t >& other )
01115 {
01116 for( size_t index = 0; index < M; ++index )
01117 {
01118 array[ index ] = static_cast< float_t >( other.array[ index ] );
01119 }
01120 }
01121
01122
01123
01124 template< size_t M, typename float_t >
01125 void
01126 vector< M, float_t >::copyFrom1DimCArray( const float_t* c_array )
01127 {
01128 memcpy( array, c_array, M * sizeof( float_t ) );
01129 }
01130
01131
01132
01133 template< size_t M, typename float_t >
01134 template< typename different_float_t >
01135 void
01136 vector< M, float_t >::copyFrom1DimCArray( const different_float_t* c_array )
01137 {
01138 for( size_t index = 0; index < M; ++index )
01139 {
01140 at( index ) = static_cast< float_t >( c_array[ index ] );
01141 }
01142 }
01143
01144
01145 template< size_t M, typename float_t >
01146 void
01147 vector< M, float_t >::scale_to_8bit_uint( vector< M, uint8_t >& scaled_vector,
01148 float_t min_value, float_t max_value ) const
01149 {
01150 float_t range = max_value-min_value;
01151 float_t half_range = range * 0.5;
01152 float_t scale = ( 1.0 / range ) * 255.0;
01153
01154 for( size_t index = 0; index < M; ++index )
01155 {
01156 scaled_vector.at( index )
01157 = static_cast< uint8_t >( ( at( index ) + half_range ) * scale );
01158 }
01159
01160 }
01161
01162
01163
01164 template< size_t M, typename float_t >
01165 inline size_t
01166 vector< M, float_t >::size()
01167 {
01168 return M;
01169 }
01170
01171
01172
01173 template< size_t M, typename float_t >
01174 size_t
01175 vector< M, float_t >::getSmallestComponentIndex() const
01176 {
01177 size_t smallest_index = 0;
01178 for( size_t index = 1; index != M; ++index )
01179 {
01180 if ( array[ index ] < array[ smallest_index ] )
01181 smallest_index = index;
01182 }
01183 return smallest_index;
01184 }
01185
01186
01187
01188 template< size_t M, typename float_t >
01189 size_t
01190 vector< M, float_t >::getLargestComponentIndex() const
01191 {
01192 size_t largest_index = 0;
01193 for( size_t index = 1; index != M; ++index )
01194 {
01195 if ( array[ index ] > array[ largest_index ] )
01196 largest_index = index;
01197 }
01198 return largest_index;
01199 }
01200
01201
01202
01203 template< size_t M, typename float_t >
01204 float_t&
01205 vector< M, float_t >::getSmallestComponent()
01206 {
01207 return at( getSmallestComponentIndex() );
01208 }
01209
01210
01211
01212 template< size_t M, typename float_t >
01213 const float_t&
01214 vector< M, float_t >::getSmallestComponent() const
01215 {
01216 return at( getSmallestComponentIndex() );
01217 }
01218
01219
01220
01221 template< size_t M, typename float_t >
01222 float_t&
01223 vector< M, float_t >::getLargestComponent()
01224 {
01225 return at( getLargestComponentIndex() );
01226 }
01227
01228
01229
01230 template< size_t M, typename float_t >
01231 const float_t&
01232 vector< M, float_t >::getLargestComponent() const
01233 {
01234 return at( getLargestComponentIndex() );
01235 }
01236
01237
01238 template< size_t M, typename float_t >
01239 inline typename vector< M, float_t >::iterator
01240 vector< M, float_t >::begin()
01241 {
01242 return array;
01243 }
01244
01245
01246 template< size_t M, typename float_t >
01247 inline typename vector< M, float_t >::iterator
01248 vector< M, float_t >::end()
01249 {
01250 return array + M; ;
01251 }
01252
01253
01254 template< size_t M, typename float_t >
01255 inline typename vector< M, float_t >::const_iterator
01256 vector< M, float_t >::begin() const
01257 {
01258 return array;
01259 }
01260
01261
01262 template< size_t M, typename float_t >
01263 inline typename vector< M, float_t >::const_iterator
01264 vector< M, float_t >::end() const
01265 {
01266 return array + M; ;
01267 }
01268
01269
01270 }
01271
01272 #endif
01273