#ifndef TORSION_H
#define TORSION_H

#include "RigidTrans3.h"
#include "numerics.h"
#include "Line.h"

#define DEG pi/180

/* 
CLASS
  Torsion
  
  Class for torsion rotation support
 
OVERVIEW TEXT

  The class handles rotation around axis. It can compute torsional angle, like
  phi, psi, or rotational matrix for rotation around an axis.

  Given 4 points in 3D space: A,B,C,D, the torsion angle is an angle between
  two planes defined as A-B-C and B-C-D. Rotations around a B-C axis will
  therefore lead to different torsion angles. The angle is computed as an angle
  between the normals to these planes.
  For definitions of protein torsion angles see:
  www.mlb.co.jp/linux/science/garlic/doc/commands/dihedrals.html
  
KEYWORDS

  Torsion angle, Dihedral angle, RigidTrans3

AUTHORS

  Yuval, Dina (inbaryuv,duhovka@tau.ac.il)

  copyright: SAMBA Group , Tel-Aviv Univ. Israel, 2003.

USAGE

CHANGES LOG
<UL>
</UL>

  Copyright: SAMBA group, Tel-Aviv Univ. Israel, 2003.
*/

class Torsion {
 public:
  //// compute torsional angle defined by 4 input points in degrees 
  static float torsionAngleDEG(const Vector3& A, const Vector3& B, const Vector3& C, const Vector3& D);

  //// compute torsional angle defined by 4 input points in radians 
  static float torsionAngleRAD(const Vector3& A, const Vector3& B, const Vector3& C, const Vector3& D) {
    return torsionAngleDEG(A, B, C, D) * DEG;
  }
  
  //// compute rotational matrix for rotation around given vector with given angle
  static Matrix3 calcRotation(const Vector3 &noment, float angle);

  //// compute transformation for rotation around given Line with given angle
  //// in radians
  static RigidTrans3 calcTransformationRAD(const Line& line, float angle);

  //// compute transformation for rotation around b-a vector with given angle
  //// in radians
  static RigidTrans3 calcTransformationRAD(const Vector3 &a, const Vector3 &b, float angle);

  //// 
  // Compute the transformation for a rotation around the given
  // segment with the given angle in radians
  static RigidTrans3 calcTransformationRAD(const Segment& segment, float angle) {
    return calcTransformationRAD(segment.getFirstPoint(), segment.getSecondPoint(), angle);
  }


  //// compute transformation for rotation around b-a vector with given angle
  //// in degrees
  static RigidTrans3 calcTransformationDEG(const Vector3 &a, const Vector3 &b, float angle) {
    return calcTransformationRAD(a,b,angle*DEG);
  }
};

#endif

