00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
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
00037
00038
00039
00040
00041 Transform3D::Transform3D(const XYZPoint & fr0, const XYZPoint & fr1, const XYZPoint & fr2,
00042 const XYZPoint & to0, const XYZPoint & to1, const XYZPoint & to2 )
00043 {
00044
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
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
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
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
00116 void Transform3D::Invert()
00117 {
00118
00119
00120
00121
00122
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
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
00160
00161 double rotData[9];
00162 r.GetComponents(rotData, rotData +9);
00163
00164 for (int i = 0; i < 3; ++i)
00165 fM[i] = rotData[i];
00166
00167 for (int i = 0; i < 3; ++i)
00168 fM[kYX+i] = rotData[3+i];
00169
00170 for (int i = 0; i < 3; ++i)
00171 fM[kZX+i] = rotData[6+i];
00172
00173
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
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
00191 fM[4*i + 3] = 0;
00192 }
00193 }
00194
00195 void Transform3D::AssignFrom(const XYZVector & v)
00196 {
00197
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
00206 XYZVector n = plane.Normal();
00207
00208
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
00217
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 }
00228 }