00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #pragma once
00013
00015 #include "nvsgcommon.h"
00016
00017 #include "nvutil/Assert.h"
00018 #include <float.h>
00019 #include <math.h>
00020
00021 namespace nvmath
00022 {
00024 template<unsigned char n> class Vecnf
00025 {
00026 public:
00028
00029 Vecnf<n>( void );
00030
00032 Vecnf<n>( const Vecnf<n> & v
00033 );
00034
00036
00037 float& operator[]( size_t i
00038 );
00039
00041
00042 const float& operator[]( size_t i
00043 ) const;
00044
00046
00047 Vecnf<n> operator-( void ) const;
00048
00050
00051 Vecnf<n> operator*( float f
00052 ) const;
00053
00055
00056 float operator*( const Vecnf<n> &v
00057 ) const;
00058
00060
00061 Vecnf<n> operator/( float f
00062 ) const;
00063
00065
00066 Vecnf<n> operator+( const Vecnf<n> &v
00067 ) const;
00068
00070
00071 Vecnf<n> operator-( const Vecnf<n> &v
00072 ) const;
00073
00075
00076 bool operator==( const Vecnf<n> &v
00077 ) const;
00078
00080
00081 bool operator!=( const Vecnf<n> &v
00082 ) const;
00083
00085
00086 Vecnf<n> & operator=( const Vecnf<n> &v
00087 );
00088
00090
00091 Vecnf<n> & operator*=( float f
00092 );
00093
00095
00096 Vecnf<n> & operator/=( float f
00097 );
00098
00100
00101 Vecnf<n> & operator+=( const Vecnf<n> &v
00102 );
00103
00105
00106 Vecnf<n> & operator-=( const Vecnf<n> &v
00107 );
00108
00110
00111 const float* getPtr( void ) const;
00112
00114
00115 float normalize( void );
00116
00118
00119 void orthogonalize( const Vecnf<n> &v
00120 );
00121
00123
00124 void orthonormalize( const Vecnf<n>& v
00125 );
00126
00127 protected:
00128 float m_vec[n];
00129 };
00130
00131
00132
00133
00137 template<unsigned char n> bool areOrthogonal( const Vecnf<n> &v0
00138 , const Vecnf<n> &v1
00139 )
00140 {
00141 return( fabs( v0 * v1 ) <= FLT_EPSILON );
00142 }
00143
00148 template<unsigned char n> bool areOrthonormal( const Vecnf<n> &v0
00149 , const Vecnf<n> &v1
00150 )
00151 {
00152 return( areOrthogonal( v0, v1 ) && isNormalized( v0 ) && isNormalized( v1 ) );
00153 }
00154
00159 template<unsigned char n> bool areSimilar( const Vecnf<n> &v0
00160 , const Vecnf<n> &v1
00161 , float tol = FLT_EPSILON
00162 )
00163 {
00164 __ASSERT( 0.0f <= tol );
00165 bool similar = true;
00166 for ( size_t i=0 ; similar && i<n ; i++ )
00167 {
00168 similar = ( fabs( v0[i] - v1[i] ) <= tol );
00169 }
00170 return( similar );
00171 }
00172
00176 template<unsigned char n> float distance( const Vecnf<n> &p0
00177 , const Vecnf<n> &p1
00178 )
00179 {
00180 return( length( p0 - p1 ) );
00181 }
00182
00187 template<unsigned char n> bool isNormalized( const Vecnf<n> &v
00188 )
00189 {
00190 return( fabs( length( v ) - 1.0f ) < 2 * FLT_EPSILON );
00191 }
00192
00197 template<unsigned char n> bool isNull( const Vecnf<n> &v
00198 )
00199 {
00200 return( length( v ) <= FLT_EPSILON );
00201 }
00202
00206 template<unsigned char n> float length( const Vecnf<n> &v
00207 )
00208 {
00209 return( sqrtf( lengthSquared( v ) ) );
00210 }
00211
00215 template<unsigned char n> float lengthSquared( const Vecnf<n> &v
00216 )
00217 {
00218 return( v * v );
00219 }
00220
00224 template<unsigned char n> float maxElement( const Vecnf<n> &v
00225 )
00226 {
00227 float f = fabsf( v[0] );
00228 for ( size_t i=1 ; i<n ; i++ )
00229 {
00230 float t = fabsf( v[i] );
00231 if ( f < t )
00232 {
00233 f = t;
00234 }
00235 }
00236 return( f );
00237 }
00238
00242 template<unsigned char n> float minElement( const Vecnf<n> &v
00243 )
00244 {
00245 float f = v[0];
00246 for ( size_t i=1 ; i<n ; i++ )
00247 {
00248 if ( v[i] < f )
00249 {
00250 f = v[i];
00251 }
00252 }
00253 return( f );
00254 }
00255
00259 template<unsigned char n> Vecnf<n> operator*( float f
00260 , const Vecnf<n> &v
00261 )
00262 {
00263 return( v * f );
00264 }
00265
00266
00267
00268
00269 template<unsigned char n> Vecnf<n>::Vecnf( void )
00270 {
00271 }
00272
00273 template<unsigned char n> Vecnf<n>::Vecnf( const Vecnf<n> &v )
00274 {
00275 for ( size_t i=0 ; i<n ; i++ )
00276 {
00277 m_vec[i] = v[i];
00278 }
00279 }
00280
00281 template<unsigned char n> float& Vecnf<n>::operator[]( size_t i )
00282 {
00283 __ASSERT( 0 <= i && i < n );
00284 return( m_vec[i] );
00285 }
00286
00287 template<unsigned char n> const float& Vecnf<n>::operator[]( size_t i ) const
00288 {
00289 __ASSERT( 0 <= i && i < n );
00290 return( m_vec[i] );
00291 }
00292
00293 template<unsigned char n> Vecnf<n> Vecnf<n>::operator-( void ) const
00294 {
00295 Vecnf<n> v;
00296 for ( size_t i=0 ; i<n ; i++ )
00297 {
00298 v[i] = -m_vec[i];
00299 }
00300 return( v );
00301 }
00302
00303 template<unsigned char n> Vecnf<n> Vecnf<n>::operator*( float f ) const
00304 {
00305 Vecnf<n> ret( *this );
00306 return( ret *= f );
00307 }
00308
00309 template<unsigned char n> float Vecnf<n>::operator*( const Vecnf<n> &v ) const
00310 {
00311 float f = 0.0f;
00312 for ( size_t i=0 ; i<n ; i++ )
00313 {
00314 f += m_vec[i] * v[i];
00315 }
00316 return( f );
00317 }
00318
00319 template<unsigned char n> Vecnf<n> Vecnf<n>::operator/( float f ) const
00320 {
00321 __ASSERT( fabs( f ) > FLT_EPSILON );
00322 Vecnf<n> ret( *this );
00323 return( ret /= f );
00324 }
00325
00326 template<unsigned char n> Vecnf<n> Vecnf<n>::operator+( const Vecnf<n> &v ) const
00327 {
00328 Vecnf<n> ret( *this );
00329 return( ret += v );
00330 }
00331
00332 template<unsigned char n> Vecnf<n> Vecnf<n>::operator-( const Vecnf<n> &v ) const
00333 {
00334 Vecnf<n> ret( *this );
00335 return( ret -= v );
00336 }
00337
00338 template<unsigned char n> bool Vecnf<n>::operator==( const Vecnf<n> &v ) const
00339 {
00340 bool equal = true;
00341 for ( unsigned char i=0 ; equal && i<n ; i++ )
00342 {
00343 equal = ( fabs( m_vec[i] - v[i] ) < FLT_EPSILON );
00344 }
00345 return( equal );
00346 }
00347
00348 template<unsigned char n> bool Vecnf<n>::operator!=( const Vecnf<n> &v ) const
00349 {
00350 return( ! ( *this == v ) );
00351 }
00352
00353 template<unsigned char n> Vecnf<n> & Vecnf<n>::operator=( const Vecnf<n> &v )
00354 {
00355 for ( size_t i=0 ; i<n ; i++ )
00356 {
00357 m_vec[i] = v[i];
00358 }
00359 return( *this );
00360 }
00361
00362 template<unsigned char n> Vecnf<n> & Vecnf<n>::operator*=( float f )
00363 {
00364 for ( size_t i=0 ; i<n ; i++ )
00365 {
00366 m_vec[i] *= f;
00367 }
00368 return( *this );
00369 }
00370
00371 template<unsigned char n> Vecnf<n> & Vecnf<n>::operator/=( float f )
00372 {
00373 __ASSERT( fabs( f ) > FLT_EPSILON );
00374 for ( size_t i=0 ; i<n ; i++ )
00375 {
00376 m_vec[i] /= f;
00377 }
00378 return( *this );
00379 }
00380
00381 template<unsigned char n> Vecnf<n> & Vecnf<n>::operator+=( const Vecnf<n> &v )
00382 {
00383 for ( size_t i=0 ; i<n ; i++ )
00384 {
00385 m_vec[i] += v[i];
00386 }
00387 return( *this );
00388 }
00389
00390 template<unsigned char n> Vecnf<n> & Vecnf<n>::operator-=( const Vecnf<n> &v )
00391 {
00392 for ( size_t i=0 ; i<n ; i++ )
00393 {
00394 m_vec[i] -= v[i];
00395 }
00396 return( *this );
00397 }
00398
00399 template<unsigned char n> const float* Vecnf<n>::getPtr( void ) const
00400 {
00401 return( &m_vec[0] );
00402 }
00403
00404 template<unsigned char n> float Vecnf<n>::normalize( void )
00405 {
00406 float norm = length( *this );
00407 if ( FLT_EPSILON < norm )
00408 {
00409 *this /= norm;
00410 }
00411 return( norm );
00412 }
00413
00414 template<unsigned char n> void Vecnf<n>::orthogonalize( const Vecnf<n> &v )
00415 {
00416
00417
00418 *this = *this - ( v * *this ) * v;
00419 }
00420
00421 template<unsigned char n> void Vecnf<n>::orthonormalize( const Vecnf<n> &v )
00422 {
00423 __ASSERT( isNormalized( v ) );
00424
00425
00426 orthogonalize( v );
00427 normalize();
00428 }
00429
00430 }