Esempio n. 1
0
  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);
  }
Esempio n. 2
0
  /*! 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;
  }