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 98309 2016-07-06 10:30:15Z 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
366 return G4Rep3x3(rxx,rxy,rxz,
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)
400 G4AffineTransform::operator G4Transform3D () const
402 return G4Transform3D(NetRotation().inverse(),NetTranslation());
406 std::ostream& operator << (std::ostream& os, const G4AffineTransform& transf)
408 std::streamsize oldPrec = os.precision(6);
409 G4double DeviationTolerance = 1.0e-05;
411 G4double diagDeviation = 0.0;
412 G4double offdDeviationUL = 0.0;
413 G4double offdDeviationDR = 0.0;
414 G4double offdDeviation = 0.0;
416 os << " Transformation: " << G4endl;
418 // double a = std::max ( 1, 2, 3 ) ;
420 G4bool UnitTr = ! transf.IsRotated();
421 diagDeviation = std::max( std::fabs( transf[0] - 1.0 ) , // |rxx - 1|
422 std::fabs( transf[5] - 1.0 ) ); // |ryy - 1|
423 diagDeviation = std::max( diagDeviation,
424 std::fabs( transf[10] - 1.0 ) ); // |rzz - 1|
426 offdDeviationUL = std::max( std::fabs( transf[1] ) , // |rxy|
427 std::fabs( transf[2] ) ); // |rxz|
428 offdDeviationUL = std::max( offdDeviationUL,
429 std::fabs( transf[4] ) ); // |ryx|
431 offdDeviationDR = std::max( std::fabs( transf[6] ) , // |ryz|
432 std::fabs( transf[8] ) ); // |rzx|
433 offdDeviationDR = std::max( offdDeviationDR,
434 std::fabs( transf[9] ) ); // |rzy|
435 offdDeviation = std::max( offdDeviationUL, offdDeviationDR );
437 if( UnitTr || std::max(diagDeviation, offdDeviation) < DeviationTolerance )
439 os << " UNIT Rotation " << G4endl;
444 << transf[0] << " " << transf[1] << " " << transf[2] << G4endl
446 << transf[4] << " " << transf[5] << " " << transf[6] << G4endl
448 << transf[8] << " " << transf[9] << " " << transf[10] << G4endl;
451 os << "tr/x,y,z: " << transf[12] << " " << transf[13] << " " << transf[14]
454 os.precision(oldPrec);