CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
Transform3DPJ.cc
Go to the documentation of this file.
1 // @(#)root/mathcore:$Name: V02-02-29 $:$Id: Transform3DPJ.cc,v 1.2 2008/01/22 20:41:27 muzaffar Exp $
2 // Authors: W. Brown, M. Fischler, L. Moneta 2005
3 
4 /**********************************************************************
5  * *
6  * Copyright (c) 2005 , LCG ROOT MathLib Team *
7  * *
8  * *
9  **********************************************************************/
10 
11 // implementation file for class Transform3D
12 //
13 // Created by: Lorenzo Moneta October 27 2005
14 //
15 //
16 
18 #include "Math/GenVector/Plane3D.h"
19 
20 #include <cmath>
21 #include <algorithm>
22 
23 
24 
25 
26 namespace ROOT {
27 
28 namespace Math {
29 
30 
33 
34 
35 // ========== Constructors and Assignment =====================
36 
37 
38 
39 // construct from two ref frames
40 Transform3DPJ::Transform3DPJ(const XYZPoint & fr0, const XYZPoint & fr1, const XYZPoint & fr2,
41  const XYZPoint & to0, const XYZPoint & to1, const XYZPoint & to2 )
42 {
43  // takes impl. from CLHEP ( E.Chernyaev). To be checked
44 
45  XYZVector x1,y1,z1, x2,y2,z2;
46  x1 = (fr1 - fr0).Unit();
47  y1 = (fr2 - fr0).Unit();
48  x2 = (to1 - to0).Unit();
49  y2 = (to2 - to0).Unit();
50 
51  // C H E C K A N G L E S
52 
53  double cos1, cos2;
54  cos1 = x1.Dot(y1);
55  cos2 = x2.Dot(y2);
56 
57  if (std::fabs(1.0-cos1) <= 0.000001 || std::fabs(1.0-cos2) <= 0.000001) {
58  std::cerr << "Transform3DPJ: Error : zero angle between axes" << std::endl;
59  SetIdentity();
60  } else {
61  if (std::fabs(cos1-cos2) > 0.000001) {
62  std::cerr << "Transform3DPJ: Warning: angles between axes are not equal"
63  << std::endl;
64  }
65 
66  // F I N D R O T A T I O N M A T R I X
67 
68  z1 = (x1.Cross(y1)).Unit();
69  y1 = z1.Cross(x1);
70 
71  z2 = (x2.Cross(y2)).Unit();
72  y2 = z2.Cross(x2);
73 
74  double x1x = x1.X(), x1y = x1.Y(), x1z = x1.Z();
75  double y1x = y1.X(), y1y = y1.Y(), y1z = y1.Z();
76  double z1x = z1.X(), z1y = z1.Y(), z1z = z1.Z();
77 
78  double detxx = (y1y*z1z - z1y*y1z);
79  double detxy = -(y1x*z1z - z1x*y1z);
80  double detxz = (y1x*z1y - z1x*y1y);
81  double detyx = -(x1y*z1z - z1y*x1z);
82  double detyy = (x1x*z1z - z1x*x1z);
83  double detyz = -(x1x*z1y - z1x*x1y);
84  double detzx = (x1y*y1z - y1y*x1z);
85  double detzy = -(x1x*y1z - y1x*x1z);
86  double detzz = (x1x*y1y - y1x*x1y);
87 
88  double x2x = x2.X(), x2y = x2.Y(), x2z = x2.Z();
89  double y2x = y2.X(), y2y = y2.Y(), y2z = y2.Z();
90  double z2x = z2.X(), z2y = z2.Y(), z2z = z2.Z();
91 
92  double txx = x2x*detxx + y2x*detyx + z2x*detzx;
93  double txy = x2x*detxy + y2x*detyy + z2x*detzy;
94  double txz = x2x*detxz + y2x*detyz + z2x*detzz;
95  double tyx = x2y*detxx + y2y*detyx + z2y*detzx;
96  double tyy = x2y*detxy + y2y*detyy + z2y*detzy;
97  double tyz = x2y*detxz + y2y*detyz + z2y*detzz;
98  double tzx = x2z*detxx + y2z*detyx + z2z*detzx;
99  double tzy = x2z*detxy + y2z*detyy + z2z*detzy;
100  double tzz = x2z*detxz + y2z*detyz + z2z*detzz;
101 
102  // S E T T R A N S F O R M A T I O N
103 
104  double dx1 = fr0.X(), dy1 = fr0.Y(), dz1 = fr0.Z();
105  double dx2 = to0.X(), dy2 = to0.Y(), dz2 = to0.Z();
106 
107  SetComponents(txx, txy, txz, dx2-txx*dx1-txy*dy1-txz*dz1,
108  tyx, tyy, tyz, dy2-tyx*dx1-tyy*dy1-tyz*dz1,
109  tzx, tzy, tzz, dz2-tzx*dx1-tzy*dy1-tzz*dz1);
110  }
111 }
112 
113 
114 // inversion (from CLHEP)
116 {
117  //
118  // Name: Transform3DPJ::inverse Date: 24.09.96
119  // Author: E.Chernyaev (IHEP/Protvino) Revised:
120  //
121  // Function: Find inverse affine transformation.
122 
123  double detxx = fM[kYY]*fM[kZZ] - fM[kYZ]*fM[kZY];
124  double detxy = fM[kYX]*fM[kZZ] - fM[kYZ]*fM[kZX];
125  double detxz = fM[kYX]*fM[kZY] - fM[kYY]*fM[kZX];
126  double det = fM[kXX]*detxx - fM[kXY]*detxy + fM[kXZ]*detxz;
127  if (det == 0) {
128  std::cerr << "Transform3DPJ::inverse error: zero determinant" << std::endl;
129  return;
130  }
131  det = 1./det; detxx *= det; detxy *= det; detxz *= det;
132  double detyx = (fM[kXY]*fM[kZZ] - fM[kXZ]*fM[kZY] )*det;
133  double detyy = (fM[kXX]*fM[kZZ] - fM[kXZ]*fM[kZX] )*det;
134  double detyz = (fM[kXX]*fM[kZY] - fM[kXY]*fM[kZX] )*det;
135  double detzx = (fM[kXY]*fM[kYZ] - fM[kXZ]*fM[kYY] )*det;
136  double detzy = (fM[kXX]*fM[kYZ] - fM[kXZ]*fM[kYX] )*det;
137  double detzz = (fM[kXX]*fM[kYY] - fM[kXY]*fM[kYX] )*det;
139  (detxx, -detyx, detzx, -detxx*fM[kDX]+detyx*fM[kDY]-detzx*fM[kDZ],
140  -detxy, detyy, -detzy, detxy*fM[kDX]-detyy*fM[kDY]+detzy*fM[kDZ],
141  detxz, -detyz, detzz, -detxz*fM[kDX]+detyz*fM[kDY]-detzz*fM[kDZ]);
142 }
143 
144 
145 // get rotations and translations
146 void Transform3DPJ::GetDecomposition ( Rotation3D &r, XYZVector &v) const
147 {
148  // decompose a trasfomation in a 3D rotation and in a 3D vector (cartesian coordinates)
149  r.SetComponents( fM[kXX], fM[kXY], fM[kXZ],
150  fM[kYX], fM[kYY], fM[kYZ],
151  fM[kZX], fM[kZY], fM[kZZ] );
152 
153  v.SetCoordinates( fM[kDX], fM[kDY], fM[kDZ] );
154 }
155 
156 // transformation on Position Vector (rotation + translations)
158 {
159  // pass through rotation class (could be implemented directly to be faster)
160 
161  Rotation3D r;
162  XYZVector t;
163  GetDecomposition(r, t);
164  XYZPoint pnew = r(p);
165  pnew += t;
166  return pnew;
167 }
168 
169 // transformation on Displacement Vector (only rotation)
171 {
172  // pass through rotation class ( could be implemented directly to be faster)
173 
174  Rotation3D r;
175  XYZVector t;
176  GetDecomposition(r, t);
177  // only rotation
178  return r(v);
179 }
180 
182 {
183  // combination of transformations
184 
185  SetComponents(fM[kXX]*t.fM[kXX]+fM[kXY]*t.fM[kYX]+fM[kXZ]*t.fM[kZX],
186  fM[kXX]*t.fM[kXY]+fM[kXY]*t.fM[kYY]+fM[kXZ]*t.fM[kZY],
187  fM[kXX]*t.fM[kXZ]+fM[kXY]*t.fM[kYZ]+fM[kXZ]*t.fM[kZZ],
188  fM[kXX]*t.fM[kDX]+fM[kXY]*t.fM[kDY]+fM[kXZ]*t.fM[kDZ]+fM[kDX],
189 
190  fM[kYX]*t.fM[kXX]+fM[kYY]*t.fM[kYX]+fM[kYZ]*t.fM[kZX],
191  fM[kYX]*t.fM[kXY]+fM[kYY]*t.fM[kYY]+fM[kYZ]*t.fM[kZY],
192  fM[kYX]*t.fM[kXZ]+fM[kYY]*t.fM[kYZ]+fM[kYZ]*t.fM[kZZ],
193  fM[kYX]*t.fM[kDX]+fM[kYY]*t.fM[kDY]+fM[kYZ]*t.fM[kDZ]+fM[kDY],
194 
195  fM[kZX]*t.fM[kXX]+fM[kZY]*t.fM[kYX]+fM[kZZ]*t.fM[kZX],
196  fM[kZX]*t.fM[kXY]+fM[kZY]*t.fM[kYY]+fM[kZZ]*t.fM[kZY],
197  fM[kZX]*t.fM[kXZ]+fM[kZY]*t.fM[kYZ]+fM[kZZ]*t.fM[kZZ],
198  fM[kZX]*t.fM[kDX]+fM[kZY]*t.fM[kDY]+fM[kZZ]*t.fM[kDZ]+fM[kDZ]);
199 
200  return *this;
201 }
202 
204 {
205  //set identity ( identity rotation and zero translation)
206  fM[kXX] = 1.0; fM[kXY] = 0.0; fM[kXZ] = 0.0; fM[kDX] = 0.0;
207  fM[kYX] = 0.0; fM[kYY] = 1.0; fM[kYZ] = 0.0; fM[kDY] = 0.0;
208  fM[kZX] = 0.0; fM[kZY] = 0.0; fM[kZZ] = 1.0; fM[kDZ] = 0.0;
209 }
210 
211 
212 void Transform3DPJ::AssignFrom (const Rotation3D & r, const XYZVector & v)
213 {
214  // assignment from rotation + translation
215 
216  double rotData[9];
217  r.GetComponents(rotData, rotData +9);
218  // first raw
219  for (int i = 0; i < 3; ++i)
220  fM[i] = rotData[i];
221  // second raw
222  for (int i = 0; i < 3; ++i)
223  fM[kYX+i] = rotData[3+i];
224  // third raw
225  for (int i = 0; i < 3; ++i)
226  fM[kZX+i] = rotData[6+i];
227 
228  // translation data
229  double vecData[3];
230  v.GetCoordinates(vecData, vecData+3);
231  fM[kDX] = vecData[0];
232  fM[kDY] = vecData[1];
233  fM[kDZ] = vecData[2];
234 }
235 
236 
237 void Transform3DPJ::AssignFrom(const Rotation3D & r)
238 {
239  // assign from only a rotation (null translation)
240  double rotData[9];
241  r.GetComponents(rotData, rotData +9);
242  for (int i = 0; i < 3; ++i) {
243  for (int j = 0; j < 3; ++j)
244  fM[4*i + j] = rotData[3*i+j];
245  // empty vector data
246  fM[4*i + 3] = 0;
247  }
248 }
249 
251 {
252  // assign from a translation only (identity rotations)
253  fM[kXX] = 1.0; fM[kXY] = 0.0; fM[kXZ] = 0.0; fM[kDX] = v.X();
254  fM[kYX] = 0.0; fM[kYY] = 1.0; fM[kYZ] = 0.0; fM[kDY] = v.Y();
255  fM[kZX] = 0.0; fM[kZY] = 0.0; fM[kZZ] = 1.0; fM[kDZ] = v.Z();
256 }
257 
259 {
260  // transformations on a 3D plane
261  XYZVector n = plane.Normal();
262  // take a point on the plane. Use origin projection on the plane
263  // ( -ad, -bd, -cd) if (a**2 + b**2 + c**2 ) = 1
264  double d = plane.HesseDistance();
265  XYZPoint p( - d * n.X() , - d *n.Y(), -d *n.Z() );
266  return Plane3D ( operator() (n), operator() (p) );
267 }
268 
269 std::ostream & operator<< (std::ostream & os, const Transform3DPJ & t)
270 {
271  // TODO - this will need changing for machine-readable issues
272  // and even the human readable form needs formatiing improvements
273 
274  double m[12];
275  t.GetComponents(m, m+12);
276  os << "\n" << m[0] << " " << m[1] << " " << m[2] << " " << m[3] ;
277  os << "\n" << m[4] << " " << m[5] << " " << m[6] << " " << m[7] ;
278  os << "\n" << m[8] << " " << m[9] << " " << m[10]<< " " << m[11] << "\n";
279  return os;
280 }
281 
282 } // end namespace Math
283 } // end namespace ROOT
void AssignFrom(const Rotation3D &r, const Vector &v)
int i
Definition: DBlmapReader.cc:9
PositionVector3D< Cartesian3D< double >, DefaultCoordinateSystemTag > Point
Definition: Transform3DPJ.h:66
DisplacementVector3D< Cartesian3D< double >, DefaultCoordinateSystemTag > Vector
Definition: Transform3DPJ.h:65
Transform3DPJ & operator*=(const Transform3DPJ &t)
std::ostream & operator<<(std::ostream &os, const Transform3DPJ &t)
int j
Definition: DBlmapReader.cc:9
Transform3DPJ::Vector XYZVector
void SetComponents(IT begin, IT end)
void GetDecomposition(Rotation3D &r, Vector &v) const
Transform3DPJ::Point XYZPoint
void GetComponents(IT begin, IT end) const
ROOT::Math::Plane3D Plane3D
Point operator()(const Point &p) const