bool OBRing::findCenterAndNormal(vector3 & center, vector3 &norm1, vector3 &norm2) { OBMol *mol= this->_parent; int j= 0; const int nA= this->_path.size(); vector3 tmp; center.Set(0.0,0.0,0.0); norm1.Set(0.0,0.0,0.0); norm2.Set(0.0,0.0,0.0); for (j = 0; j != nA; ++j) { center += (mol->GetAtom(_path[j]))->GetVector(); } center/= double(nA); for (j = 0; j != nA; ++j) { vector3 v1= (mol->GetAtom(_path[j]))->GetVector() - center; vector3 v2= (mol->GetAtom(_path[j+1==nA?0:j+1]))->GetVector() - center; tmp= cross(v1,v2); norm1+= tmp; } norm1/= double(nA); norm1.normalize(); norm2= norm1; norm2 *= -1.0; return(true); }
/*! This method employs the static method matrix3x3::jacobi(...) to find the eigenvalues and eigenvectors of a symmetric matrix. On entry it is checked if the matrix really is symmetric: if isSymmetric() returns 'false', an OBError is thrown. \note The jacobi algorithm is should work great for all symmetric 3x3 matrices. If you need to find the eigenvectors of a non-symmetric matrix, you might want to resort to the sophisticated routines of LAPACK. @param eigenvals a reference to a vector3 where the eigenvalues will be stored. The eigenvalues are ordered so that eigenvals[0] <= eigenvals[1] <= eigenvals[2]. @return an orthogonal matrix whose ith column is an eigenvector for the eigenvalue eigenvals[i]. Here 'orthogonal' means that all eigenvectors have length one and are mutually orthogonal. The ith eigenvector can thus be conveniently accessed by the GetColumn() method, as in the following example. \code // Calculate eigenvectors and -values vector3 eigenvals; matrix3x3 eigenmatrix = somematrix.findEigenvectorsIfSymmetric(eigenvals); // Print the 2nd eigenvector cout << eigenmatrix.GetColumn(1) << endl; \endcode With these conventions, a matrix is diagonalized in the following way: \code // Diagonalize the matrix matrix3x3 diagonalMatrix = eigenmatrix.inverse() * somematrix * eigenmatrix; \endcode */ matrix3x3 matrix3x3::findEigenvectorsIfSymmetric(vector3 &eigenvals) const #ifdef OB_OLD_MATH_CHECKS throw(OBError) #endif { matrix3x3 result; #ifdef OB_OLD_MATH_CHECKS if (!isSymmetric()) { OBError er("matrix3x3::findEigenvectorsIfSymmetric(vector3 &eigenvals) const throw(OBError)", "The method was called on a matrix that was not symmetric, i.e. where isSymetric() == false.", "This is a runtime or a programming error in your application."); throw er; } #endif double d[3]; matrix3x3 copyOfThis = *this; jacobi(3, copyOfThis.ele[0], d, result.ele[0]); eigenvals.Set(d); return result; }