Geant4  10.03
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 98309 2016-07-06 10:30:15Z 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  return G4Rep3x3(rxx,rxy,rxz,
367  ryx,ryy,ryz,
368  rzx,rzy,rzz);
369 }
370 
371 inline
372 G4ThreeVector G4AffineTransform::NetTranslation() const
373 {
374  return G4ThreeVector(tx,ty,tz);
375 }
376 
377 inline
378 void G4AffineTransform::SetNetRotation(const G4RotationMatrix& rot)
379 {
380  rxx=rot.xx();
381  rxy=rot.xy();
382  rxz=rot.xz();
383  ryx=rot.yx();
384  ryy=rot.yy();
385  ryz=rot.yz();
386  rzx=rot.zx();
387  rzy=rot.zy();
388  rzz=rot.zz();
389 }
390 
391 inline
392 void G4AffineTransform::SetNetTranslation(const G4ThreeVector& tlate)
393 {
394  tx=tlate.x();
395  ty=tlate.y();
396  tz=tlate.z();
397 }
398 
399 inline
400 G4AffineTransform::operator G4Transform3D () const
401 {
402  return G4Transform3D(NetRotation().inverse(),NetTranslation());
403 }
404 
405 inline
406 std::ostream& operator << (std::ostream& os, const G4AffineTransform& transf)
407 {
408  std::streamsize oldPrec = os.precision(6);
409  G4double DeviationTolerance = 1.0e-05;
410 
411  G4double diagDeviation = 0.0;
412  G4double offdDeviationUL = 0.0;
413  G4double offdDeviationDR = 0.0;
414  G4double offdDeviation = 0.0;
415 
416  os << " Transformation: " << G4endl;
417 
418  // double a = std::max ( 1, 2, 3 ) ;
419 
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|
425 
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|
430 
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 );
436 
437  if( UnitTr || std::max(diagDeviation, offdDeviation) < DeviationTolerance )
438  {
439  os << " UNIT Rotation " << G4endl;
440  }
441  else
442  {
443  os << "rx/x,y,z: "
444  << transf[0] << " " << transf[1] << " " << transf[2] << G4endl
445  << "ry/x,y,z: "
446  << transf[4] << " " << transf[5] << " " << transf[6] << G4endl
447  << "rz/x,y,z: "
448  << transf[8] << " " << transf[9] << " " << transf[10] << G4endl;
449  }
450 
451  os << "tr/x,y,z: " << transf[12] << " " << transf[13] << " " << transf[14]
452  << G4endl;
453 
454  os.precision(oldPrec);
455 
456  return os;
457 }