// @(#)root/mathcore:$Name: $:$Id: AxisAngle.h,v 1.3 2005/09/19 16:43:07 brun Exp $
// Authors: W. Brown, M. Fischler, L. Moneta 2005
/**********************************************************************
* *
* Copyright (c) 2005 , LCG ROOT MathLib Team *
* *
* *
**********************************************************************/
// Header file for class AxisAngle
//
// Created by: Lorenzo Moneta at Wed May 11 10:37:10 2005
//
// Last update: Wed May 11 10:37:10 2005
//
#ifndef ROOT_Math_GenVector_AxisAngle
#define ROOT_Math_GenVector_AxisAngle 1
#include "Math/GenVector/Rotation3D.h"
#include "Math/GenVector/DisplacementVector3D.h"
#include "Math/GenVector/PositionVector3D.h"
#include "Math/GenVector/LorentzVector.h"
#include "Math/GenVector/3DConversions.h"
#include <algorithm>
#include <cassert>
namespace ROOT {
namespace Math {
/**
AxisAngle class describing a rotation as a direction axis and an
angle of rotation around that axis.
@ingroup GenVector
*/
class AxisAngle {
public:
typedef double Scalar;
/**
definition of vector axis
*/
typedef DisplacementVector3D<Cartesian3D<Scalar> > AxisVector;
/**
Default constructor (axis is z and angle is zero)
*/
AxisAngle() : fAxis(0,0,1), fAngle(0) { }
/**
Construct from a non-zero vector (x,y,z) and an angle.
Precondition: the Vector needs to implement x(), y(), z(), and unit()
*/
template<class AnyVector>
AxisAngle(const AnyVector & v, Scalar angle) :
fAxis(v.unit()), fAngle(angle) { }
/**
Construct given a pair of pointers or iterators defining the
beginning and end of an array of four Scalars, to be treated as
the x, y, and z components of a unit axis vector, and the angle
of rotation.
Precondition: The first three components are assumed to represent
a unit vector. The angle is assumed to be in the rand (-pi,pi].
NO checking or re-adjusting is performed.
*/
template<class IT>
AxisAngle(IT begin, IT end) { SetComponents(begin,end); }
// The compiler-generated copy ctor, copy assignment, and dtor are OK.
/**
Re-adjust components to eliminate small deviations from the axis
being a unit vector and angles out of the canonical range (-pi,pi]
*/
void Rectify();
// ======== Construction From other Rotation Forms ==================
/**
Construct from a rotation matrix
*/
explicit AxisAngle(const Rotation3D & r) {gv_detail::convert(r,*this);}
/**
Construct from EulerAngles
*/
explicit AxisAngle(const EulerAngles & e) {gv_detail::convert(e,*this);}
/**
Construct from a rotation represented by a Quaternion
*/
explicit AxisAngle(const Quaternion & q) {gv_detail::convert(q,*this);}
/**
Construct from an axial rotation
*/
explicit AxisAngle( RotationZ const & r ) { gv_detail::convert(r, *this); }
explicit AxisAngle( RotationY const & r ) { gv_detail::convert(r, *this); }
explicit AxisAngle( RotationX const & r ) { gv_detail::convert(r, *this); }
/**
Assign from a Rotation3D
*/
AxisAngle &
operator=( Rotation3D const & r ) { return operator=(AxisAngle(r)); }
/**
Assign from EulerAngles
*/
AxisAngle &
operator=( EulerAngles const & e ) { return operator=(AxisAngle(e)); }
/**
Assign from a Quaternion
*/
AxisAngle &
operator=( Quaternion const & q ) {return operator=(AxisAngle(q)); }
/**
Assign from an axial rotation
*/
AxisAngle &
operator=( RotationZ const & r ) { return operator=(AxisAngle(r)); }
AxisAngle &
operator=( RotationY const & r ) { return operator=(AxisAngle(r)); }
AxisAngle &
operator=( RotationX const & r ) { return operator=(AxisAngle(r)); }
// ======== Components ==============
/**
Set the axis and then the angle given a pair of pointers or iterators
defining the beginning and end of an array of four Scalars.
Precondition: The axis is assumed to represent a unit vector.
NO checking or re-adjusting is performed.
*/
template<class IT>
void SetComponents(IT begin, IT end) {
assert (end==begin+4);
fAxis.SetCoordinates(begin, begin+3);
fAngle = *(begin+3);
}
/**
Get the axis and then the angle into data specified by an iterator begin
and another to the end of the desired data (4 past start).
*/
template<class IT>
void GetComponents(IT begin, IT end) const {
assert (end==begin+4);
fAxis.GetCoordinates(begin, begin+3);
*(begin+3) = fAngle;
}
/**
Set components from a non-zero vector (x,y,z) and an angle.
Precondition: the Vector needs to implement x(), y(), z(), and unit()
*/
template<class AnyVector>
void SetComponents(const AnyVector & v, Scalar angle) {
fAxis=v.unit();
fAngle=angle;
}
/**
Set components into a non-zero vector (x,y,z) and an angle.
The vector is intended to be a cartesian dispalcement vector
but any vector class assignable from one will work.
*/
template<class AnyVector>
void GetComponents(AnyVector & axis, Scalar & angle) const {
axis = fAxis;
angle = fAngle;
}
/**
accesss to rotation axis
*/
AxisVector Axis() const { return fAxis; }
/**
access to rotation angle
*/
Scalar Angle() const { return fAngle; }
// =========== operations ==============
/**
Rotation operation on a cartesian vector
*/
DisplacementVector3D< ROOT::Math::Cartesian3D<double> >
operator() (const DisplacementVector3D< ROOT::Math::Cartesian3D<double> > & v) const;
/**
Rotation operation on a displacement vector in any coordinate system
*/
template <class CoordSystem>
DisplacementVector3D<CoordSystem>
operator() (const DisplacementVector3D<CoordSystem> & v) const {
DisplacementVector3D< Cartesian3D<double> > xyz(v);
DisplacementVector3D< Cartesian3D<double> > Rxyz = operator()(xyz);
return DisplacementVector3D<CoordSystem> ( Rxyz );
}
/**
Rotation operation on a position vector in any coordinate system
*/
template <class CoordSystem>
PositionVector3D<CoordSystem>
operator() (const PositionVector3D<CoordSystem> & v) const {
DisplacementVector3D< Cartesian3D<double> > xyz(v);
DisplacementVector3D< Cartesian3D<double> > Rxyz = operator()(xyz);
return PositionVector3D<CoordSystem> ( Rxyz );
}
/**
Rotation operation on a Lorentz vector in any 4D coordinate system
*/
template <class CoordSystem>
LorentzVector<CoordSystem>
operator() (const LorentzVector<CoordSystem> & v) const {
DisplacementVector3D< Cartesian3D<double> > xyz(v.Vec());
xyz = operator()(xyz);
LorentzVector< PxPyPzE4D<double> > xyzt (xyz.X(), xyz.Y(), xyz.Z(), v.E());
return LorentzVector<CoordSystem> ( xyzt );
}
/**
Rotation operation on an arbitrary vector v.
Preconditions: v must implement methods x(), y(), and z()
and the arbitrary vector type must have a constructor taking (x,y,z)
*/
template <class ForeignVector>
ForeignVector
operator() (const ForeignVector & v) const {
DisplacementVector3D< Cartesian3D<double> > xyz(v);
DisplacementVector3D< Cartesian3D<double> > Rxyz = operator()(xyz);
return ForeignVector ( Rxyz.X(), Rxyz.Y(), Rxyz.Z() );
}
/**
Overload operator * for rotation on a vector
*/
template <class AVector>
inline
AVector operator* (const AVector & v) const
{
return operator()(v);
}
/**
Invert an AxisAngle rotation in place
*/
void Invert() { fAngle = -fAngle; }
/**
Return inverse of an AxisAngle rotation
*/
AxisAngle Inverse() const { AxisAngle result(*this); result.Invert(); return result; }
// ========= Multi-Rotation Operations ===============
/**
Multiply (combine) two rotations
*/
AxisAngle operator * (const Rotation3D & r) const;
AxisAngle operator * (const AxisAngle & a) const;
AxisAngle operator * (const EulerAngles & e) const;
AxisAngle operator * (const Quaternion & q) const;
AxisAngle operator * (const RotationX & rx) const;
AxisAngle operator * (const RotationY & ry) const;
AxisAngle operator * (const RotationZ & rz) const;
/**
Post-Multiply (on right) by another rotation : T = T*R
*/
template <class R>
AxisAngle & operator *= (const R & r) { return *this = (*this)*r; }
/**
Distance between two rotations
*/
template <class R>
Scalar Distance ( const R & r ) {return gv_detail::dist(*this,r);}
/**
Equality/inequality operators
*/
bool operator == (const AxisAngle & rhs) {
if( fAxis != rhs.fAxis ) return false;
if( fAngle != rhs.fAngle ) return false;
return true;
}
bool operator != (const AxisAngle & rhs) {
return ! operator==(rhs);
}
private:
AxisVector fAxis;
Scalar fAngle;
void RectifyAngle();
static double Pi() { return 3.14159265358979323; }
}; // AxisAngle
// ============ Class AxisAngle ends here ============
/**
Distance between two rotations
*/
template <class R>
inline
typename AxisAngle::Scalar
Distance ( const AxisAngle& r1, const R & r2) {return gv_detail::dist(r1,r2);}
/**
Multiplication of an axial rotation by an AxisAngle
*/
AxisAngle operator* (RotationX const & r1, AxisAngle const & r2);
AxisAngle operator* (RotationY const & r1, AxisAngle const & r2);
AxisAngle operator* (RotationZ const & r1, AxisAngle const & r2);
/**
Stream Output and Input
*/
// TODO - I/O should be put in the manipulator form
std::ostream & operator<< (std::ostream & os, const AxisAngle & a);
} // namespace Math
} // namespace ROOT
#endif /* ROOT_Math_GenVector_AxisAngle */
ROOT page - Class index - Class Hierarchy - Top of the page
This page has been automatically generated. If you have any comments or suggestions about the page layout send a mail to ROOT support, or contact the developers with any questions or problems regarding ROOT.