2 // ********************************************************************
3 // * License and Disclaimer *
5 // * The Geant4 software is copyright of the Copyright Holders of *
6 // * the Geant4 Collaboration. It is provided under the terms and *
7 // * conditions of the Geant4 Software License, included in the file *
8 // * LICENSE and available at http://cern.ch/geant4/license . These *
9 // * include a list of copyright holders. *
11 // * Neither the authors of this software system, nor their employing *
12 // * institutes,nor the agencies providing financial support for this *
13 // * work make any representation or warranty, express or implied, *
14 // * regarding this software system or assume any liability for its *
15 // * use. Please see the license in the file LICENSE and URL above *
16 // * for the full disclaimer and the limitation of liability. *
18 // * This code implementation is the result of the scientific and *
19 // * technical work of the GEANT4 collaboration. *
20 // * By using, copying, modifying or distributing the software (or *
21 // * any work based on the software) you agree to acknowledge its *
22 // * use in resulting scientific publications, and indicate your *
23 // * acceptance of all terms of the Geant4 Software license. *
24 // ********************************************************************
27 // $Id: G4AffineTransform.icc 90701 2015-06-08 09:43:16Z gcosmo $
30 // G4AffineTransformation Inline implementation
32 // --------------------------------------------------------------------
34 inline G4AffineTransform::G4AffineTransform()
35 : rxx(1),rxy(0),rxz(0),
41 inline G4AffineTransform::G4AffineTransform(const G4ThreeVector& tlate)
42 : rxx(1),rxy(0),rxz(0),
45 tx(tlate.x()),ty(tlate.y()),tz(tlate.z())
48 inline G4AffineTransform::G4AffineTransform(const G4RotationMatrix& rot)
49 : rxx(rot.xx()),rxy(rot.xy()),rxz(rot.xz()),
50 ryx(rot.yx()),ryy(rot.yy()),ryz(rot.yz()),
51 rzx(rot.zx()),rzy(rot.zy()),rzz(rot.zz()),
55 inline G4AffineTransform::G4AffineTransform( const G4RotationMatrix& rot,
56 const G4ThreeVector& tlate )
57 : rxx(rot.xx()),rxy(rot.xy()),rxz(rot.xz()),
58 ryx(rot.yx()),ryy(rot.yy()),ryz(rot.yz()),
59 rzx(rot.zx()),rzy(rot.zy()),rzz(rot.zz()),
60 tx(tlate.x()),ty(tlate.y()),tz(tlate.z())
63 inline G4AffineTransform::G4AffineTransform( const G4RotationMatrix *rot,
64 const G4ThreeVector& tlate)
65 : tx(tlate.x()),ty(tlate.y()),tz(tlate.z())
69 rxx=rot->xx();rxy=rot->xy();rxz=rot->xz();
70 ryx=rot->yx();ryy=rot->yy();ryz=rot->yz();
71 rzx=rot->zx();rzy=rot->zy();rzz=rot->zz();
83 G4AffineTransform( const G4double prxx,const G4double prxy,const G4double prxz,
84 const G4double pryx,const G4double pryy,const G4double pryz,
85 const G4double przx,const G4double przy,const G4double przz,
86 const G4double ptx,const G4double pty,const G4double ptz)
87 : rxx(prxx),rxy(prxy),rxz(prxz),
88 ryx(pryx),ryy(pryy),ryz(pryz),
89 rzx(przx),rzy(przy),rzz(przz),
90 tx(ptx),ty(pty),tz(ptz)
93 inline G4AffineTransform
94 G4AffineTransform::operator * (const G4AffineTransform& tf) const
96 return G4AffineTransform(
97 rxx*tf.rxx+rxy*tf.ryx+rxz*tf.rzx,
98 rxx*tf.rxy+rxy*tf.ryy+rxz*tf.rzy,
99 rxx*tf.rxz+rxy*tf.ryz+rxz*tf.rzz,
101 ryx*tf.rxx+ryy*tf.ryx+ryz*tf.rzx,
102 ryx*tf.rxy+ryy*tf.ryy+ryz*tf.rzy,
103 ryx*tf.rxz+ryy*tf.ryz+ryz*tf.rzz,
105 rzx*tf.rxx+rzy*tf.ryx+rzz*tf.rzx,
106 rzx*tf.rxy+rzy*tf.ryy+rzz*tf.rzy,
107 rzx*tf.rxz+rzy*tf.ryz+rzz*tf.rzz,
109 tx*tf.rxx+ty*tf.ryx+tz*tf.rzx+tf.tx,
110 tx*tf.rxy+ty*tf.ryy+tz*tf.rzy+tf.ty,
111 tx*tf.rxz+ty*tf.ryz+tz*tf.rzz+tf.tz);
114 inline G4AffineTransform&
115 G4AffineTransform::operator *= (const G4AffineTransform& tf)
117 // Use temporaries for `in place' compound transform computation
119 G4double nrxx=rxx*tf.rxx+rxy*tf.ryx+rxz*tf.rzx;
120 G4double nrxy=rxx*tf.rxy+rxy*tf.ryy+rxz*tf.rzy;
121 G4double nrxz=rxx*tf.rxz+rxy*tf.ryz+rxz*tf.rzz;
123 G4double nryx=ryx*tf.rxx+ryy*tf.ryx+ryz*tf.rzx;
124 G4double nryy=ryx*tf.rxy+ryy*tf.ryy+ryz*tf.rzy;
125 G4double nryz=ryx*tf.rxz+ryy*tf.ryz+ryz*tf.rzz;
127 G4double nrzx=rzx*tf.rxx+rzy*tf.ryx+rzz*tf.rzx;
128 G4double nrzy=rzx*tf.rxy+rzy*tf.ryy+rzz*tf.rzy;
129 G4double nrzz=rzx*tf.rxz+rzy*tf.ryz+rzz*tf.rzz;
131 G4double ntx=tx*tf.rxx+ty*tf.ryx+tz*tf.rzx+tf.tx;
132 G4double nty=tx*tf.rxy+ty*tf.ryy+tz*tf.rzy+tf.ty;
133 G4double ntz=tx*tf.rxz+ty*tf.ryz+tz*tf.rzz+tf.tz;
135 tx=ntx; ty=nty; tz=ntz;
136 rxx=nrxx; rxy=nrxy; rxz=nrxz;
137 ryx=nryx; ryy=nryy; ryz=nryz;
138 rzx=nrzx; rzy=nrzy; rzz=nrzz;
143 inline G4AffineTransform&
144 G4AffineTransform::Product(const G4AffineTransform& tf1,
145 const G4AffineTransform& tf2)
147 rxx=tf1.rxx*tf2.rxx + tf1.rxy*tf2.ryx + tf1.rxz*tf2.rzx;
148 rxy=tf1.rxx*tf2.rxy + tf1.rxy*tf2.ryy + tf1.rxz*tf2.rzy;
149 rxz=tf1.rxx*tf2.rxz + tf1.rxy*tf2.ryz + tf1.rxz*tf2.rzz;
151 ryx=tf1.ryx*tf2.rxx + tf1.ryy*tf2.ryx + tf1.ryz*tf2.rzx;
152 ryy=tf1.ryx*tf2.rxy + tf1.ryy*tf2.ryy + tf1.ryz*tf2.rzy;
153 ryz=tf1.ryx*tf2.rxz + tf1.ryy*tf2.ryz + tf1.ryz*tf2.rzz;
155 rzx=tf1.rzx*tf2.rxx + tf1.rzy*tf2.ryx + tf1.rzz*tf2.rzx;
156 rzy=tf1.rzx*tf2.rxy + tf1.rzy*tf2.ryy + tf1.rzz*tf2.rzy;
157 rzz=tf1.rzx*tf2.rxz + tf1.rzy*tf2.ryz + tf1.rzz*tf2.rzz;
159 tx=tf1.tx*tf2.rxx + tf1.ty*tf2.ryx + tf1.tz*tf2.rzx + tf2.tx;
160 ty=tf1.tx*tf2.rxy + tf1.ty*tf2.ryy + tf1.tz*tf2.rzy + tf2.ty;
161 tz=tf1.tx*tf2.rxz + tf1.ty*tf2.ryz + tf1.tz*tf2.rzz + tf2.tz;
166 inline G4AffineTransform&
167 G4AffineTransform::InverseProduct( const G4AffineTransform& tf1,
168 const G4AffineTransform& tf2)
170 G4double itf2tx = - tf2.tx*tf2.rxx - tf2.ty*tf2.rxy - tf2.tz*tf2.rxz;
171 G4double itf2ty = - tf2.tx*tf2.ryx - tf2.ty*tf2.ryy - tf2.tz*tf2.ryz;
172 G4double itf2tz = - tf2.tx*tf2.rzx - tf2.ty*tf2.rzy - tf2.tz*tf2.rzz;
174 rxx=tf1.rxx*tf2.rxx+tf1.rxy*tf2.rxy+tf1.rxz*tf2.rxz;
175 rxy=tf1.rxx*tf2.ryx+tf1.rxy*tf2.ryy+tf1.rxz*tf2.ryz;
176 rxz=tf1.rxx*tf2.rzx+tf1.rxy*tf2.rzy+tf1.rxz*tf2.rzz;
178 ryx=tf1.ryx*tf2.rxx+tf1.ryy*tf2.rxy+tf1.ryz*tf2.rxz;
179 ryy=tf1.ryx*tf2.ryx+tf1.ryy*tf2.ryy+tf1.ryz*tf2.ryz;
180 ryz=tf1.ryx*tf2.rzx+tf1.ryy*tf2.rzy+tf1.ryz*tf2.rzz;
182 rzx=tf1.rzx*tf2.rxx+tf1.rzy*tf2.rxy+tf1.rzz*tf2.rxz;
183 rzy=tf1.rzx*tf2.ryx+tf1.rzy*tf2.ryy+tf1.rzz*tf2.ryz;
184 rzz=tf1.rzx*tf2.rzx+tf1.rzy*tf2.rzy+tf1.rzz*tf2.rzz;
186 tx=tf1.tx*tf2.rxx+tf1.ty*tf2.rxy+tf1.tz*tf2.rxz+itf2tx;
187 ty=tf1.tx*tf2.ryx+tf1.ty*tf2.ryy+tf1.tz*tf2.ryz+itf2ty;
188 tz=tf1.tx*tf2.rzx+tf1.ty*tf2.rzy+tf1.tz*tf2.rzz+itf2tz;
194 G4ThreeVector G4AffineTransform::TransformPoint(const G4ThreeVector& vec) const
196 return G4ThreeVector( vec.x()*rxx + vec.y()*ryx + vec.z()*rzx + tx,
197 vec.x()*rxy + vec.y()*ryy + vec.z()*rzy + ty,
198 vec.x()*rxz + vec.y()*ryz + vec.z()*rzz + tz );
202 G4ThreeVector G4AffineTransform::TransformAxis(const G4ThreeVector& axis) const
204 return G4ThreeVector( axis.x()*rxx + axis.y()*ryx + axis.z()*rzx,
205 axis.x()*rxy + axis.y()*ryy + axis.z()*rzy,
206 axis.x()*rxz + axis.y()*ryz + axis.z()*rzz );
210 void G4AffineTransform::ApplyPointTransform(G4ThreeVector& vec) const
212 G4double x = vec.x()*rxx + vec.y()*ryx + vec.z()*rzx + tx;
213 G4double y = vec.x()*rxy + vec.y()*ryy + vec.z()*rzy + ty;
214 G4double z = vec.x()*rxz + vec.y()*ryz + vec.z()*rzz + tz;
222 void G4AffineTransform::ApplyAxisTransform(G4ThreeVector& axis) const
224 G4double x = axis.x()*rxx + axis.y()*ryx + axis.z()*rzx;
225 G4double y = axis.x()*rxy + axis.y()*ryy + axis.z()*rzy;
226 G4double z = axis.x()*rxz + axis.y()*ryz + axis.z()*rzz;
234 G4AffineTransform G4AffineTransform::Inverse() const
236 return G4AffineTransform( rxx, ryx, rzx,
240 -tx*rxx - ty*rxy - tz*rxz,
241 -tx*ryx - ty*ryy - tz*ryz,
242 -tx*rzx - ty*rzy - tz*rzz );
246 G4AffineTransform& G4AffineTransform::Invert()
248 G4double v1 = -tx*rxx - ty*rxy - tz*rxz;
249 G4double v2 = -tx*ryx - ty*ryy - tz*ryz;
250 G4double v3 = -tx*rzx - ty*rzy - tz*rzz;
254 G4double tmp1=ryx; ryx=rxy; rxy=tmp1;
255 G4double tmp2=rzx; rzx=rxz; rxz=tmp2;
256 G4double tmp3=rzy; rzy=ryz; ryz=tmp3;
263 G4AffineTransform& G4AffineTransform::operator +=(const G4ThreeVector& tlate)
273 G4AffineTransform& G4AffineTransform::operator -=(const G4ThreeVector& tlate)
283 G4bool G4AffineTransform::operator == (const G4AffineTransform& tf) const
285 return (tx==tf.tx&&ty==tf.ty&&tz==tf.tz&&
286 rxx==tf.rxx&&rxy==tf.rxy&&rxz==tf.rxz&&
287 ryx==tf.ryx&&ryy==tf.ryy&&ryz==tf.ryz&&
288 rzx==tf.rzx&&rzy==tf.rzy&&rzz==tf.rzz) ? true : false;
291 G4bool G4AffineTransform::operator != (const G4AffineTransform& tf) const
293 return (tx!=tf.tx||ty!=tf.ty||tz!=tf.tz||
294 rxx!=tf.rxx||rxy!=tf.rxy||rxz!=tf.rxz||
295 ryx!=tf.ryx||ryy!=tf.ryy||ryz!=tf.ryz||
296 rzx!=tf.rzx||rzy!=tf.rzy||rzz!=tf.rzz) ? true : false;
300 G4double G4AffineTransform::operator [] (const G4int n) const
353 G4bool G4AffineTransform::IsRotated() const
355 return (rxx==1.0 && ryy==1.0 && rzz==1.0) ? false : true;
359 G4bool G4AffineTransform::IsTranslated() const
361 return (tx || ty || tz) ? true:false;
364 inline G4RotationMatrix G4AffineTransform::NetRotation() const {
365 G4RotationMatrix mat;
366 return mat.rotateAxes(G4ThreeVector(rxx,ryx,rzx),
367 G4ThreeVector(rxy,ryy,rzy),
368 G4ThreeVector(rxz,ryz,rzz));
372 G4ThreeVector G4AffineTransform::NetTranslation() const
374 return G4ThreeVector(tx,ty,tz);
378 void G4AffineTransform::SetNetRotation(const G4RotationMatrix& rot)
392 void G4AffineTransform::SetNetTranslation(const G4ThreeVector& tlate)
401 operator << (std::ostream &os, const G4AffineTransform &transf)
404 int oldPrec= os.precision(6);
405 double DeviationTolerance= 1.0e-05;
407 double diagDeviation= 0.0;
408 double offdDeviationUL= 0.0;
409 double offdDeviationDR= 0.0;
410 double offdDeviation= 0.0;
412 os << " Transformation: " << G4endl;
414 // double a = std::max ( 1, 2, 3 ) ;
416 bool UnitTr = ! transf.IsRotated();
417 diagDeviation= std::max ( std::fabs( transf[0] - 1.0 ) , // | rxx - 1 |
418 std::fabs( transf[5] - 1.0 ) ); // | ryy - 1 |
419 diagDeviation= std::max ( diagDeviation,
420 std::fabs( transf[10] - 1.0 ) ); // | rzz - 1 |
422 offdDeviationUL= std::max ( std::fabs( transf[1] ) , // | rxy |
423 std::fabs( transf[2] ) ); // | rxz |
424 offdDeviationUL= std::max ( offdDeviationUL,
425 std::fabs( transf[4] ) ); // | ryx |
427 offdDeviationDR= std::max ( std::fabs( transf[6] ) , // | ryz |
428 std::fabs( transf[8] ) ); // | rzx |
429 offdDeviationDR= std::max ( offdDeviationDR,
430 std::fabs( transf[9] ) ); // | rzy |
431 offdDeviation= std::max( offdDeviationUL, offdDeviationDR );
433 if( UnitTr || std::max( diagDeviation, offdDeviation ) < DeviationTolerance ) {
434 os << " UNIT Rotation " << G4endl;
436 // os << " " << transf[0] << " " << transf[1] << " " << transf[2] << G4endl
437 // << " " << transf[4] << " " << transf[5] << " " << transf[6] << G4endl
438 // << " " << transf[8] << " " << transf[9] << " " << transf[10] << G4endl
439 // << " " << transf[12] << " " << transf[13] << " " << transf[14] << G4endl
441 sprintf( buffer, "rx/x,y,z %10.6f %10.6f %10.6f ", transf[0], transf[1], transf[2] );
442 os << buffer << G4endl;
443 sprintf( buffer, "ry/x,y,z %10.6f %10.6f %10.6f ", transf[4], transf[5], transf[6] );
444 os << buffer << G4endl;
445 sprintf( buffer, "rz/x,y,z %10.6f %10.6f %10.6f ", transf[8], transf[9], transf[10] );
446 os << buffer << G4endl;
449 sprintf( buffer, "tr/x,y,z %10.6f %10.6f %10.6f ", transf[12], transf[13], transf[14] );
450 os << buffer << G4endl;
452 os.precision(oldPrec);