Geant4-11
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
G4AffineTransform.icc
Go to the documentation of this file.
1//
2// ********************************************************************
3// * License and Disclaimer *
4// * *
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. *
10// * *
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. *
17// * *
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// ********************************************************************
25//
26// G4AffineTransformation Inline implementation
27//
28// --------------------------------------------------------------------
29
30inline G4AffineTransform::G4AffineTransform()
31 : rxx(1),rxy(0),rxz(0),
32 ryx(0),ryy(1),ryz(0),
33 rzx(0),rzy(0),rzz(1),
34 tx(0),ty(0),tz(0)
35{}
36
37inline G4AffineTransform::G4AffineTransform(const G4ThreeVector& tlate)
38 : rxx(1),rxy(0),rxz(0),
39 ryx(0),ryy(1),ryz(0),
40 rzx(0),rzy(0),rzz(1),
41 tx(tlate.x()),ty(tlate.y()),tz(tlate.z())
42{}
43
44inline G4AffineTransform::G4AffineTransform(const G4RotationMatrix& rot)
45 : rxx(rot.xx()),rxy(rot.xy()),rxz(rot.xz()),
46 ryx(rot.yx()),ryy(rot.yy()),ryz(rot.yz()),
47 rzx(rot.zx()),rzy(rot.zy()),rzz(rot.zz()),
48 tx(0),ty(0),tz(0)
49{}
50
51inline G4AffineTransform::G4AffineTransform( const G4RotationMatrix& rot,
52 const G4ThreeVector& tlate )
53 : rxx(rot.xx()),rxy(rot.xy()),rxz(rot.xz()),
54 ryx(rot.yx()),ryy(rot.yy()),ryz(rot.yz()),
55 rzx(rot.zx()),rzy(rot.zy()),rzz(rot.zz()),
56 tx(tlate.x()),ty(tlate.y()),tz(tlate.z())
57{}
58
59inline G4AffineTransform::G4AffineTransform( const G4RotationMatrix* rot,
60 const G4ThreeVector& tlate )
61 : tx(tlate.x()),ty(tlate.y()),tz(tlate.z())
62{
63 if (rot != nullptr)
64 {
65 rxx=rot->xx();rxy=rot->xy();rxz=rot->xz();
66 ryx=rot->yx();ryy=rot->yy();ryz=rot->yz();
67 rzx=rot->zx();rzy=rot->zy();rzz=rot->zz();
68 }
69 else
70 {
71 rxx=1; rxy=0; rxz=0;
72 ryx=0; ryy=1; ryz=0;
73 rzx=0; rzy=0; rzz=1;
74 }
75}
76
77inline
78G4AffineTransform::
79G4AffineTransform( const G4double prxx,const G4double prxy,const G4double prxz,
80 const G4double pryx,const G4double pryy,const G4double pryz,
81 const G4double przx,const G4double przy,const G4double przz,
82 const G4double ptx,const G4double pty,const G4double ptz )
83 : rxx(prxx),rxy(prxy),rxz(prxz),
84 ryx(pryx),ryy(pryy),ryz(pryz),
85 rzx(przx),rzy(przy),rzz(przz),
86 tx(ptx),ty(pty),tz(ptz)
87{}
88
89inline G4AffineTransform&
90G4AffineTransform::operator = (const G4AffineTransform& rhs)
91{
92 if (this == &rhs) { return *this; }
93 rxx = rhs.rxx; rxy = rhs.rxy; rxz = rhs.rxz;
94 ryx = rhs.ryx; ryy = rhs.ryy; ryz = rhs.ryz;
95 rzx = rhs.rzx; rzy = rhs.rzy; rzz = rhs.rzz;
96 tx = rhs.tx; ty = rhs.ty; tz = rhs.tz;
97 return *this;
98}
99
100inline G4AffineTransform
101G4AffineTransform::operator * (const G4AffineTransform& tf) const
102{
103 return G4AffineTransform(rxx*tf.rxx+rxy*tf.ryx+rxz*tf.rzx,
104 rxx*tf.rxy+rxy*tf.ryy+rxz*tf.rzy,
105 rxx*tf.rxz+rxy*tf.ryz+rxz*tf.rzz,
106
107 ryx*tf.rxx+ryy*tf.ryx+ryz*tf.rzx,
108 ryx*tf.rxy+ryy*tf.ryy+ryz*tf.rzy,
109 ryx*tf.rxz+ryy*tf.ryz+ryz*tf.rzz,
110
111 rzx*tf.rxx+rzy*tf.ryx+rzz*tf.rzx,
112 rzx*tf.rxy+rzy*tf.ryy+rzz*tf.rzy,
113 rzx*tf.rxz+rzy*tf.ryz+rzz*tf.rzz,
114
115 tx*tf.rxx+ty*tf.ryx+tz*tf.rzx+tf.tx,
116 tx*tf.rxy+ty*tf.ryy+tz*tf.rzy+tf.ty,
117 tx*tf.rxz+ty*tf.ryz+tz*tf.rzz+tf.tz);
118}
119
120inline G4AffineTransform&
121G4AffineTransform::operator *= (const G4AffineTransform& tf)
122{
123 // Use temporaries for `in place' compound transform computation
124 //
125 G4double nrxx=rxx*tf.rxx+rxy*tf.ryx+rxz*tf.rzx;
126 G4double nrxy=rxx*tf.rxy+rxy*tf.ryy+rxz*tf.rzy;
127 G4double nrxz=rxx*tf.rxz+rxy*tf.ryz+rxz*tf.rzz;
128
129 G4double nryx=ryx*tf.rxx+ryy*tf.ryx+ryz*tf.rzx;
130 G4double nryy=ryx*tf.rxy+ryy*tf.ryy+ryz*tf.rzy;
131 G4double nryz=ryx*tf.rxz+ryy*tf.ryz+ryz*tf.rzz;
132
133 G4double nrzx=rzx*tf.rxx+rzy*tf.ryx+rzz*tf.rzx;
134 G4double nrzy=rzx*tf.rxy+rzy*tf.ryy+rzz*tf.rzy;
135 G4double nrzz=rzx*tf.rxz+rzy*tf.ryz+rzz*tf.rzz;
136
137 G4double ntx=tx*tf.rxx+ty*tf.ryx+tz*tf.rzx+tf.tx;
138 G4double nty=tx*tf.rxy+ty*tf.ryy+tz*tf.rzy+tf.ty;
139 G4double ntz=tx*tf.rxz+ty*tf.ryz+tz*tf.rzz+tf.tz;
140
141 tx=ntx; ty=nty; tz=ntz;
142 rxx=nrxx; rxy=nrxy; rxz=nrxz;
143 ryx=nryx; ryy=nryy; ryz=nryz;
144 rzx=nrzx; rzy=nrzy; rzz=nrzz;
145
146 return *this;
147}
148
149inline G4AffineTransform&
150G4AffineTransform::Product( const G4AffineTransform& tf1,
151 const G4AffineTransform& tf2 )
152{
153 rxx = tf1.rxx*tf2.rxx + tf1.rxy*tf2.ryx + tf1.rxz*tf2.rzx;
154 rxy = tf1.rxx*tf2.rxy + tf1.rxy*tf2.ryy + tf1.rxz*tf2.rzy;
155 rxz = tf1.rxx*tf2.rxz + tf1.rxy*tf2.ryz + tf1.rxz*tf2.rzz;
156
157 ryx = tf1.ryx*tf2.rxx + tf1.ryy*tf2.ryx + tf1.ryz*tf2.rzx;
158 ryy = tf1.ryx*tf2.rxy + tf1.ryy*tf2.ryy + tf1.ryz*tf2.rzy;
159 ryz = tf1.ryx*tf2.rxz + tf1.ryy*tf2.ryz + tf1.ryz*tf2.rzz;
160
161 rzx = tf1.rzx*tf2.rxx + tf1.rzy*tf2.ryx + tf1.rzz*tf2.rzx;
162 rzy = tf1.rzx*tf2.rxy + tf1.rzy*tf2.ryy + tf1.rzz*tf2.rzy;
163 rzz = tf1.rzx*tf2.rxz + tf1.rzy*tf2.ryz + tf1.rzz*tf2.rzz;
164
165 tx = tf1.tx*tf2.rxx + tf1.ty*tf2.ryx + tf1.tz*tf2.rzx + tf2.tx;
166 ty = tf1.tx*tf2.rxy + tf1.ty*tf2.ryy + tf1.tz*tf2.rzy + tf2.ty;
167 tz = tf1.tx*tf2.rxz + tf1.ty*tf2.ryz + tf1.tz*tf2.rzz + tf2.tz;
168
169 return *this;
170}
171
172inline G4AffineTransform&
173G4AffineTransform::InverseProduct( const G4AffineTransform& tf1,
174 const G4AffineTransform& tf2 )
175{
176 if ((tf2.rxx + tf2.ryy + tf2.rzz) == 3.)
177 {
178 rxx = tf1.rxx;
179 rxy = tf1.rxy;
180 rxz = tf1.rxz;
181
182 ryx = tf1.ryx;
183 ryy = tf1.ryy;
184 ryz = tf1.ryz;
185
186 rzx = tf1.rzx;
187 rzy = tf1.rzy;
188 rzz = tf1.rzz;
189
190 tx = tf1.tx - tf2.tx;
191 ty = tf1.ty - tf2.ty;
192 tz = tf1.tz - tf2.tz;
193 }
194 else
195 {
196 G4double tf1rxx = tf1.rxx, tf1rxy = tf1.rxy, tf1rxz = tf1.rxz;
197 rxx = tf1rxx*tf2.rxx + tf1rxy*tf2.rxy + tf1rxz*tf2.rxz;
198 rxy = tf1rxx*tf2.ryx + tf1rxy*tf2.ryy + tf1rxz*tf2.ryz;
199 rxz = tf1rxx*tf2.rzx + tf1rxy*tf2.rzy + tf1rxz*tf2.rzz;
200
201 G4double tf1ryx = tf1.ryx, tf1ryy = tf1.ryy, tf1ryz = tf1.ryz;
202 ryx = tf1ryx*tf2.rxx + tf1ryy*tf2.rxy + tf1ryz*tf2.rxz;
203 ryy = tf1ryx*tf2.ryx + tf1ryy*tf2.ryy + tf1ryz*tf2.ryz;
204 ryz = tf1ryx*tf2.rzx + tf1ryy*tf2.rzy + tf1ryz*tf2.rzz;
205
206 G4double tf1rzx = tf1.rzx, tf1rzy = tf1.rzy, tf1rzz = tf1.rzz;
207 rzx = tf1rzx*tf2.rxx + tf1rzy*tf2.rxy + tf1rzz*tf2.rxz;
208 rzy = tf1rzx*tf2.ryx + tf1rzy*tf2.ryy + tf1rzz*tf2.ryz;
209 rzz = tf1rzx*tf2.rzx + tf1rzy*tf2.rzy + tf1rzz*tf2.rzz;
210
211 G4double tf1_2tx = tf1.tx - tf2.tx;
212 G4double tf1_2ty = tf1.ty - tf2.ty;
213 G4double tf1_2tz = tf1.tz - tf2.tz;
214 tx = tf1_2tx*tf2.rxx + tf1_2ty*tf2.rxy + tf1_2tz*tf2.rxz;
215 ty = tf1_2tx*tf2.ryx + tf1_2ty*tf2.ryy + tf1_2tz*tf2.ryz;
216 tz = tf1_2tx*tf2.rzx + tf1_2ty*tf2.rzy + tf1_2tz*tf2.rzz;
217 }
218 return *this;
219}
220
221inline G4ThreeVector
222G4AffineTransform::TransformPoint(const G4ThreeVector& vec) const
223{
224 G4double vecx = vec.x(), vecy = vec.y(), vecz = vec.z();
225 return G4ThreeVector( vecx*rxx + vecy*ryx + vecz*rzx + tx,
226 vecx*rxy + vecy*ryy + vecz*rzy + ty,
227 vecx*rxz + vecy*ryz + vecz*rzz + tz );
228}
229
230inline G4ThreeVector
231G4AffineTransform::InverseTransformPoint(const G4ThreeVector& vec) const
232{
233 G4double vecx = vec.x()-tx, vecy = vec.y()-ty, vecz = vec.z()-tz;
234 return G4ThreeVector( vecx*rxx + vecy*rxy + vecz*rxz,
235 vecx*ryx + vecy*ryy + vecz*ryz,
236 vecx*rzx + vecy*rzy + vecz*rzz );
237}
238
239inline G4ThreeVector
240G4AffineTransform::TransformAxis(const G4ThreeVector& axis) const
241{
242 G4double axisx = axis.x(), axisy = axis.y(), axisz = axis.z();
243 return G4ThreeVector( axisx*rxx + axisy*ryx + axisz*rzx,
244 axisx*rxy + axisy*ryy + axisz*rzy,
245 axisx*rxz + axisy*ryz + axisz*rzz );
246}
247
248inline G4ThreeVector
249G4AffineTransform::InverseTransformAxis(const G4ThreeVector& axis) const
250{
251 G4double axisx = axis.x(), axisy = axis.y(), axisz = axis.z();
252 return G4ThreeVector( axisx*rxx + axisy*rxy + axisz*rxz,
253 axisx*ryx + axisy*ryy + axisz*ryz,
254 axisx*rzx + axisy*rzy + axisz*rzz );
255}
256
257inline
258void G4AffineTransform::ApplyPointTransform(G4ThreeVector& vec) const
259{
260 G4double vecx = vec.x(), vecy = vec.y(), vecz = vec.z();
261 vec.setX( vecx*rxx + vecy*ryx + vecz*rzx + tx );
262 vec.setY( vecx*rxy + vecy*ryy + vecz*rzy + ty );
263 vec.setZ( vecx*rxz + vecy*ryz + vecz*rzz + tz );
264}
265
266inline
267void G4AffineTransform::ApplyAxisTransform(G4ThreeVector& axis) const
268{
269 G4double axisx = axis.x(), axisy = axis.y(), axisz = axis.z();
270 axis.setX( axisx*rxx + axisy*ryx + axisz*rzx );
271 axis.setY( axisx*rxy + axisy*ryy + axisz*rzy );
272 axis.setZ( axisx*rxz + axisy*ryz + axisz*rzz );
273}
274
275inline
276G4AffineTransform G4AffineTransform::Inverse() const
277{
278 G4double ttx = -tx, tty = -ty, ttz = -tz;
279 return G4AffineTransform( rxx, ryx, rzx,
280 rxy, ryy, rzy,
281 rxz, ryz, rzz,
282 ttx*rxx + tty*rxy + ttz*rxz,
283 ttx*ryx + tty*ryy + ttz*ryz,
284 ttx*rzx + tty*rzy + ttz*rzz );
285}
286
287inline
288G4AffineTransform& G4AffineTransform::Invert()
289{
290 G4double ttx = -tx, tty = -ty, ttz = -tz;
291 tx = ttx*rxx + tty*rxy + ttz*rxz;
292 ty = ttx*ryx + tty*ryy + ttz*ryz;
293 tz = ttx*rzx + tty*rzy + ttz*rzz;
294
295 G4double tmp1=ryx; ryx=rxy; rxy=tmp1;
296 G4double tmp2=rzx; rzx=rxz; rxz=tmp2;
297 G4double tmp3=rzy; rzy=ryz; ryz=tmp3;
298
299 return *this;
300}
301
302inline
303G4AffineTransform& G4AffineTransform::operator +=(const G4ThreeVector& tlate)
304{
305 tx += tlate.x();
306 ty += tlate.y();
307 tz += tlate.z();
308
309 return *this;
310}
311
312inline
313G4AffineTransform& G4AffineTransform::operator -=(const G4ThreeVector& tlate)
314{
315 tx -= tlate.x();
316 ty -= tlate.y();
317 tz -= tlate.z();
318
319 return *this;
320}
321
322inline
323G4bool G4AffineTransform::operator == (const G4AffineTransform& tf) const
324{
325 return (tx==tf.tx&&ty==tf.ty&&tz==tf.tz&&
326 rxx==tf.rxx&&rxy==tf.rxy&&rxz==tf.rxz&&
327 ryx==tf.ryx&&ryy==tf.ryy&&ryz==tf.ryz&&
328 rzx==tf.rzx&&rzy==tf.rzy&&rzz==tf.rzz) ? true : false;
329}
330
331inline
332G4bool G4AffineTransform::operator != (const G4AffineTransform& tf) const
333{
334 return (tx!=tf.tx||ty!=tf.ty||tz!=tf.tz||
335 rxx!=tf.rxx||rxy!=tf.rxy||rxz!=tf.rxz||
336 ryx!=tf.ryx||ryy!=tf.ryy||ryz!=tf.ryz||
337 rzx!=tf.rzx||rzy!=tf.rzy||rzz!=tf.rzz) ? true : false;
338}
339
340inline
341G4double G4AffineTransform::operator [] (const G4int n) const
342{
343 G4double v = 0.0;
344 switch(n)
345 {
346 case 0:
347 v=rxx;
348 break;
349 case 1:
350 v=rxy;
351 break;
352 case 2:
353 v=rxz;
354 break;
355 case 4:
356 v=ryx;
357 break;
358 case 5:
359 v=ryy;
360 break;
361 case 6:
362 v=ryz;
363 break;
364 case 8:
365 v=rzx;
366 break;
367 case 9:
368 v=rzy;
369 break;
370 case 10:
371 v=rzz;
372 break;
373 case 12:
374 v=tx;
375 break;
376 case 13:
377 v=ty;
378 break;
379 case 14:
380 v=tz;
381 break;
382 case 3:
383 case 7:
384 case 11:
385 break;
386 case 15:
387 v=1.0;
388 break;
389 }
390 return v;
391}
392
393inline
394G4bool G4AffineTransform::IsRotated() const
395{
396 return (rxx==1.0 && ryy==1.0 && rzz==1.0) ? false : true;
397}
398
399inline
400G4bool G4AffineTransform::IsTranslated() const
401{
402 return (tx || ty || tz) ? true:false;
403}
404
405inline G4RotationMatrix G4AffineTransform::NetRotation() const
406{
407 return G4Rep3x3(rxx,rxy,rxz,
408 ryx,ryy,ryz,
409 rzx,rzy,rzz);
410}
411
412inline G4RotationMatrix G4AffineTransform::InverseNetRotation() const
413{
414 return G4Rep3x3(rxx,ryx,rzx,
415 rxy,ryy,rzy,
416 rxz,ryz,rzz);
417}
418
419inline
420G4ThreeVector G4AffineTransform::NetTranslation() const
421{
422 return G4ThreeVector(tx,ty,tz);
423}
424
425inline
426G4ThreeVector G4AffineTransform::InverseNetTranslation() const
427{
428 G4double ttx = -tx, tty = -ty, ttz = -tz;
429 G4double invtx = ttx*rxx + tty*rxy + ttz*rxz;
430 G4double invty = ttx*ryx + tty*ryy + ttz*ryz;
431 G4double invtz = ttx*rzx + tty*rzy + ttz*rzz;
432 return G4ThreeVector(invtx,invty,invtz);
433}
434
435inline
436void G4AffineTransform::SetNetRotation(const G4RotationMatrix& rot)
437{
438 rxx=rot.xx();
439 rxy=rot.xy();
440 rxz=rot.xz();
441 ryx=rot.yx();
442 ryy=rot.yy();
443 ryz=rot.yz();
444 rzx=rot.zx();
445 rzy=rot.zy();
446 rzz=rot.zz();
447}
448
449inline
450void G4AffineTransform::SetNetTranslation(const G4ThreeVector& tlate)
451{
452 tx=tlate.x();
453 ty=tlate.y();
454 tz=tlate.z();
455}
456
457inline
458G4AffineTransform::operator G4Transform3D () const
459{
460 return G4Transform3D(NetRotation().inverse(),NetTranslation());
461}
462
463inline
464std::ostream& operator << (std::ostream& os, const G4AffineTransform& transf)
465{
466 std::streamsize oldPrec = os.precision(6);
467 G4double DeviationTolerance = 1.0e-05;
468
469 G4double diagDeviation = 0.0;
470 G4double offdDeviationUL = 0.0;
471 G4double offdDeviationDR = 0.0;
472 G4double offdDeviation = 0.0;
473
474 os << " Transformation: " << G4endl;
475
476 // double a = std::max ( 1, 2, 3 ) ;
477
478 G4bool UnitTr = ! transf.IsRotated();
479 diagDeviation = std::max( std::fabs( transf[0] - 1.0 ) , // |rxx - 1|
480 std::fabs( transf[5] - 1.0 ) ); // |ryy - 1|
481 diagDeviation = std::max( diagDeviation,
482 std::fabs( transf[10] - 1.0 ) ); // |rzz - 1|
483
484 offdDeviationUL = std::max( std::fabs( transf[1] ) , // |rxy|
485 std::fabs( transf[2] ) ); // |rxz|
486 offdDeviationUL = std::max( offdDeviationUL,
487 std::fabs( transf[4] ) ); // |ryx|
488
489 offdDeviationDR = std::max( std::fabs( transf[6] ) , // |ryz|
490 std::fabs( transf[8] ) ); // |rzx|
491 offdDeviationDR = std::max( offdDeviationDR,
492 std::fabs( transf[9] ) ); // |rzy|
493 offdDeviation = std::max( offdDeviationUL, offdDeviationDR );
494
495 if( UnitTr || std::max(diagDeviation, offdDeviation) < DeviationTolerance )
496 {
497 os << " UNIT Rotation " << G4endl;
498 }
499 else
500 {
501 os << "rx/x,y,z: "
502 << transf[0] << " " << transf[1] << " " << transf[2] << G4endl
503 << "ry/x,y,z: "
504 << transf[4] << " " << transf[5] << " " << transf[6] << G4endl
505 << "rz/x,y,z: "
506 << transf[8] << " " << transf[9] << " " << transf[10] << G4endl;
507 }
508
509 os << "tr/x,y,z: " << transf[12] << " " << transf[13] << " " << transf[14]
510 << G4endl;
511
512 os.precision(oldPrec);
513
514 return os;
515}