Geant4  10.02.p01
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 //
27 // $Id: G4AffineTransform.icc 93152 2015-10-08 11:53:57Z gcosmo $
28 //
29 //
30 // G4AffineTransformation Inline implementation
31 //
32 // --------------------------------------------------------------------
33 
34 inline G4AffineTransform::G4AffineTransform()
35  : rxx(1),rxy(0),rxz(0),
36  ryx(0),ryy(1),ryz(0),
37  rzx(0),rzy(0),rzz(1),
38  tx(0),ty(0),tz(0)
39 {}
40 
41 inline G4AffineTransform::G4AffineTransform(const G4ThreeVector& tlate)
42  : rxx(1),rxy(0),rxz(0),
43  ryx(0),ryy(1),ryz(0),
44  rzx(0),rzy(0),rzz(1),
45  tx(tlate.x()),ty(tlate.y()),tz(tlate.z())
46 {}
47 
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()),
52  tx(0),ty(0),tz(0)
53 {}
54 
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())
61 {}
62 
63 inline G4AffineTransform::G4AffineTransform( const G4RotationMatrix* rot,
64  const G4ThreeVector& tlate)
65  : tx(tlate.x()),ty(tlate.y()),tz(tlate.z())
66 {
67  if (rot)
68  {
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();
72  }
73  else
74  {
75  rxx=1; rxy=0; rxz=0;
76  ryx=0; ryy=1; ryz=0;
77  rzx=0; rzy=0; rzz=1;
78  }
79 }
80 
81 inline
82 G4AffineTransform::
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)
91 {}
92 
93 inline G4AffineTransform
94 G4AffineTransform::operator * (const G4AffineTransform& tf) const
95 {
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,
100 
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,
104 
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,
108 
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);
112 }
113 
114 inline G4AffineTransform&
115 G4AffineTransform::operator *= (const G4AffineTransform& tf)
116 {
117  // Use temporaries for `in place' compound transform computation
118 
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;
122 
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;
126 
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;
130 
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;
134 
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;
139 
140  return *this;
141 }
142 
143 inline G4AffineTransform&
144 G4AffineTransform::Product(const G4AffineTransform& tf1,
145  const G4AffineTransform& tf2)
146 {
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;
150 
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;
154 
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;
158 
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;
162 
163  return *this;
164 }
165 
166 inline G4AffineTransform&
167 G4AffineTransform::InverseProduct( const G4AffineTransform& tf1,
168  const G4AffineTransform& tf2)
169 {
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;
173 
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;
177 
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;
181 
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;
185 
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;
189 
190  return *this;
191 }
192 
193 inline
194 G4ThreeVector G4AffineTransform::TransformPoint(const G4ThreeVector& vec) const
195 {
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 );
199 }
200 
201 inline
202 G4ThreeVector G4AffineTransform::TransformAxis(const G4ThreeVector& axis) const
203 {
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 );
207 }
208 
209 inline
210 void G4AffineTransform::ApplyPointTransform(G4ThreeVector& vec) const
211 {
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;
215 
216  vec.setX(x);
217  vec.setY(y);
218  vec.setZ(z);
219 }
220 
221 inline
222 void G4AffineTransform::ApplyAxisTransform(G4ThreeVector& axis) const
223 {
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;
227 
228  axis.setX(x);
229  axis.setY(y);
230  axis.setZ(z);
231 }
232 
233 inline
234 G4AffineTransform G4AffineTransform::Inverse() const
235 {
236  return G4AffineTransform( rxx, ryx, rzx,
237  rxy, ryy, rzy,
238  rxz, ryz, rzz,
239 
240  -tx*rxx - ty*rxy - tz*rxz,
241  -tx*ryx - ty*ryy - tz*ryz,
242  -tx*rzx - ty*rzy - tz*rzz );
243 }
244 
245 inline
246 G4AffineTransform& G4AffineTransform::Invert()
247 {
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;
251 
252  tx=v1; ty=v2; tz=v3;
253 
254  G4double tmp1=ryx; ryx=rxy; rxy=tmp1;
255  G4double tmp2=rzx; rzx=rxz; rxz=tmp2;
256  G4double tmp3=rzy; rzy=ryz; ryz=tmp3;
257 
258  return *this;
259 
260 }
261 
262 inline
263 G4AffineTransform& G4AffineTransform::operator +=(const G4ThreeVector& tlate)
264 {
265  tx += tlate.x();
266  ty += tlate.y();
267  tz += tlate.z();
268 
269  return *this;
270 }
271 
272 inline
273 G4AffineTransform& G4AffineTransform::operator -=(const G4ThreeVector& tlate)
274 {
275  tx -= tlate.x();
276  ty -= tlate.y();
277  tz -= tlate.z();
278 
279  return *this;
280 }
281 
282 inline
283 G4bool G4AffineTransform::operator == (const G4AffineTransform& tf) const
284 {
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;
289 }
290 inline
291 G4bool G4AffineTransform::operator != (const G4AffineTransform& tf) const
292 {
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;
297 }
298 
299 inline
300 G4double G4AffineTransform::operator [] (const G4int n) const
301 {
302  G4double v = 0.0;
303  switch(n)
304  {
305  case 0:
306  v=rxx;
307  break;
308  case 1:
309  v=rxy;
310  break;
311  case 2:
312  v=rxz;
313  break;
314  case 4:
315  v=ryx;
316  break;
317  case 5:
318  v=ryy;
319  break;
320  case 6:
321  v=ryz;
322  break;
323  case 8:
324  v=rzx;
325  break;
326  case 9:
327  v=rzy;
328  break;
329  case 10:
330  v=rzz;
331  break;
332  case 12:
333  v=tx;
334  break;
335  case 13:
336  v=ty;
337  break;
338  case 14:
339  v=tz;
340  break;
341  case 3:
342  case 7:
343  case 11:
344  break;
345  case 15:
346  v=1.0;
347  break;
348  }
349  return v;
350 }
351 
352 inline
353 G4bool G4AffineTransform::IsRotated() const
354 {
355  return (rxx==1.0 && ryy==1.0 && rzz==1.0) ? false : true;
356 }
357 
358 inline
359 G4bool G4AffineTransform::IsTranslated() const
360 {
361  return (tx || ty || tz) ? true:false;
362 }
363 
364 inline G4RotationMatrix G4AffineTransform::NetRotation() const
365 {
366  G4RotationMatrix mat;
367  return mat.rotateAxes(G4ThreeVector(rxx,ryx,rzx),
368  G4ThreeVector(rxy,ryy,rzy),
369  G4ThreeVector(rxz,ryz,rzz));
370 }
371 
372 inline
373 G4ThreeVector G4AffineTransform::NetTranslation() const
374 {
375  return G4ThreeVector(tx,ty,tz);
376 }
377 
378 inline
379 void G4AffineTransform::SetNetRotation(const G4RotationMatrix& rot)
380 {
381  rxx=rot.xx();
382  rxy=rot.xy();
383  rxz=rot.xz();
384  ryx=rot.yx();
385  ryy=rot.yy();
386  ryz=rot.yz();
387  rzx=rot.zx();
388  rzy=rot.zy();
389  rzz=rot.zz();
390 }
391 
392 inline
393 void G4AffineTransform::SetNetTranslation(const G4ThreeVector& tlate)
394 {
395  tx=tlate.x();
396  ty=tlate.y();
397  tz=tlate.z();
398 }
399 
400 inline
401 std::ostream& operator << (std::ostream& os, const G4AffineTransform& transf)
402 {
403  std::streamsize oldPrec = os.precision(6);
404  G4double DeviationTolerance = 1.0e-05;
405 
406  G4double diagDeviation = 0.0;
407  G4double offdDeviationUL = 0.0;
408  G4double offdDeviationDR = 0.0;
409  G4double offdDeviation = 0.0;
410 
411  os << " Transformation: " << G4endl;
412 
413  // double a = std::max ( 1, 2, 3 ) ;
414 
415  G4bool UnitTr = ! transf.IsRotated();
416  diagDeviation = std::max( std::fabs( transf[0] - 1.0 ) , // |rxx - 1|
417  std::fabs( transf[5] - 1.0 ) ); // |ryy - 1|
418  diagDeviation = std::max( diagDeviation,
419  std::fabs( transf[10] - 1.0 ) ); // |rzz - 1|
420 
421  offdDeviationUL = std::max( std::fabs( transf[1] ) , // |rxy|
422  std::fabs( transf[2] ) ); // |rxz|
423  offdDeviationUL = std::max( offdDeviationUL,
424  std::fabs( transf[4] ) ); // |ryx|
425 
426  offdDeviationDR = std::max( std::fabs( transf[6] ) , // |ryz|
427  std::fabs( transf[8] ) ); // |rzx|
428  offdDeviationDR = std::max( offdDeviationDR,
429  std::fabs( transf[9] ) ); // |rzy|
430  offdDeviation = std::max( offdDeviationUL, offdDeviationDR );
431 
432  if( UnitTr || std::max(diagDeviation, offdDeviation) < DeviationTolerance )
433  {
434  os << " UNIT Rotation " << G4endl;
435  }
436  else
437  {
438  os << "rx/x,y,z: "
439  << transf[0] << " " << transf[1] << " " << transf[2] << G4endl
440  << "ry/x,y,z: "
441  << transf[4] << " " << transf[5] << " " << transf[6] << G4endl
442  << "rz/x,y,z: "
443  << transf[8] << " " << transf[9] << " " << transf[10] << G4endl;
444  }
445 
446  os << "tr/x,y,z: " << transf[12] << " " << transf[13] << " " << transf[14]
447  << G4endl;
448 
449  os.precision(oldPrec);
450 
451  return os;
452 }