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 |
---|