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