K3dVector3Work.cpp

Go to the documentation of this file.
00001 
00012 /***************************************************************************
00013  *   Copyright (C) 2007 by Jan Koci   *
00014  *   honza.koci@email.cz   *
00015  *   http://kengine.sourceforge.net/tutorial/
00016  *                                                                         *
00017  *   This program is free software; you can redistribute it and/or modify  *
00018  *   it under the terms of the GNU General Public License as published by  *
00019  *   the Free Software Foundation; either version 2 of the License, or     *
00020  *   (at your option) any later version.                                   *
00021  *                                                                         *
00022  *   This program is distributed in the hope that it will be useful,       *
00023  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00024  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00025  *   GNU General Public License for more details.                          *
00026  *                                                                         *
00027  *   You should have received a copy of the GNU General Public License     *
00028  *   along with this program; if not, write to the                         *
00029  *   Free Software Foundation, Inc.,                                       *
00030  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
00031  ***************************************************************************/
00032 
00033 #include "K3dVector3Work.h"
00034 
00035 K3dVector3Work::K3dVector3Work ( K3dGameData *_pGameData )
00036 {
00037         m_pGameData = _pGameData;
00038         // Set this pointer to the game data
00039         m_pGameData->SetVector3Work ( this );
00040 }
00041 
00042 K3dVector3Work::~K3dVector3Work ( void )
00043 {}
00044 
00047 void K3dVector3Work::CheckVector3Array ( TVector3Array &_rvVertex )
00048 {
00049         cout << endl;
00050         cout << "Num verts" << _rvVertex.size() << endl;
00051         for ( int i=0; i< ( int ) _rvVertex.size(); i++ )
00052         {
00053                 cout << "Vertex " << i << endl;
00054                 cout << "Vertex X = " << _rvVertex[i]->GetX() << endl;
00055                 cout << "Vertex Y = " << _rvVertex[i]->GetY() << endl;
00056                 cout << "Vertex Z = " << _rvVertex[i]->GetZ() << endl;
00057         }
00058 }
00059 
00064 K3dVector3Obj &K3dVector3Work::Sqr ( const K3dVector3Obj &_rkV0, const K3dVector3Obj &_rkV1 )
00065 {
00066         m_kVector = _rkV0 * _rkV1;
00067         return m_kVector;
00068 }
00069 
00074 K3dVector3Obj &K3dVector3Work::Cross ( const K3dVector3Obj &_rkV0,const K3dVector3Obj &_rkV1 )
00075 {
00076         m_kVector[0] = ( ( _rkV0[1] * _rkV1[2] ) - ( _rkV0[2] * _rkV1[1] ) );
00077         m_kVector[1] = ( ( _rkV0[2] * _rkV1[0] ) - ( _rkV0[0] * _rkV1[2] ) );
00078         m_kVector[2] = ( ( _rkV0[0] * _rkV1[1] ) - ( _rkV0[1] * _rkV1[0] ) );
00079         return m_kVector;
00080 }
00081 
00086 K3dVector3Obj &K3dVector3Work::UnitCross ( const K3dVector3Obj &_rkV0,const K3dVector3Obj &_rkV1 )
00087 {
00088         K3dVector3Obj kCross = Cross ( _rkV0,_rkV1 );
00089         m_kVector = Normalize ( kCross );
00090         return m_kVector;
00091 }
00092 
00098 K3dVector3Obj &K3dVector3Work::Normal ( const K3dVector3Obj &_rkV0,const K3dVector3Obj &_rkV1,const K3dVector3Obj &_rkV2 )
00099 {
00100         // Equation is
00101         // N = (P1 - P0) x (P2 - P0)
00102         K3dVector3Obj kDiff0, kDiff1;
00103         kDiff0 = _rkV1 - _rkV0;
00104         kDiff1 = _rkV2 - _rkV1;
00105         return UnitCross ( kDiff0, kDiff1 );
00106 }
00107 
00112 void K3dVector3Work::AddScalar ( K3dVector3Obj &_rkV, const float _fScalar, const int _iId )
00113 {
00114         if ( ! ( 0 <= _iId ) && ( _iId < 3 ) )
00115         {
00116                 cerr << "Error -- K3dVector3Work::AddScalar() -- Index must be from 0 to 2" << _iId <<endl;
00117                 return;
00118         }
00119         _rkV[_iId] += _fScalar;
00120 }
00121 
00122 
00123 
00128 void K3dVector3Work::SubtractScalar ( K3dVector3Obj &_rkV, const float _fScalar, const int _iId )
00129 {
00130         if ( ! ( 0 <= _iId ) && ( _iId < 3 ) )
00131         {
00132                 cerr << "Error -- K3dVector3Work::SubtractScalar() -- Index must be from 0 to 2" << _iId <<endl;
00133                 return;
00134         }
00135         _rkV[_iId] -= _fScalar;
00136 }
00137 
00141 K3dVector3Obj& K3dVector3Work::Normalize (const K3dVector3Obj &_rkV )
00142 {
00143         float fLength0, fLength1;
00144         m_kVector = _rkV;
00145         // Calculate vector lenght
00146         fLength0 = Length ( _rkV );
00147         if ( fLength0 != ( float ) 0 )
00148         {
00149                 fLength1 = 1.0f/fLength0;
00150                 m_kVector.GetX() *= fLength1;
00151                 m_kVector.GetY() *= fLength1;
00152                 m_kVector.GetZ() *= fLength1;
00153         }
00154         return m_kVector;
00155 }
00156 
00161 float K3dVector3Work::DotAngleBetweenVectors ( const K3dVector3Obj &_rkV0,const K3dVector3Obj &_rkV1 )
00162 {
00163         // Normalize vectors
00164         K3dVector3Obj kN0 = _rkV0;
00165         K3dVector3Obj kN1 = _rkV1;
00166         kN0 = Normalize ( kN0 );
00167         kN1 = Normalize ( kN1 );
00168 
00169         return Dot ( kN0, kN1 );
00170 }
00171 
00176 K3dVector3Obj& K3dVector3Work::Reflection ( const K3dVector3Obj &_rkDirection,const K3dVector3Obj &_rkNormal )
00177 {
00178         // Equation is
00179         // R = L - 2 perpN L
00180         //   = L - 2[L -(N.L)N]
00181         //   = 2(N.L)N - L
00182 
00183         K3dVector3Obj kL, kN;
00184         float fDot;
00185         K3dVector3 kPerpN, kDot;
00186 
00187         // Set actual vector
00188         //kL = m_afVector;
00189 
00190         // Set normal vector
00191         kN = _rkNormal;
00192         kN = Normalize ( kN );
00193 
00194 
00195         // Calculate dot product
00196         fDot = Dot ( kN , _rkDirection );
00197         //fDot = kN.Dot(kL);
00198         // Calc twice dot
00199         fDot = 2*fDot;
00200         // Calc new normal
00201         kN = kN * fDot;
00202         // Calc reflection
00203         m_kVector = kN - _rkDirection;
00204         //kR = kN - kL;
00205 
00206         return m_kVector;
00207 }
00208 
00212 float K3dVector3Work::Length ( const K3dVector3Obj &_rkV )
00213 {
00214         return ( float ) sqrt ( (_rkV.GetX() * _rkV.GetX()) + (_rkV.GetY() * _rkV.GetY()) + (_rkV.GetZ() * _rkV.GetZ()) );
00215 }
00216 
00221 K3dVector3Obj &K3dVector3Work::VectorBetween ( const K3dVector3Obj &_rkV1,const K3dVector3Obj &_rkV2 )
00222 {
00223         m_kVector[0] = _rkV1[0] - _rkV2[0];
00224         m_kVector[1] = _rkV1[1] - _rkV2[1];
00225         m_kVector[2] = _rkV1[2] - _rkV2[2];
00226         return m_kVector;
00227 }
00228 
00231 void K3dVector3Work::Angle ( K3dVector3Obj &_rkAngle )
00232 {
00233         // Length of vector
00234         float fLength;
00235         // Get length of actual vector
00236         fLength = Length ( _rkAngle );
00237         if ( fLength )
00238         {
00239                 // Calculate length for multiplication instead dividing
00240                 fLength = 1/fLength;
00241                 // Calculate X angle
00242                 m_kVector.GetX() = K3dMath::ACos ( _rkAngle.GetX() * fLength );
00243                 // Calculate Y angle
00244                 m_kVector.GetY() = K3dMath::ACos ( _rkAngle.GetY() * fLength );
00245                 // Calculate Z angle
00246                 m_kVector.GetX() = K3dMath::ACos ( _rkAngle.GetX() * fLength );
00247                 // Set result
00248                 _rkAngle = m_kVector;
00249         }
00250 }
00251 
00255 float K3dVector3Work::SquaredLength ( const K3dVector3Obj &_rkV )
00256 {
00257         float fSqrLen = 0.0f;
00258         for ( int i = 0; i < 3; i++ )
00259                 fSqrLen += ( float ) _rkV.GetVector() [i]*_rkV.GetVector() [i];
00260         return fSqrLen;
00261 }
00262 
00266 const float K3dVector3Work::SquaredLength ( const K3dVector3Obj &_rkV ) const
00267 {
00268         float fSqrLen = 0.0f;
00269         for ( int i = 0; i < 3; i++ )
00270                 fSqrLen += ( float ) _rkV.GetVector() [i]*_rkV.GetVector() [i];
00271         return fSqrLen;
00272 }
00273 
00277 float K3dVector3Work::UnitLength ( const K3dVector3Obj &_rkV )
00278 {
00279         return _rkV.GetX() + _rkV.GetY() + _rkV.GetZ();
00280 }
00281 
00286 K3dVector3Obj &K3dVector3Work::AddVector ( const K3dVector3Obj &_rkV0,const K3dVector3Obj &_rkV1 )
00287 {
00288         m_kVector[0] = _rkV0[0] + _rkV1[0];
00289         m_kVector[1] = _rkV0[1] + _rkV1[1];
00290         m_kVector[2] = _rkV0[2] + _rkV1[2];
00291         return m_kVector;
00292 }
00293 
00294 
00295 
00299 void K3dVector3Work::DivideVector ( K3dVector3Obj &_rkV ,const float _fDivider )
00300 {
00301         if ( _fDivider!=0 )
00302         {
00303                 _rkV[0] = _rkV[0] / _fDivider;
00304                 _rkV[1] = _rkV[1] / _fDivider;
00305                 _rkV[2] = _rkV[2] / _fDivider;
00306         }
00307         else
00308         {
00309                 cerr << "inline void K3dVector3Work::DivideVector() -- Error - divide by zero" << endl;
00310                 return;
00311         }
00312 }
00313 
00318 void K3dVector3Work::Translate ( K3dVector3 &_rkV, const K3dVector3 &_rkDir, const float _fDist )
00319 {
00320         m_kVector[0] = _rkV[0] + ( _rkDir[0] * _fDist );
00321         m_kVector[1] = _rkV[1] + ( _rkDir[1] * _fDist );
00322         m_kVector[2] = _rkV[2] + ( _rkDir[2] * _fDist );
00323         _rkV = m_kVector;
00324 }
00325 
00328 void K3dVector3Work::Invert ( K3dVector3 &_rkV )
00329 {
00330         _rkV[0] = -_rkV[0];
00331         _rkV[1] = -_rkV[1];
00332         _rkV[2] = -_rkV[2];
00333 
00334 }
00335 
00340 float K3dVector3Work::Dot ( const K3dVector3Obj &_rkV0,const K3dVector3Obj &_rkV1 )
00341 {
00342         float fX,fY,fZ,fResult;
00343         fX = _rkV0[0] * _rkV1[0];
00344         fY = _rkV0[1] * _rkV1[1];
00345         fZ = _rkV0[2] * _rkV1[2];
00346         fResult = fX + fY + fZ;
00347         return fResult;
00348 }
00349 
00354 float K3dVector3Work::AngleBetweenNormals ( const K3dVector3Obj &_rkNormal0,const K3dVector3Obj &_rkNormal1 )
00355 {
00356         /*
00357         * angle = acos(|U|*|V| * U·V)
00358         *
00359         * If vector is normalized, than UV lengths = 1
00360         *       
00361         * angle = acos(1*U·V)
00362         *
00363         * Consequently
00364         *
00365         * angle = acos(U·V)
00366         */
00367 
00368         float fDot = Dot ( _rkNormal0, _rkNormal1 );
00369         return K3dMath::ACos( fDot );
00370 }
00371 
00376 float K3dVector3Work::AngleBetweenVectors ( const K3dVector3Obj &_rkV0,const K3dVector3Obj &_rkV1 )
00377 {
00378         /*
00379         * Equation is
00380         * ANGLE = acos( DOT(_rkV0,_rkV1) / (LENGTH(_rkV0) * LENGTH(_rkV1)) )
00381         * If normalized vectors equation is
00382         * NORMALIZE(_rkV0)
00383         * NORMALIZE(_rkV1)
00384         * ANGLE = acos( DOT(_rkV0,_rkV1))
00385         * Therefore length of normalized vector is equals one
00386         */
00387 
00388         // Normalize vectors
00389         K3dVector3Obj kN0 = _rkV0;
00390         K3dVector3Obj kN1 = _rkV1;
00391         kN0 = Normalize ( kN0 );
00392         kN1 = Normalize ( kN1 );
00393         return AngleBetweenNormals ( kN0, kN1 );
00394 }
00395 
00401 float K3dVector3Work::AngleBetweenVectors ( const K3dVector3Obj &_rkV0,const K3dVector3Obj &_rkV1, const K3dVector3Obj &_rkCentre )
00402 {
00403         // Calculate direction vector between first vector and centre
00404         K3dVector3Obj kDirection0 = _rkV0 - _rkCentre;
00405         // Calculate direction vector between second vector and centre
00406         K3dVector3Obj kDirection1 = _rkV1 - _rkCentre;
00407         // Calculate angle between direction  vectors
00408         float fAngle = AngleBetweenVectors ( kDirection0, kDirection1 );
00409         // Calculate cross product between direction vectors
00410         K3dVector3Obj kCross = Cross ( kDirection0, kDirection1 );
00411         // Calculate unit length of cross product
00412         float fLen = UnitLength ( kCross );
00413         // Convert radian angle to degree angle
00414         fAngle = fAngle * K3dMath::K_RAD_TO_DEG;
00415         // If unit length is positive then angle is greater than 180 degree
00416         if ( fLen > ( float ) 0 )
00417         {
00418                 fAngle = ( float ) 360 - fAngle;
00419         }
00420         return fAngle;
00421 }
00422 
00427 K3dVector3Obj &K3dVector3Work::Projection ( const K3dVector3Obj &_rkP ,const K3dVector3Obj &_rkQ )
00428 {
00429         //
00430         //            P dot Q
00431         // proj qP = --------- Q
00432         //            Q dot Q
00433         //
00434 
00435         m_kVector.Set ( 0,0,0 );
00436         // Dot product
00437         float fDotPQ, fDotQQ;
00438         // Calc PQ dot product
00439         fDotPQ = Dot ( _rkP, _rkQ );
00440         // Calc QQ dot product
00441         fDotQQ = Dot ( _rkQ, _rkQ );
00442         // Calc projection
00443         if ( fDotQQ )
00444         {
00445                 m_kVector = _rkQ* ( fDotPQ/fDotQQ );
00446         }
00447         return m_kVector;
00448 }
00449 
00454 K3dVector3Obj &K3dVector3Work::Perpendicular ( const K3dVector3Obj &_rkP,const  K3dVector3Obj &_rkQ )
00455 {
00456         //
00457         // perp qP = P - proj qP
00458         //
00459 
00460         // Projection vector
00461         K3dVector3Obj kProj;
00462         // Calc projection vector
00463         kProj = Projection ( _rkP, _rkQ );
00464         // Calc perpendicular vector
00465         m_kVector = _rkP - kProj;
00466         return m_kVector;
00467 }
00468 
00473 K3dVector3Obj &K3dVector3Work::Multiply ( const K3dVector3Obj &_rkV0, const  K3dVector3Obj &_rkV1 )
00474 {
00475         m_kVector[0] = _rkV0[0] * _rkV1[0];
00476         m_kVector[1] = _rkV0[1] * _rkV1[1];
00477         m_kVector[2] = _rkV0[2] * _rkV1[2];
00478 
00479         return m_kVector;
00480 }
00481 
00486 bool K3dVector3Work::CompareIntScalars ( const K3dVector3Obj &_rkV0,const  K3dVector3Obj &_rkV1 )
00487 {
00488         if ( ( ( int ) _rkV0[0] == ( int ) _rkV1[0] )
00489                 && ( ( int ) _rkV0[1] == ( int ) _rkV1[1] )
00490                 && ( ( int ) _rkV0[2] == ( int ) _rkV1[2] ) )
00491         {
00492                 return true;
00493         }
00494         else
00495         {
00496                 return false;
00497         }
00498 }
00499 
00505 bool K3dVector3Work::EqualRange ( const K3dVector3Obj &_rkV0,const  K3dVector3Obj &_rkV1 , const float _fRange )
00506 {
00507         if (
00508             ( K3dMath::Positive ( _rkV0[0] - _rkV1[0] ) <= _fRange )
00509             && ( K3dMath::Positive ( _rkV0[1] - _rkV1[1] ) <= _fRange )
00510             && ( K3dMath::Positive ( _rkV0[2] - _rkV1[2] ) <= _fRange )
00511         )
00512         {
00513                 return true;
00514         }
00515         else
00516         {
00517                 return false;
00518         }
00519 }
00520 
00521 
00527 K3dVector3Obj &K3dVector3Work::CalcCentre ( const K3dVector3Obj &_rkV0, const K3dVector3Obj &_rkV1, const K3dVector3Obj &_rkV2 )
00528 {
00529         float fX = _rkV0[0] + _rkV1[0] + _rkV2[0];
00530         float fY = _rkV0[1] + _rkV1[1] + _rkV2[1];
00531         float fZ = _rkV0[2] + _rkV1[2] + _rkV2[2];
00532 
00533         if ( fX != 0 )
00534         {
00535                 m_kVector[0] = ( fX ) / ( float ) 3;
00536         }
00537         else
00538         {
00539                 m_kVector[0] = ( float ) 0;
00540         }
00541 
00542         if ( fY != 0 )
00543         {
00544                 m_kVector[1] = ( fY ) / ( float ) 3;
00545         }
00546         else
00547         {
00548                 m_kVector[1] = ( float ) 0;
00549         }
00550 
00551         if ( fZ != 0 )
00552         {
00553                 m_kVector[2] = ( fZ ) / ( float ) 3;
00554         }
00555         else
00556         {
00557                 m_kVector[2] = ( float ) 0;
00558         }
00559         return m_kVector;
00560 }
00561 
00564 void K3dVector3Work::SwapXY(K3dVector3Obj &_rkV)
00565 {
00566         float f = _rkV[0];
00567         _rkV[0] = _rkV[1];
00568         _rkV[1] = f;
00569 }
00570 
00573 void K3dVector3Work::SwapXZ(K3dVector3Obj &_rkV)
00574 {
00575         float f = _rkV[0];
00576         _rkV[0] = _rkV[2];
00577         _rkV[2] = f;
00578 }
00579 
00582 void K3dVector3Work::SwapYZ(K3dVector3Obj &_rkV)
00583 {
00584         float f = _rkV[1];
00585         _rkV[1] = _rkV[2];
00586         _rkV[2] = f;
00587 }
00588 
00592 void K3dVector3Work::CalcVectorArrayCentre(K3dVector3Obj &_rkVCentre, const TVector3Array &_rvVector)
00593 {
00594         // Get number of vertices
00595         int iNum = (int) _rvVector.size();
00596         _rkVCentre.Reset();
00597         
00598         // Go through all vertices
00599         for(int i=0; i<iNum; i++)
00600         {
00601                 K3dVector3Obj *pPos = _rvVector[i];
00602                 _rkVCentre += *pPos;
00603         }
00604         if(iNum > 0)
00605         {
00606                 _rkVCentre /= (float) iNum;
00607         }
00608 }
00609 
00610 
00611 
00612 
00613 
00614 

Generated on Thu Aug 16 23:53:29 2007 for K3dEngine by  doxygen 1.5.0