#ifndef ROOT_Math_GenVector_Transform3D
#define ROOT_Math_GenVector_Transform3D 1
#ifndef ROOT_Math_GenVector_DisplacementVector3D
#include "Math/GenVector/DisplacementVector3D.h"
#endif
#ifndef ROOT_Math_GenVector_PositionVector3D
#include "Math/GenVector/PositionVector3D.h"
#endif
#ifndef ROOT_Math_GenVector_Rotation3D
#include "Math/GenVector/Rotation3D.h"
#endif
#ifndef ROOT_Math_GenVector_Translation3D
#include "Math/GenVector/Translation3D.h"
#endif
#include "Math/GenVector/AxisAnglefwd.h"
#include "Math/GenVector/EulerAnglesfwd.h"
#include "Math/GenVector/Quaternionfwd.h"
#include "Math/GenVector/RotationZYXfwd.h"
#include "Math/GenVector/RotationXfwd.h"
#include "Math/GenVector/RotationYfwd.h"
#include "Math/GenVector/RotationZfwd.h"
#include <iostream>
namespace ROOT {
namespace Math {
class Plane3D;
class Transform3D {
public:
typedef DisplacementVector3D<Cartesian3D<double>, DefaultCoordinateSystemTag > Vector;
typedef PositionVector3D<Cartesian3D<double>, DefaultCoordinateSystemTag > Point;
enum ETransform3DMatrixIndex {
kXX = 0, kXY = 1, kXZ = 2, kDX = 3,
kYX = 4, kYY = 5, kYZ = 6, kDY = 7,
kZX = 8, kZY = 9, kZZ =10, kDZ = 11
};
Transform3D()
{
SetIdentity();
}
template<class IT>
Transform3D(IT begin, IT end)
{
SetComponents(begin,end);
}
Transform3D( const Rotation3D & r, const Vector & v)
{
AssignFrom( r, v );
}
Transform3D( const Rotation3D & r, const Translation3D & t)
{
AssignFrom( r, t.Vect() );
}
template <class ARotation, class CoordSystem, class Tag>
Transform3D( const ARotation & r, const DisplacementVector3D<CoordSystem,Tag> & v)
{
AssignFrom( Rotation3D(r), Vector (v.X(),v.Y(),v.Z()) );
}
template <class ARotation>
Transform3D( const ARotation & r, const Translation3D & t)
{
AssignFrom( Rotation3D(r), t.Vect() );
}
#ifdef OLD_VERSION
Transform3D( const Vector & v, const Rotation3D & r)
{
AssignFrom( r, r(v) );
}
#endif
explicit Transform3D( const Rotation3D & r) {
AssignFrom(r);
}
explicit Transform3D( const AxisAngle & r) {
AssignFrom(Rotation3D(r));
}
explicit Transform3D( const EulerAngles & r) {
AssignFrom(Rotation3D(r));
}
explicit Transform3D( const Quaternion & r) {
AssignFrom(Rotation3D(r));
}
explicit Transform3D( const RotationZYX & r) {
AssignFrom(Rotation3D(r));
}
explicit Transform3D( const RotationX & r) {
AssignFrom(Rotation3D(r));
}
explicit Transform3D( const RotationY & r) {
AssignFrom(Rotation3D(r));
}
explicit Transform3D( const RotationZ & r) {
AssignFrom(Rotation3D(r));
}
template<class CoordSystem, class Tag>
explicit Transform3D( const DisplacementVector3D<CoordSystem,Tag> & v) {
AssignFrom(Vector(v.X(),v.Y(),v.Z()));
}
explicit Transform3D( const Vector & v) {
AssignFrom(v);
}
explicit Transform3D( const Translation3D & t) {
AssignFrom(t.Vect());
}
#ifdef OLD_VERSION
template <class ARotation, class CoordSystem, class Tag>
Transform3D(const DisplacementVector3D<CoordSystem,Tag> & v , const ARotation & r)
{
Rotation3D r3d(r);
AssignFrom( r3d, r3d( Vector(v.X(),v.Y(),v.Z()) ) );
}
#endif
Transform3D
(const Point & fr0, const Point & fr1, const Point & fr2,
const Point & to0, const Point & to1, const Point & to2 );
template<class ForeignMatrix>
explicit Transform3D(const ForeignMatrix & m) {
SetComponents(m);
}
Transform3D(double xx, double xy, double xz, double dx,
double yx, double yy, double yz, double dy,
double zx, double zy, double zz, double dz)
{
SetComponents (xx, xy, xz, dx, yx, yy, yz, dy, zx, zy, zz, dz);
}
template<class ForeignMatrix>
Transform3D & operator= (const ForeignMatrix & m) {
SetComponents(m);
return *this;
}
template<class IT>
void SetComponents(IT begin, IT end) {
(void)end;
for (int i = 0; i <12; ++i) {
fM[i] = *begin;
++begin;
}
assert (end==begin);
}
template<class IT>
void GetComponents(IT begin, IT end) const {
(void)end;
for (int i = 0; i <12; ++i) {
*begin = fM[i];
++begin;
}
assert (end==begin);
}
template<class IT>
void GetComponents(IT begin) const {
std::copy ( fM, fM+12, begin );
}
template<class ForeignMatrix>
void
SetTransformMatrix (const ForeignMatrix & m) {
fM[kXX]=m(0,0); fM[kXY]=m(0,1); fM[kXZ]=m(0,2); fM[kDX]=m(0,3);
fM[kYX]=m(1,0); fM[kYY]=m(1,1); fM[kYZ]=m(1,2); fM[kDY]=m(1,3);
fM[kZX]=m(2,0); fM[kZY]=m(2,1); fM[kZZ]=m(2,2); fM[kDZ]=m(2,3);
}
template<class ForeignMatrix>
void
GetTransformMatrix (ForeignMatrix & m) const {
m(0,0)=fM[kXX]; m(0,1)=fM[kXY]; m(0,2)=fM[kXZ]; m(0,3)=fM[kDX];
m(1,0)=fM[kYX]; m(1,1)=fM[kYY]; m(1,2)=fM[kYZ]; m(1,3)=fM[kDY];
m(2,0)=fM[kZX]; m(2,1)=fM[kZY]; m(2,2)=fM[kZZ]; m(2,3)=fM[kDZ];
}
void
SetComponents (double xx, double xy, double xz, double dx,
double yx, double yy, double yz, double dy,
double zx, double zy, double zz, double dz) {
fM[kXX]=xx; fM[kXY]=xy; fM[kXZ]=xz; fM[kDX]=dx;
fM[kYX]=yx; fM[kYY]=yy; fM[kYZ]=yz; fM[kDY]=dy;
fM[kZX]=zx; fM[kZY]=zy; fM[kZZ]=zz; fM[kDZ]=dz;
}
void
GetComponents (double &xx, double &xy, double &xz, double &dx,
double &yx, double &yy, double &yz, double &dy,
double &zx, double &zy, double &zz, double &dz) const {
xx=fM[kXX]; xy=fM[kXY]; xz=fM[kXZ]; dx=fM[kDX];
yx=fM[kYX]; yy=fM[kYY]; yz=fM[kYZ]; dy=fM[kDY];
zx=fM[kZX]; zy=fM[kZY]; zz=fM[kZZ]; dz=fM[kDZ];
}
template<class AnyRotation, class V>
void GetDecomposition(AnyRotation &r, V &v) const {
GetRotation(r);
GetTranslation(v);
}
void GetDecomposition(Rotation3D &r, Vector &v) const {
GetRotation(r);
GetTranslation(v);
}
Rotation3D Rotation() const {
return Rotation3D( fM[kXX], fM[kXY], fM[kXZ],
fM[kYX], fM[kYY], fM[kYZ],
fM[kZX], fM[kZY], fM[kZZ] );
}
template <class AnyRotation>
AnyRotation Rotation() const {
return AnyRotation(Rotation3D(fM[kXX], fM[kXY], fM[kXZ],
fM[kYX], fM[kYY], fM[kYZ],
fM[kZX], fM[kZY], fM[kZZ] ) );
}
template <class AnyRotation>
void GetRotation(AnyRotation &r) const {
r = Rotation();
}
Translation3D Translation() const {
return Translation3D( fM[kDX], fM[kDY], fM[kDZ] );
}
template <class AnyVector>
void GetTranslation(AnyVector &v) const {
v.SetXYZ(fM[kDX], fM[kDY], fM[kDZ]);
}
Point operator() (const Point & p) const {
return Point ( fM[kXX]*p.X() + fM[kXY]*p.Y() + fM[kXZ]*p.Z() + fM[kDX],
fM[kYX]*p.X() + fM[kYY]*p.Y() + fM[kYZ]*p.Z() + fM[kDY],
fM[kZX]*p.X() + fM[kZY]*p.Y() + fM[kZZ]*p.Z() + fM[kDZ] );
}
Vector operator() (const Vector & v) const {
return Vector( fM[kXX]*v.X() + fM[kXY]*v.Y() + fM[kXZ]*v.Z() ,
fM[kYX]*v.X() + fM[kYY]*v.Y() + fM[kYZ]*v.Z() ,
fM[kZX]*v.X() + fM[kZY]*v.Y() + fM[kZZ]*v.Z() );
}
template<class CoordSystem >
PositionVector3D<CoordSystem> operator() (const PositionVector3D <CoordSystem> & p) const {
Point xyzNew = operator() ( Point(p) );
return PositionVector3D<CoordSystem> (xyzNew);
}
template<class CoordSystem >
DisplacementVector3D<CoordSystem> operator() (const DisplacementVector3D <CoordSystem> & v) const {
Vector xyzNew = operator() ( Vector(v) );
return DisplacementVector3D<CoordSystem> (xyzNew);
}
template<class CoordSystem, class Tag1, class Tag2 >
void Transform (const PositionVector3D <CoordSystem,Tag1> & p1, PositionVector3D <CoordSystem,Tag2> & p2 ) const {
Point xyzNew = operator() ( Point(p1.X(), p1.Y(), p1.Z()) );
p2.SetXYZ( xyzNew.X(), xyzNew.Y(), xyzNew.Z() );
}
template<class CoordSystem, class Tag1, class Tag2 >
void Transform (const DisplacementVector3D <CoordSystem,Tag1> & v1, DisplacementVector3D <CoordSystem,Tag2> & v2 ) const {
Vector xyzNew = operator() ( Vector(v1.X(), v1.Y(), v1.Z() ) );
v2.SetXYZ( xyzNew.X(), xyzNew.Y(), xyzNew.Z() );
}
template <class CoordSystem >
LorentzVector<CoordSystem> operator() (const LorentzVector<CoordSystem> & q) const {
Vector xyzNew = operator() ( Vector(q.Vect() ) );
return LorentzVector<CoordSystem> (xyzNew.X(), xyzNew.Y(), xyzNew.Z(), q.E() );
}
Plane3D operator() (const Plane3D & plane) const;
template<class AVector >
AVector operator * (const AVector & v) const {
return operator() (v);
}
inline Transform3D & operator *= (const Transform3D & t);
inline Transform3D operator * (const Transform3D & t) const;
void Invert();
Transform3D Inverse() const {
Transform3D t(*this);
t.Invert();
return t;
}
bool operator == (const Transform3D & rhs) const {
if( fM[0] != rhs.fM[0] ) return false;
if( fM[1] != rhs.fM[1] ) return false;
if( fM[2] != rhs.fM[2] ) return false;
if( fM[3] != rhs.fM[3] ) return false;
if( fM[4] != rhs.fM[4] ) return false;
if( fM[5] != rhs.fM[5] ) return false;
if( fM[6] != rhs.fM[6] ) return false;
if( fM[7] != rhs.fM[7] ) return false;
if( fM[8] != rhs.fM[8] ) return false;
if( fM[9] != rhs.fM[9] ) return false;
if( fM[10]!= rhs.fM[10] ) return false;
if( fM[11]!= rhs.fM[11] ) return false;
return true;
}
bool operator != (const Transform3D & rhs) const {
return ! operator==(rhs);
}
protected:
void AssignFrom( const Rotation3D & r, const Vector & v);
void AssignFrom( const Rotation3D & r);
void AssignFrom( const Vector & v);
void SetIdentity() ;
private:
double fM[12];
};
inline Transform3D & Transform3D::operator *= (const Transform3D & t)
{
SetComponents(fM[kXX]*t.fM[kXX]+fM[kXY]*t.fM[kYX]+fM[kXZ]*t.fM[kZX],
fM[kXX]*t.fM[kXY]+fM[kXY]*t.fM[kYY]+fM[kXZ]*t.fM[kZY],
fM[kXX]*t.fM[kXZ]+fM[kXY]*t.fM[kYZ]+fM[kXZ]*t.fM[kZZ],
fM[kXX]*t.fM[kDX]+fM[kXY]*t.fM[kDY]+fM[kXZ]*t.fM[kDZ]+fM[kDX],
fM[kYX]*t.fM[kXX]+fM[kYY]*t.fM[kYX]+fM[kYZ]*t.fM[kZX],
fM[kYX]*t.fM[kXY]+fM[kYY]*t.fM[kYY]+fM[kYZ]*t.fM[kZY],
fM[kYX]*t.fM[kXZ]+fM[kYY]*t.fM[kYZ]+fM[kYZ]*t.fM[kZZ],
fM[kYX]*t.fM[kDX]+fM[kYY]*t.fM[kDY]+fM[kYZ]*t.fM[kDZ]+fM[kDY],
fM[kZX]*t.fM[kXX]+fM[kZY]*t.fM[kYX]+fM[kZZ]*t.fM[kZX],
fM[kZX]*t.fM[kXY]+fM[kZY]*t.fM[kYY]+fM[kZZ]*t.fM[kZY],
fM[kZX]*t.fM[kXZ]+fM[kZY]*t.fM[kYZ]+fM[kZZ]*t.fM[kZZ],
fM[kZX]*t.fM[kDX]+fM[kZY]*t.fM[kDY]+fM[kZZ]*t.fM[kDZ]+fM[kDZ]);
return *this;
}
inline Transform3D Transform3D::operator * (const Transform3D & t) const
{
return Transform3D(fM[kXX]*t.fM[kXX]+fM[kXY]*t.fM[kYX]+fM[kXZ]*t.fM[kZX],
fM[kXX]*t.fM[kXY]+fM[kXY]*t.fM[kYY]+fM[kXZ]*t.fM[kZY],
fM[kXX]*t.fM[kXZ]+fM[kXY]*t.fM[kYZ]+fM[kXZ]*t.fM[kZZ],
fM[kXX]*t.fM[kDX]+fM[kXY]*t.fM[kDY]+fM[kXZ]*t.fM[kDZ]+fM[kDX],
fM[kYX]*t.fM[kXX]+fM[kYY]*t.fM[kYX]+fM[kYZ]*t.fM[kZX],
fM[kYX]*t.fM[kXY]+fM[kYY]*t.fM[kYY]+fM[kYZ]*t.fM[kZY],
fM[kYX]*t.fM[kXZ]+fM[kYY]*t.fM[kYZ]+fM[kYZ]*t.fM[kZZ],
fM[kYX]*t.fM[kDX]+fM[kYY]*t.fM[kDY]+fM[kYZ]*t.fM[kDZ]+fM[kDY],
fM[kZX]*t.fM[kXX]+fM[kZY]*t.fM[kYX]+fM[kZZ]*t.fM[kZX],
fM[kZX]*t.fM[kXY]+fM[kZY]*t.fM[kYY]+fM[kZZ]*t.fM[kZY],
fM[kZX]*t.fM[kXZ]+fM[kZY]*t.fM[kYZ]+fM[kZZ]*t.fM[kZZ],
fM[kZX]*t.fM[kDX]+fM[kZY]*t.fM[kDY]+fM[kZZ]*t.fM[kDZ]+fM[kDZ] );
}
inline Transform3D operator * (const Rotation3D & r, const Translation3D & t) {
return Transform3D( r, r(t.Vect()) );
}
inline Transform3D operator * (const RotationX & r, const Translation3D & t) {
Rotation3D r3(r);
return Transform3D( r3, r3(t.Vect()) );
}
inline Transform3D operator * (const RotationY & r, const Translation3D & t) {
Rotation3D r3(r);
return Transform3D( r3, r3(t.Vect()) );
}
inline Transform3D operator * (const RotationZ & r, const Translation3D & t) {
Rotation3D r3(r);
return Transform3D( r3, r3(t.Vect()) );
}
inline Transform3D operator * (const RotationZYX & r, const Translation3D & t) {
Rotation3D r3(r);
return Transform3D( r3, r3(t.Vect()) );
}
inline Transform3D operator * (const AxisAngle & r, const Translation3D & t) {
Rotation3D r3(r);
return Transform3D( r3, r3(t.Vect()) );
}
inline Transform3D operator * (const EulerAngles & r, const Translation3D & t) {
Rotation3D r3(r);
return Transform3D( r3, r3(t.Vect()) );
}
inline Transform3D operator * (const Quaternion & r, const Translation3D & t) {
Rotation3D r3(r);
return Transform3D( r3, r3(t.Vect()) );
}
inline Transform3D operator * (const Translation3D & t, const Rotation3D & r) {
return Transform3D( r, t.Vect());
}
inline Transform3D operator * (const Translation3D & t, const RotationX & r) {
return Transform3D( Rotation3D(r) , t.Vect());
}
inline Transform3D operator * (const Translation3D & t, const RotationY & r) {
return Transform3D( Rotation3D(r) , t.Vect());
}
inline Transform3D operator * (const Translation3D & t, const RotationZ & r) {
return Transform3D( Rotation3D(r) , t.Vect());
}
inline Transform3D operator * (const Translation3D & t, const RotationZYX & r) {
return Transform3D( Rotation3D(r) , t.Vect());
}
inline Transform3D operator * (const Translation3D & t, const EulerAngles & r) {
return Transform3D( Rotation3D(r) , t.Vect());
}
inline Transform3D operator * (const Translation3D & t, const Quaternion & r) {
return Transform3D( Rotation3D(r) , t.Vect());
}
inline Transform3D operator * (const Translation3D & t, const AxisAngle & r) {
return Transform3D( Rotation3D(r) , t.Vect());
}
inline Transform3D operator * (const Transform3D & t, const Translation3D & d) {
Rotation3D r = t.Rotation();
return Transform3D( r, r( d.Vect() ) + t.Translation().Vect() );
}
inline Transform3D operator * (const Translation3D & d, const Transform3D & t) {
return Transform3D( t.Rotation(), t.Translation().Vect() + d.Vect());
}
inline Transform3D operator * (const Transform3D & t, const Rotation3D & r) {
return Transform3D( t.Rotation()*r , t.Translation() );
}
inline Transform3D operator * (const Transform3D & t, const RotationX & r) {
return Transform3D( t.Rotation()*r , t.Translation() );
}
inline Transform3D operator * (const Transform3D & t, const RotationY & r) {
return Transform3D( t.Rotation()*r , t.Translation() );
}
inline Transform3D operator * (const Transform3D & t, const RotationZ & r) {
return Transform3D( t.Rotation()*r , t.Translation() );
}
inline Transform3D operator * (const Transform3D & t, const RotationZYX & r) {
return Transform3D( t.Rotation()*r , t.Translation() );
}
inline Transform3D operator * (const Transform3D & t, const EulerAngles & r) {
return Transform3D( t.Rotation()*r , t.Translation() );
}
inline Transform3D operator * (const Transform3D & t, const AxisAngle & r) {
return Transform3D( t.Rotation()*r , t.Translation() );
}
inline Transform3D operator * (const Transform3D & t, const Quaternion & r) {
return Transform3D( t.Rotation()*r , t.Translation() );
}
inline Transform3D operator * (const Rotation3D & r, const Transform3D & t) {
return Transform3D( r * t.Rotation(), r * t.Translation().Vect() );
}
inline Transform3D operator * (const RotationX & r, const Transform3D & t) {
Rotation3D r3d(r);
return Transform3D( r3d * t.Rotation(), r3d * t.Translation().Vect() );
}
inline Transform3D operator * (const RotationY & r, const Transform3D & t) {
Rotation3D r3d(r);
return Transform3D( r3d * t.Rotation(), r3d * t.Translation().Vect() );
}
inline Transform3D operator * (const RotationZ & r, const Transform3D & t) {
Rotation3D r3d(r);
return Transform3D( r3d * t.Rotation(), r3d * t.Translation().Vect() );
}
inline Transform3D operator * (const RotationZYX & r, const Transform3D & t) {
Rotation3D r3d(r);
return Transform3D( r3d * t.Rotation(), r3d * t.Translation().Vect() );
}
inline Transform3D operator * (const EulerAngles & r, const Transform3D & t) {
Rotation3D r3d(r);
return Transform3D( r3d * t.Rotation(), r3d * t.Translation().Vect() );
}
inline Transform3D operator * (const AxisAngle & r, const Transform3D & t) {
Rotation3D r3d(r);
return Transform3D( r3d * t.Rotation(), r3d * t.Translation().Vect() );
}
inline Transform3D operator * (const Quaternion & r, const Transform3D & t) {
Rotation3D r3d(r);
return Transform3D( r3d * t.Rotation(), r3d * t.Translation().Vect() );
}
std::ostream & operator<< (std::ostream & os, const Transform3D & t);
}
}
#endif /* ROOT_Math_GenVector_Transform3D */