Transform3D.cxx

Go to the documentation of this file.
00001 // @(#)root/mathcore:$Id: Transform3D.cxx 22516 2008-03-07 15:14:26Z moneta $
00002 // Authors: W. Brown, M. Fischler, L. Moneta    2005
00003 
00004 /**********************************************************************
00005  *                                                                    *
00006  * Copyright (c) 2005 , LCG ROOT MathLib Team                         *
00007  *                                                                    *
00008  *                                                                    *
00009  **********************************************************************/
00010 
00011 // implementation file for class Transform3D
00012 //
00013 // Created by: Lorenzo Moneta  October 27 2005
00014 //
00015 //
00016 #include "Math/GenVector/GenVectorIO.h"
00017 
00018 #include "Math/GenVector/Transform3D.h"
00019 #include "Math/GenVector/Plane3D.h"
00020 
00021 #include <cmath>
00022 #include <algorithm>
00023 
00024 
00025 
00026 
00027 namespace ROOT {
00028 
00029 namespace Math {
00030 
00031 
00032 typedef Transform3D::Point  XYZPoint; 
00033 typedef Transform3D::Vector XYZVector; 
00034 
00035 
00036 // ========== Constructors and Assignment =====================
00037 
00038 
00039 
00040 // construct from two ref frames
00041 Transform3D::Transform3D(const XYZPoint & fr0, const XYZPoint & fr1, const XYZPoint & fr2,
00042                          const XYZPoint & to0, const XYZPoint & to1, const XYZPoint & to2 )
00043 {
00044    // takes impl. from CLHEP ( E.Chernyaev). To be checked
00045    
00046    XYZVector x1,y1,z1, x2,y2,z2;
00047    x1 = (fr1 - fr0).Unit();
00048    y1 = (fr2 - fr0).Unit();
00049    x2 = (to1 - to0).Unit();
00050    y2 = (to2 - to0).Unit();
00051    
00052    //   C H E C K   A N G L E S
00053    
00054    double cos1, cos2;
00055    cos1 = x1.Dot(y1);
00056    cos2 = x2.Dot(y2);
00057    
00058    if (std::fabs(1.0-cos1) <= 0.000001 || std::fabs(1.0-cos2) <= 0.000001) {
00059       std::cerr << "Transform3D: Error : zero angle between axes" << std::endl;
00060       SetIdentity();
00061    } else {
00062       if (std::fabs(cos1-cos2) > 0.000001) {
00063          std::cerr << "Transform3D: Warning: angles between axes are not equal"
00064          << std::endl;
00065       }
00066       
00067       //   F I N D   R O T A T I O N   M A T R I X
00068       
00069       z1 = (x1.Cross(y1)).Unit();
00070       y1  = z1.Cross(x1);
00071       
00072       z2 = (x2.Cross(y2)).Unit();
00073       y2  = z2.Cross(x2);
00074 
00075       double x1x = x1.x();      double x1y = x1.y();      double x1z = x1.z();
00076       double y1x = y1.x();      double y1y = y1.y();      double y1z = y1.z();
00077       double z1x = z1.x();      double z1y = z1.y();      double z1z = z1.z();
00078 
00079       double x2x = x2.x();      double x2y = x2.y();      double x2z = x2.z();
00080       double y2x = y2.x();      double y2y = y2.y();      double y2z = y2.z();
00081       double z2x = z2.x();      double z2y = z2.y();      double z2z = z2.z();
00082       
00083       double detxx =  (y1y *z1z  - z1y *y1z );
00084       double detxy = -(y1x *z1z  - z1x *y1z );
00085       double detxz =  (y1x *z1y  - z1x *y1y );
00086       double detyx = -(x1y *z1z  - z1y *x1z );
00087       double detyy =  (x1x *z1z  - z1x *x1z );
00088       double detyz = -(x1x *z1y  - z1x *x1y );
00089       double detzx =  (x1y *y1z  - y1y *x1z );
00090       double detzy = -(x1x *y1z  - y1x *x1z );
00091       double detzz =  (x1x *y1y  - y1x *x1y );
00092       
00093       double txx = x2x *detxx + y2x *detyx + z2x *detzx;
00094       double txy = x2x *detxy + y2x *detyy + z2x *detzy;
00095       double txz = x2x *detxz + y2x *detyz + z2x *detzz;
00096       double tyx = x2y *detxx + y2y *detyx + z2y *detzx;
00097       double tyy = x2y *detxy + y2y *detyy + z2y *detzy;
00098       double tyz = x2y *detxz + y2y *detyz + z2y *detzz;
00099       double tzx = x2z *detxx + y2z *detyx + z2z *detzx;
00100       double tzy = x2z *detxy + y2z *detyy + z2z *detzy;
00101       double tzz = x2z *detxz + y2z *detyz + z2z *detzz;
00102       
00103       //   S E T    T R A N S F O R M A T I O N
00104       
00105       double dx1 = fr0.x(), dy1 = fr0.y(), dz1 = fr0.z();
00106       double dx2 = to0.x(), dy2 = to0.y(), dz2 = to0.z();
00107       
00108       SetComponents(txx, txy, txz, dx2-txx*dx1-txy*dy1-txz*dz1,
00109                     tyx, tyy, tyz, dy2-tyx*dx1-tyy*dy1-tyz*dz1,
00110                     tzx, tzy, tzz, dz2-tzx*dx1-tzy*dy1-tzz*dz1);
00111    }
00112 }
00113 
00114 
00115 // inversion (from CLHEP)
00116 void Transform3D::Invert()
00117 {
00118    //
00119    // Name: Transform3D::inverse                     Date:    24.09.96
00120    // Author: E.Chernyaev (IHEP/Protvino)            Revised:
00121    //
00122    // Function: Find inverse affine transformation.
00123    
00124    double detxx = fM[kYY]*fM[kZZ] - fM[kYZ]*fM[kZY];
00125    double detxy = fM[kYX]*fM[kZZ] - fM[kYZ]*fM[kZX];
00126    double detxz = fM[kYX]*fM[kZY] - fM[kYY]*fM[kZX];
00127    double det   = fM[kXX]*detxx - fM[kXY]*detxy + fM[kXZ]*detxz;
00128    if (det == 0) {
00129       std::cerr << "Transform3D::inverse error: zero determinant" << std::endl;
00130       return;
00131    }
00132    det = 1./det; detxx *= det; detxy *= det; detxz *= det;
00133    double detyx = (fM[kXY]*fM[kZZ] - fM[kXZ]*fM[kZY] )*det;
00134    double detyy = (fM[kXX]*fM[kZZ] - fM[kXZ]*fM[kZX] )*det;
00135    double detyz = (fM[kXX]*fM[kZY] - fM[kXY]*fM[kZX] )*det;
00136    double detzx = (fM[kXY]*fM[kYZ] - fM[kXZ]*fM[kYY] )*det;
00137    double detzy = (fM[kXX]*fM[kYZ] - fM[kXZ]*fM[kYX] )*det;
00138    double detzz = (fM[kXX]*fM[kYY] - fM[kXY]*fM[kYX] )*det;
00139    SetComponents
00140       (detxx, -detyx,  detzx, -detxx*fM[kDX]+detyx*fM[kDY]-detzx*fM[kDZ],
00141        -detxy,  detyy, -detzy,  detxy*fM[kDX]-detyy*fM[kDY]+detzy*fM[kDZ],
00142        detxz, -detyz,  detzz, -detxz*fM[kDX]+detyz*fM[kDY]-detzz*fM[kDZ]);
00143 }
00144 
00145 
00146 
00147 
00148 void Transform3D::SetIdentity()
00149 {
00150    //set identity ( identity rotation and zero translation)
00151    fM[kXX] = 1.0;  fM[kXY] = 0.0; fM[kXZ] = 0.0; fM[kDX] = 0.0;
00152    fM[kYX] = 0.0;  fM[kYY] = 1.0; fM[kYZ] = 0.0; fM[kDY] = 0.0;
00153    fM[kZX] = 0.0;  fM[kZY] = 0.0; fM[kZZ] = 1.0; fM[kDZ] = 0.0;
00154 }
00155 
00156 
00157 void Transform3D::AssignFrom (const Rotation3D  & r,  const XYZVector & v)
00158 {
00159    // assignment  from rotation + translation
00160    
00161    double rotData[9];
00162    r.GetComponents(rotData, rotData +9);
00163    // first raw
00164    for (int i = 0; i < 3; ++i)
00165       fM[i] = rotData[i];
00166    // second raw
00167    for (int i = 0; i < 3; ++i)
00168       fM[kYX+i] = rotData[3+i];
00169    // third raw
00170    for (int i = 0; i < 3; ++i)
00171       fM[kZX+i] = rotData[6+i];
00172    
00173    // translation data
00174    double vecData[3];
00175    v.GetCoordinates(vecData, vecData+3);
00176    fM[kDX] = vecData[0];
00177    fM[kDY] = vecData[1];
00178    fM[kDZ] = vecData[2];
00179 }
00180 
00181 
00182 void Transform3D::AssignFrom(const Rotation3D & r)
00183 {
00184    // assign from only a rotation  (null translation)
00185    double rotData[9];
00186    r.GetComponents(rotData, rotData +9);
00187    for (int i = 0; i < 3; ++i) {
00188       for (int j = 0; j < 3; ++j)
00189          fM[4*i + j] = rotData[3*i+j];
00190       // empty vector data
00191       fM[4*i + 3] = 0;
00192    }
00193 }
00194 
00195 void Transform3D::AssignFrom(const XYZVector & v)
00196 {
00197    // assign from a translation only (identity rotations)
00198    fM[kXX] = 1.0;  fM[kXY] = 0.0; fM[kXZ] = 0.0; fM[kDX] = v.X();
00199    fM[kYX] = 0.0;  fM[kYY] = 1.0; fM[kYZ] = 0.0; fM[kDY] = v.Y();
00200    fM[kZX] = 0.0;  fM[kZY] = 0.0; fM[kZZ] = 1.0; fM[kDZ] = v.Z();
00201 }
00202 
00203 Plane3D Transform3D::operator() (const Plane3D & plane) const
00204 {
00205    // transformations on a 3D plane
00206    XYZVector n = plane.Normal();
00207    // take a point on the plane. Use origin projection on the plane
00208    // ( -ad, -bd, -cd) if (a**2 + b**2 + c**2 ) = 1
00209    double d = plane.HesseDistance();
00210    XYZPoint p( - d * n.X() , - d *n.Y(), -d *n.Z() );
00211    return Plane3D ( operator() (n), operator() (p) );
00212 }
00213 
00214 std::ostream & operator<< (std::ostream & os, const Transform3D & t)
00215 {
00216    // TODO - this will need changing for machine-readable issues
00217    //        and even the human readable form needs formatting improvements
00218    
00219    double m[12];
00220    t.GetComponents(m, m+12);
00221    os << "\n" << m[0] << "  " << m[1] << "  " << m[2] << "  " << m[3] ;
00222    os << "\n" << m[4] << "  " << m[5] << "  " << m[6] << "  " << m[7] ;
00223    os << "\n" << m[8] << "  " << m[9] << "  " << m[10]<< "  " << m[11] << "\n";
00224    return os;
00225 }
00226 
00227 }  // end namespace Math
00228 }  // end namespace ROOT

Generated on Tue Jul 5 14:33:07 2011 for ROOT_528-00b_version by  doxygen 1.5.1