[21] | 1 | #ifndef _OGREODEEIGENSOLVER_H_ |
---|
| 2 | #define _OGREODEEIGENSOLVER_H_ |
---|
| 3 | |
---|
| 4 | #include "OgreOdePreReqs.h" |
---|
| 5 | |
---|
| 6 | namespace OgreOde |
---|
| 7 | { |
---|
| 8 | class _OgreOdeExport EigenSolver |
---|
| 9 | { |
---|
| 10 | public: |
---|
| 11 | EigenSolver(int iSize); |
---|
| 12 | ~EigenSolver(); |
---|
| 13 | |
---|
| 14 | // set the matrix for eigensolving |
---|
| 15 | Ogre::Real& operator() (int iRow, int iCol); |
---|
| 16 | |
---|
| 17 | // Get the eigenresults (eigenvectors are columns of eigenmatrix). The |
---|
| 18 | // GetEigenvector calls involving Vector2, Ogre::Vector3, and Vector4 should |
---|
| 19 | // only be called if you know that the eigenmatrix is of the appropriate |
---|
| 20 | // size. |
---|
| 21 | void GetEigenvector (int i, Ogre::Vector3& rkV) const; |
---|
| 22 | Ogre::Real GetEigenvalue (int i) const; |
---|
| 23 | |
---|
| 24 | // solve eigensystem, use decreasing sort on eigenvalues |
---|
| 25 | void DecrSortEigenStuff3 (); |
---|
| 26 | void IncrSortEigenStuff3 (); |
---|
| 27 | |
---|
| 28 | static void GenerateOrthonormalBasis (Ogre::Vector3& rkU, Ogre::Vector3& rkV, Ogre::Vector3& rkW, bool bUnitLengthW); |
---|
| 29 | static void orthogonalLineFit(unsigned int vertex_count, const Ogre::Vector3* vertices, Ogre::Vector3& origin, Ogre::Vector3& direction); |
---|
| 30 | static Ogre::Real SqrDistance(const Ogre::Vector3& rkPoint,const Ogre::Vector3& origin,const Ogre::Vector3& direction); |
---|
| 31 | static void GaussPointsFit(unsigned int iQuantity,const Ogre::Vector3* akPoint, Ogre::Vector3 &rkCenter, Ogre::Vector3 akAxis[3], Ogre::Real afExtent[3]); |
---|
| 32 | |
---|
| 33 | protected: |
---|
| 34 | int m_iSize; |
---|
| 35 | Ogre::Matrix3 m_kMat; |
---|
| 36 | Ogre::Real* m_afDiag; |
---|
| 37 | Ogre::Real* m_afSubd; |
---|
| 38 | |
---|
| 39 | // For odd size matrices, the Householder reduction involves an odd |
---|
| 40 | // number of reflections. The product of these is a reflection. The |
---|
| 41 | // QL algorithm uses rotations for further reductions. The final |
---|
| 42 | // orthogonal matrix whose columns are the eigenvectors is a reflection, |
---|
| 43 | // so its determinant is -1. For even size matrices, the Householder |
---|
| 44 | // reduction involves an even number of reflections whose product is a |
---|
| 45 | // rotation. The final orthogonal matrix has determinant +1. Many |
---|
| 46 | // algorithms that need an eigendecomposition want a rotation matrix. |
---|
| 47 | // We want to guarantee this is the case, so m_bRotation keeps track of |
---|
| 48 | // this. The DecrSort and IncrSort further complicate the issue since |
---|
| 49 | // they swap columns of the orthogonal matrix, causing the matrix to |
---|
| 50 | // toggle between rotation and reflection. The value m_bRotation must |
---|
| 51 | // be toggled accordingly. |
---|
| 52 | bool m_bIsRotation; |
---|
| 53 | void GuaranteeRotation (); |
---|
| 54 | |
---|
| 55 | // Householder reduction to tridiagonal form |
---|
| 56 | void Tridiagonal3 (); |
---|
| 57 | |
---|
| 58 | // QL algorithm with implicit shifting, applies to tridiagonal matrices |
---|
| 59 | bool QLAlgorithm (); |
---|
| 60 | |
---|
| 61 | // sort eigenvalues from largest to smallest |
---|
| 62 | void DecreasingSort (); |
---|
| 63 | |
---|
| 64 | void IncreasingSort (); |
---|
| 65 | }; |
---|
| 66 | } |
---|
| 67 | |
---|
| 68 | #endif |
---|