#ifndef _Reference_Frame_h

#define _Reference_Frame_h

#include "RigidTrans3.h"

/*
CLASS
   ReferenceFrame

   Holds rigid transformations, reference frames, axis systems using a 
   compact Rotation3 object and a trnaslational vector.

KEYWORDS
   reference, frame, coordinate, system, particle , vector, axis, rigid

AUTHORS
  Zipi Fligelman (zipo@math.tau.ac.il)

  Copyright: SAMBA group , Tel-Aviv Univ. Israel, 1997.

CHANGES LOG
<UL>
<LI>
</UL>

GOALS
  The class is synonymous in purpose to the RigidTrans3 class except that it
  holds the rotational parameters in a Rotation3 instead of a Matrix3. The 
  class was written in order to allow a compact description of axis systems or
  rigid transformations.

USAGE
*/


class ReferenceFrame {
public:
  //// Empty constructor = 0 rigid transformation or default axis system.
  ReferenceFrame();

  //// Builds a reference frame from a rotation and translation. The rotational
  // parameters should conform with those given in RigidTrans3. i.e. They
  // are in radians and in the order of around X (Y-Z plane), around Y
  // (Z-X plane), around Z (X-Y plane).
  ReferenceFrame(const Rotation3& r, const Vector3& t);

  //// Extracts a ReferenceFrame from a 3D rigid transformation object
  explicit ReferenceFrame(const RigidTrans3& rt);

  //// casting operator returning a reference frame as a rigid transformation
  // RigidTrans3. This casting operator allows the user to use RigidTrans3's
  // non-inplace operators.
  operator RigidTrans3() const;

  //// Computes the positions coordinates of agiven particle within the
  // reference frame.
  Vector3 coordinatesInSystem(const Vector3& v) const;

  //// Returns a Rotation3 object of the ReferenceFrame's rotation.
  const Rotation3& rotation() const;

  //// Returns the translation of the rigid transformation or in axis systems
  // the origin of the system.
  const Vector3& translation() const;

  //// Returns the appropriate rotation matrix that rotates 3D space with the
  // given rotation angles of the reference frame.
  Matrix3 rotationMatrix() const;

  Vector3 rotationAngles() const;

  // GROUP: Operators.

  //// Apply the rigid transformation rn ob vector v. Apply a rotation followed
  // by a translation
  friend Vector3 operator*(const ReferenceFrame& rt, const Vector3& v);

  //// multiply two rigid transformation such that for any vector v
  // (rt1*rt2)*v = rt1*(rt2*v)
  friend ReferenceFrame operator*(const ReferenceFrame& rt1, 
                               const ReferenceFrame& rt2);

  //// Gives the inverse of a rigid transformation such that for any vector v
  // (rt*!rt)*v = rt*(!rt*v) = v and rt*!rt = RigidTrans3().
  friend ReferenceFrame operator!(const ReferenceFrame& rt);

  //// prints 3 rotations in X-Y-Z order (see above) and translation vector.
  friend ostream& operator<<(ostream& s, const ReferenceFrame& rt);

protected:
  Rotation3 rot;
  Vector3 trans;
};

#endif










