Logo ROOT   6.12/07
Reference Guide
TGeoMatrix.cxx
Go to the documentation of this file.
1 // @(#)root/geom:$Id$
2 // Author: Andrei Gheata 25/10/01
3 
4 /*************************************************************************
5  * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. *
6  * All rights reserved. *
7  * *
8  * For the licensing terms see $ROOTSYS/LICENSE. *
9  * For the list of contributors see $ROOTSYS/README/CREDITS. *
10  *************************************************************************/
11 
12 /** \class TGeoMatrix
13 \ingroup Geometry_classes
14 
15 Geometrical transformation package.
16 
17  All geometrical transformations handled by the modeller are provided as a
18 built-in package. This was designed to minimize memory requirements and
19 optimize performance of point/vector master-to-local and local-to-master
20 computation. We need to have in mind that a transformation in TGeo has 2
21 major use-cases. The first one is for defining the placement of a volume
22 with respect to its container reference frame. This frame will be called
23 'master' and the frame of the positioned volume - 'local'. If T is a
24 transformation used for positioning volume daughters, then:
25 
26 ~~~ {.cpp}
27  MASTER = T * LOCAL
28 ~~~
29 
30  Therefore a local-to-master conversion will be performed by using T, while
31 a master-to-local by using its inverse. The second use case is the computation
32 of the global transformation of a given object in the geometry. Since the
33 geometry is built as 'volumes-inside-volumes', this global transformation
34 represent the pile-up of all local transformations in the corresponding
35 branch. The conversion from the global reference frame and the given object
36 is also called master-to-local, but it is handled by the manager class.
37  A general homogenous transformation is defined as a 4x4 matrix embedding
38 a rotation, a translation and a scale. The advantage of this description
39 is that each basic transformation can be represented as a homogenous matrix,
40 composition being performed as simple matrix multiplication.
41 
42  Rotation: Inverse rotation:
43 
44 ~~~ {.cpp}
45  r11 r12 r13 0 r11 r21 r31 0
46  r21 r22 r23 0 r12 r22 r32 0
47  r31 r32 r33 0 r13 r23 r33 0
48  0 0 0 1 0 0 0 1
49 ~~~
50 
51  Translation: Inverse translation:
52 
53 ~~~ {.cpp}
54  1 0 0 tx 1 0 0 -tx
55  0 1 0 ty 0 1 0 -ty
56  0 0 1 tz 0 0 1 -tz
57  0 0 0 1 0 0 0 1
58 ~~~
59 
60  Scale: Inverse scale:
61 
62 ~~~ {.cpp}
63  sx 0 0 0 1/sx 0 0 0
64  0 sy 0 0 0 1/sy 0 0
65  0 0 sz 0 0 0 1/sz 0
66  0 0 0 1 0 0 0 1
67 ~~~
68 
69  where:
70  - `rij` are the 3x3 rotation matrix components,
71  - `tx`, `ty`, `tz` are the translation components
72  - `sx`, `sy`, `sz` are arbitrary scale constants on each axis,
73 
74  The disadvantage in using this approach is that computation for 4x4 matrices
75 is expensive. Even combining two translation would become a multiplication
76 of their corresponding matrices, which is quite an undesired effect. On the
77 other hand, it is not a good idea to store a translation as a block of 16
78 numbers. We have therefore chosen to implement each basic transformation type
79 as a class deriving from the same basic abstract class and handling its specific
80 data and point/vector transformation algorithms.
81 
82 \image html geom_transf.jpg
83 
84 ### The base class TGeoMatrix defines abstract metods for:
85 
86 #### translation, rotation and scale getters. Every derived class stores only
87  its specific data, e.g. a translation stores an array of 3 doubles and a
88  rotation an array of 9. However, asking which is the rotation array of a
89  TGeoTranslation through the base TGeoMatrix interface is a legal operation.
90  The answer in this case is a pointer to a global constant array representing
91  an identity rotation.
92 
93 ~~~ {.cpp}
94  Double_t *TGeoMatrix::GetTranslation()
95  Double_t *TGeoMatrix::GetRotation()
96  Double_t *TGeoMatrix::GetScale()
97 ~~~
98 
99 #### MasterToLocal() and LocalToMaster() point and vector transformations :
100 
101 ~~~ {.cpp}
102  void TGeoMatrix::MasterToLocal(const Double_t *master, Double_t *local)
103  void TGeoMatrix::LocalToMaster(const Double_t *local, Double_t *master)
104  void TGeoMatrix::MasterToLocalVect(const Double_t *master, Double_t *local)
105  void TGeoMatrix::LocalToMasterVect(const Double_t *local, Double_t *master)
106 ~~~
107 
108  These allow correct conversion also for reflections.
109 
110 #### Transformation type getters :
111 
112 ~~~ {.cpp}
113  Bool_t TGeoMatrix::IsIdentity()
114  Bool_t TGeoMatrix::IsTranslation()
115  Bool_t TGeoMatrix::IsRotation()
116  Bool_t TGeoMatrix::IsScale()
117  Bool_t TGeoMatrix::IsCombi() (translation + rotation)
118  Bool_t TGeoMatrix::IsGeneral() (translation + rotation + scale)
119 ~~~
120 
121  Combinations of basic transformations are represented by specific classes
122 deriving from TGeoMatrix. In order to define a matrix as a combination of several
123 others, a special class TGeoHMatrix is provided. Here is an example of matrix
124 creation :
125 
126 ### Matrix creation example:
127 
128 ~~~ {.cpp}
129  root[0] TGeoRotation r1,r2;
130  r1.SetAngles(90,0,30); // rotation defined by Euler angles
131  r2.SetAngles(90,90,90,180,0,0); // rotation defined by GEANT3 angles
132  TGeoTranslation t1(-10,10,0);
133  TGeoTranslation t2(10,-10,5);
134  TGeoCombiTrans c1(t1,r1);
135  TGeoCombiTrans c2(t2,r2);
136  TGeoHMatrix h = c1 * c2; // composition is done via TGeoHMatrix class
137  root[7] TGeoHMatrix *ph = new TGeoHMatrix(hm); // this is the one we want to
138  // use for positioning a volume
139  root[8] ph->Print();
140  ...
141  pVolume->AddNode(pVolDaughter,id,ph) // now ph is owned by the manager
142 ~~~
143 
144 ### Rule for matrix creation:
145  Unless explicitly used for positioning nodes (TGeoVolume::AddNode()) all
146 matrices deletion have to be managed by users. Matrices passed to geometry
147 have to be created by using new() operator and their deletion is done by
148 TGeoManager class.
149 
150 ### Available geometrical transformations
151 
152 #### TGeoTranslation
153 Represent a (dx,dy,dz) translation. Data members:
154  Double_t fTranslation[3]. Translations can be added/subtracted.
155 
156 ~~~ {.cpp}
157  TGeoTranslation t1;
158  t1->SetTranslation(-5,10,4);
159  TGeoTranslation *t2 = new TGeoTranslation(4,3,10);
160  t2->Subtract(&t1);
161 ~~~
162 
163 #### Rotations
164  Represent a pure rotation. Data members: Double_t fRotationMatrix[3*3].
165  Rotations can be defined either by Euler angles, either, by GEANT3 angles :
166 
167 ~~~ {.cpp}
168  TGeoRotation *r1 = new TGeoRotation();
169  r1->SetAngles(phi, theta, psi); // all angles in degrees
170 ~~~
171 
172  This represent the composition of : first a rotation about Z axis with
173  angle phi, then a rotation with theta about the rotated X axis, and
174  finally a rotation with psi about the new Z axis.
175 
176 ~~~ {.cpp}
177  r1->SetAngles(th1,phi1, th2,phi2, th3,phi3)
178 ~~~
179 
180  This is a rotation defined in GEANT3 style. Theta and phi are the spherical
181  angles of each axis of the rotated coordinate system with respect to the
182  initial one. This construction allows definition of malformed rotations,
183  e.g. not orthogonal. A check is performed and an error message is issued
184  in this case.
185 
186  Specific utilities : determinant, inverse.
187 
188 #### Scale transformations
189  Represent a scale shrinking/enlargement. Data
190  members :Double_t fScale[3]. Not fully implemented yet.
191 
192 #### Combined transformations
193 Represent a rotation followed by a translation.
194 Data members: Double_t fTranslation[3], TGeoRotation *fRotation.
195 
196 ~~~ {.cpp}
197  TGeoRotation *rot = new TGeoRotation("rot",10,20,30);
198  TGeoTranslation trans;
199  ...
200  TGeoCombiTrans *c1 = new TGeoCombiTrans(trans, rot);
201  TGeoCombiTrans *c2 = new TGeoCombiTrans("somename",10,20,30,rot)
202 ~~~
203 
204 
205 #### TGeoGenTrans
206 Combined transformations including a scale. Not implemented.
207 
208 #### TGeoIdentity
209 A generic singleton matrix representing a identity transformation
210  NOTE: identified by the global variable gGeoIdentity.
211 */
212 
213 #include "Riostream.h"
214 #include "TObjArray.h"
215 
216 #include "TGeoManager.h"
217 #include "TGeoMatrix.h"
218 #include "TMath.h"
219 
221 const Int_t kN3 = 3*sizeof(Double_t);
222 const Int_t kN9 = 9*sizeof(Double_t);
223 
224 // statics and globals
225 
227 
228 ////////////////////////////////////////////////////////////////////////////////
229 /// dummy constructor
230 
232 {
234 }
235 
236 ////////////////////////////////////////////////////////////////////////////////
237 /// copy constructor
238 
240  :TNamed(other)
241 {
243 }
244 
245 ////////////////////////////////////////////////////////////////////////////////
246 /// Constructor
247 
249  :TNamed(name, "")
250 {
251 }
252 
253 ////////////////////////////////////////////////////////////////////////////////
254 /// Destructor
255 
257 {
258  if (IsRegistered() && gGeoManager) {
259  if (!gGeoManager->IsCleaning()) {
261  Warning("dtor", "Registered matrix %s was removed", GetName());
262  }
263  }
264 }
265 
266 ////////////////////////////////////////////////////////////////////////////////
267 /// Returns true if no rotation or the rotation is about Z axis
268 
270 {
271  if (IsIdentity()) return kTRUE;
272  const Double_t *rot = GetRotationMatrix();
273  if (TMath::Abs(rot[6])>1E-9) return kFALSE;
274  if (TMath::Abs(rot[7])>1E-9) return kFALSE;
275  if ((1.-TMath::Abs(rot[8]))>1E-9) return kFALSE;
276  return kTRUE;
277 }
278 
279 ////////////////////////////////////////////////////////////////////////////////
280 /// Get total size in bytes of this
281 
283 {
284  Int_t count = 4+28+strlen(GetName())+strlen(GetTitle()); // fId + TNamed
285  if (IsTranslation()) count += 12;
286  if (IsScale()) count += 12;
287  if (IsCombi() || IsGeneral()) count += 4 + 36;
288  return count;
289 }
290 
291 ////////////////////////////////////////////////////////////////////////////////
292 /// Provide a pointer name containing uid.
293 
295 {
296  static TString name;
297  name = TString::Format("pMatrix%d", GetUniqueID());
298  return (char*)name.Data();
299 }
300 
301 ////////////////////////////////////////////////////////////////////////////////
302 /// The homogenous matrix associated with the transformation is used for
303 /// piling up's and visualization. A homogenous matrix is a 4*4 array
304 /// containing the translation, the rotation and the scale components
305 /// ~~~ {.cpp}
306 /// | R00*sx R01 R02 dx |
307 /// | R10 R11*sy R12 dy |
308 /// | R20 R21 R22*sz dz |
309 /// | 0 0 0 1 |
310 /// ~~~
311 /// where Rij is the rotation matrix, (sx, sy, sz) is the scale
312 /// transformation and (dx, dy, dz) is the translation.
313 
315 {
316  Double_t *hmatrix = hmat;
317  const Double_t *mat = GetRotationMatrix();
318  for (Int_t i=0; i<3; i++) {
319  memcpy(hmatrix, mat, kN3);
320  mat += 3;
321  hmatrix += 3;
322  *hmatrix = 0.0;
323  hmatrix++;
324  }
325  memcpy(hmatrix, GetTranslation(), kN3);
326  hmatrix = hmat;
327  if (IsScale()) {
328  for (Int_t i=0; i<3; i++) {
329  *hmatrix *= GetScale()[i];
330  hmatrix += 5;
331  }
332  }
333  hmatrix[15] = 1.;
334 }
335 
336 ////////////////////////////////////////////////////////////////////////////////
337 /// convert a point by multiplying its column vector (x, y, z, 1) to matrix inverse
338 
339 void TGeoMatrix::LocalToMaster(const Double_t *local, Double_t *master) const
340 {
341  if (IsIdentity()) {
342  memcpy(master, local, kN3);
343  return;
344  }
345  Int_t i;
346  const Double_t *tr = GetTranslation();
347  if (!IsRotation()) {
348  for (i=0; i<3; i++) master[i] = tr[i] + local[i];
349  return;
350  }
351  const Double_t *rot = GetRotationMatrix();
352  for (i=0; i<3; i++) {
353  master[i] = tr[i]
354  + local[0]*rot[3*i]
355  + local[1]*rot[3*i+1]
356  + local[2]*rot[3*i+2];
357  }
358 }
359 
360 ////////////////////////////////////////////////////////////////////////////////
361 /// convert a vector by multiplying its column vector (x, y, z, 1) to matrix inverse
362 
363 void TGeoMatrix::LocalToMasterVect(const Double_t *local, Double_t *master) const
364 {
365  if (!IsRotation()) {
366  memcpy(master, local, kN3);
367  return;
368  }
369  const Double_t *rot = GetRotationMatrix();
370  for (Int_t i=0; i<3; i++) {
371  master[i] = local[0]*rot[3*i]
372  + local[1]*rot[3*i+1]
373  + local[2]*rot[3*i+2];
374  }
375 }
376 
377 ////////////////////////////////////////////////////////////////////////////////
378 /// convert a point by multiplying its column vector (x, y, z, 1) to matrix inverse
379 
380 void TGeoMatrix::LocalToMasterBomb(const Double_t *local, Double_t *master) const
381 {
382  if (IsIdentity()) {
383  memcpy(master, local, kN3);
384  return;
385  }
386  Int_t i;
387  const Double_t *tr = GetTranslation();
388  Double_t bombtr[3] = {0.,0.,0.};
389  gGeoManager->BombTranslation(tr, &bombtr[0]);
390  if (!IsRotation()) {
391  for (i=0; i<3; i++) master[i] = bombtr[i] + local[i];
392  return;
393  }
394  const Double_t *rot = GetRotationMatrix();
395  for (i=0; i<3; i++) {
396  master[i] = bombtr[i]
397  + local[0]*rot[3*i]
398  + local[1]*rot[3*i+1]
399  + local[2]*rot[3*i+2];
400  }
401 }
402 
403 ////////////////////////////////////////////////////////////////////////////////
404 /// convert a point by multiplying its column vector (x, y, z, 1) to matrix
405 
406 void TGeoMatrix::MasterToLocal(const Double_t *master, Double_t *local) const
407 {
408  if (IsIdentity()) {
409  memcpy(local, master, kN3);
410  return;
411  }
412  const Double_t *tr = GetTranslation();
413  Double_t mt0 = master[0]-tr[0];
414  Double_t mt1 = master[1]-tr[1];
415  Double_t mt2 = master[2]-tr[2];
416  if (!IsRotation()) {
417  local[0] = mt0;
418  local[1] = mt1;
419  local[2] = mt2;
420  return;
421  }
422  const Double_t *rot = GetRotationMatrix();
423  local[0] = mt0*rot[0] + mt1*rot[3] + mt2*rot[6];
424  local[1] = mt0*rot[1] + mt1*rot[4] + mt2*rot[7];
425  local[2] = mt0*rot[2] + mt1*rot[5] + mt2*rot[8];
426 }
427 
428 ////////////////////////////////////////////////////////////////////////////////
429 /// convert a point by multiplying its column vector (x, y, z, 1) to matrix
430 
431 void TGeoMatrix::MasterToLocalVect(const Double_t *master, Double_t *local) const
432 {
433  if (!IsRotation()) {
434  memcpy(local, master, kN3);
435  return;
436  }
437  const Double_t *rot = GetRotationMatrix();
438  for (Int_t i=0; i<3; i++) {
439  local[i] = master[0]*rot[i]
440  + master[1]*rot[i+3]
441  + master[2]*rot[i+6];
442  }
443 }
444 
445 ////////////////////////////////////////////////////////////////////////////////
446 /// convert a point by multiplying its column vector (x, y, z, 1) to matrix
447 
448 void TGeoMatrix::MasterToLocalBomb(const Double_t *master, Double_t *local) const
449 {
450  if (IsIdentity()) {
451  memcpy(local, master, kN3);
452  return;
453  }
454  const Double_t *tr = GetTranslation();
455  Double_t bombtr[3] = {0.,0.,0.};
456  Int_t i;
457  gGeoManager->UnbombTranslation(tr, &bombtr[0]);
458  if (!IsRotation()) {
459  for (i=0; i<3; i++) local[i] = master[i]-bombtr[i];
460  return;
461  }
462  const Double_t *rot = GetRotationMatrix();
463  for (i=0; i<3; i++) {
464  local[i] = (master[0]-bombtr[0])*rot[i]
465  + (master[1]-bombtr[1])*rot[i+3]
466  + (master[2]-bombtr[2])*rot[i+6];
467  }
468 }
469 
470 ////////////////////////////////////////////////////////////////////////////////
471 /// Normalize a vector.
472 
474 {
475  Double_t normfactor = vect[0]*vect[0] + vect[1]*vect[1] + vect[2]*vect[2];
476  if (normfactor <= 1E-10) return;
477  normfactor = 1./TMath::Sqrt(normfactor);
478  vect[0] *= normfactor;
479  vect[1] *= normfactor;
480  vect[2] *= normfactor;
481 }
482 
483 ////////////////////////////////////////////////////////////////////////////////
484 /// print the matrix in 4x4 format
485 
487 {
488  const Double_t *rot = GetRotationMatrix();
489  const Double_t *tr = GetTranslation();
490  printf("matrix %s - tr=%d rot=%d refl=%d scl=%d shr=%d reg=%d own=%d\n", GetName(),(Int_t)IsTranslation(),
492  (Int_t)IsOwned());
493  printf("%10.6f%12.6f%12.6f Tx = %10.6f\n", rot[0], rot[1], rot[2], tr[0]);
494  printf("%10.6f%12.6f%12.6f Ty = %10.6f\n", rot[3], rot[4], rot[5], tr[1]);
495  printf("%10.6f%12.6f%12.6f Tz = %10.6f\n", rot[6], rot[7], rot[8], tr[2]);
496  if (IsScale()) {
497  const Double_t *scl = GetScale();
498  printf("Sx=%10.6fSy=%12.6fSz=%12.6f\n", scl[0], scl[1], scl[2]);
499  }
500 }
501 
502 ////////////////////////////////////////////////////////////////////////////////
503 /// Multiply by a reflection respect to YZ.
504 
506 {
507 }
508 
509 ////////////////////////////////////////////////////////////////////////////////
510 /// Multiply by a reflection respect to ZX.
511 
513 {
514 }
515 
516 ////////////////////////////////////////////////////////////////////////////////
517 /// Multiply by a reflection respect to XY.
518 
520 {
521 }
522 
523 ////////////////////////////////////////////////////////////////////////////////
524 /// Register the matrix in the current manager, which will become the owner.
525 
527 {
528  if (!gGeoManager) {
529  Warning("RegisterYourself", "cannot register without geometry");
530  return;
531  }
532  if (!IsRegistered()) {
535  }
536 }
537 
538 ////////////////////////////////////////////////////////////////////////////////
539 /// If no name was supplied in the ctor, the type of transformation is checked.
540 /// A letter will be prepended to the name :
541 /// - t - translation
542 /// - r - rotation
543 /// - s - scale
544 /// - c - combi (translation + rotation)
545 /// - g - general (tr+rot+scale)
546 /// The index of the transformation in gGeoManager list of transformations will
547 /// be appended.
548 
550 {
551  if (!gGeoManager) return;
552  if (strlen(GetName())) return;
553  char type = 'n';
554  if (IsTranslation()) type = 't';
555  if (IsRotation()) type = 'r';
556  if (IsScale()) type = 's';
557  if (IsCombi()) type = 'c';
558  if (IsGeneral()) type = 'g';
559  TObjArray *matrices = gGeoManager->GetListOfMatrices();
560  Int_t index = 0;
561  if (matrices) index =matrices->GetEntriesFast() - 1;
562  TString name = TString::Format("%c%d", type, index);
563  SetName(name);
564 }
565 
566 /** \class TGeoTranslation
567 \ingroup Geometry_classes
568 
569 Class describing translations. A translation is
570 basically an array of 3 doubles matching the positions 12, 13
571 and 14 in the homogenous matrix description.
572 */
573 
575 
576 ////////////////////////////////////////////////////////////////////////////////
577 /// Default constructor
578 
580 {
581  for (Int_t i=0; i<3; i++) fTranslation[i] = 0;
582 }
583 
584 ////////////////////////////////////////////////////////////////////////////////
585 /// Copy ctor.
586 
588  :TGeoMatrix(other)
589 {
590  SetTranslation(other);
591 }
592 
593 ////////////////////////////////////////////////////////////////////////////////
594 /// Ctor. based on a general matrix
595 
597  :TGeoMatrix(other)
598 {
601  SetTranslation(other);
602 }
603 
604 ////////////////////////////////////////////////////////////////////////////////
605 /// Default constructor defining the translation
606 
608  :TGeoMatrix("")
609 {
610  if (dx || dy || dz) SetBit(kGeoTranslation);
611  SetTranslation(dx, dy, dz);
612 }
613 
614 ////////////////////////////////////////////////////////////////////////////////
615 /// Default constructor defining the translation
616 
618  :TGeoMatrix(name)
619 {
620  if (dx || dy || dz) SetBit(kGeoTranslation);
621  SetTranslation(dx, dy, dz);
622 }
623 
624 ////////////////////////////////////////////////////////////////////////////////
625 /// Assignment from a general matrix
626 
628 {
629  if (&matrix == this) return *this;
630  Bool_t registered = TestBit(kGeoRegistered);
631  TNamed::operator=(matrix);
632  SetTranslation(matrix);
633  SetBit(kGeoRegistered,registered);
636  return *this;
637 }
638 
639 ////////////////////////////////////////////////////////////////////////////////
640 /// Translation composition
641 
643 {
644  const Double_t *tr = right.GetTranslation();
645  fTranslation[0] += tr[0];
646  fTranslation[1] += tr[1];
647  fTranslation[2] += tr[2];
649  return *this;
650 }
651 
653 {
654  TGeoTranslation t = *this;
655  t *= right;
656  return t;
657 }
658 
660 {
661  TGeoHMatrix t = *this;
662  t *= right;
663  return t;
664 }
665 
666 ////////////////////////////////////////////////////////////////////////////////
667 /// Is-equal operator
668 
670 {
671  if (&other == this) return kTRUE;
672  const Double_t *tr = GetTranslation();
673  const Double_t *otr = other.GetTranslation();
674  for (auto i=0; i<3; i++)
675  if (TMath::Abs(tr[i]-otr[i])>1.E-10) return kFALSE;
676  return kTRUE;
677 }
678 
679 ////////////////////////////////////////////////////////////////////////////////
680 /// Return a temporary inverse of this.
681 
683 {
684  TGeoHMatrix h;
685  h = *this;
686  Double_t tr[3];
687  tr[0] = -fTranslation[0];
688  tr[1] = -fTranslation[1];
689  tr[2] = -fTranslation[2];
690  h.SetTranslation(tr);
691  return h;
692 }
693 
694 ////////////////////////////////////////////////////////////////////////////////
695 /// Adding a translation to this one
696 
698 {
699  const Double_t *trans = other->GetTranslation();
700  for (Int_t i=0; i<3; i++)
701  fTranslation[i] += trans[i];
702 }
703 
704 ////////////////////////////////////////////////////////////////////////////////
705 /// Make a clone of this matrix.
706 
708 {
709  TGeoMatrix *matrix = new TGeoTranslation(*this);
710  return matrix;
711 }
712 
713 ////////////////////////////////////////////////////////////////////////////////
714 /// Rotate about X axis of the master frame with angle expressed in degrees.
715 
717 {
718  Warning("RotateX", "Not implemented. Use TGeoCombiTrans instead");
719 }
720 
721 ////////////////////////////////////////////////////////////////////////////////
722 /// Rotate about Y axis of the master frame with angle expressed in degrees.
723 
725 {
726  Warning("RotateY", "Not implemented. Use TGeoCombiTrans instead");
727 }
728 
729 ////////////////////////////////////////////////////////////////////////////////
730 /// Rotate about Z axis of the master frame with angle expressed in degrees.
731 
733 {
734  Warning("RotateZ", "Not implemented. Use TGeoCombiTrans instead");
735 }
736 
737 ////////////////////////////////////////////////////////////////////////////////
738 /// Subtracting a translation from this one
739 
741 {
742  const Double_t *trans = other->GetTranslation();
743  for (Int_t i=0; i<3; i++)
744  fTranslation[i] -= trans[i];
745 }
746 
747 ////////////////////////////////////////////////////////////////////////////////
748 /// Set translation components
749 
751 {
752  fTranslation[0] = dx;
753  fTranslation[1] = dy;
754  fTranslation[2] = dz;
755  if (dx || dy || dz) SetBit(kGeoTranslation);
757 }
758 
759 ////////////////////////////////////////////////////////////////////////////////
760 /// Set translation components
761 
763 {
765  const Double_t *transl = other.GetTranslation();
766  memcpy(fTranslation, transl, kN3);
767 }
768 
769 ////////////////////////////////////////////////////////////////////////////////
770 /// convert a point by multiplying its column vector (x, y, z, 1) to matrix inverse
771 
772 void TGeoTranslation::LocalToMaster(const Double_t *local, Double_t *master) const
773 {
774  const Double_t *tr = GetTranslation();
775  for (Int_t i=0; i<3; i++)
776  master[i] = tr[i] + local[i];
777 }
778 
779 ////////////////////////////////////////////////////////////////////////////////
780 /// convert a vector to MARS
781 
782 void TGeoTranslation::LocalToMasterVect(const Double_t *local, Double_t *master) const
783 {
784  memcpy(master, local, kN3);
785 }
786 
787 ////////////////////////////////////////////////////////////////////////////////
788 /// convert a point by multiplying its column vector (x, y, z, 1) to matrix inverse
789 
790 void TGeoTranslation::LocalToMasterBomb(const Double_t *local, Double_t *master) const
791 {
792  const Double_t *tr = GetTranslation();
793  Double_t bombtr[3] = {0.,0.,0.};
794  gGeoManager->BombTranslation(tr, &bombtr[0]);
795  for (Int_t i=0; i<3; i++)
796  master[i] = bombtr[i] + local[i];
797 }
798 
799 ////////////////////////////////////////////////////////////////////////////////
800 /// convert a point by multiplying its column vector (x, y, z, 1) to matrix
801 
802 void TGeoTranslation::MasterToLocal(const Double_t *master, Double_t *local) const
803 {
804  const Double_t *tr = GetTranslation();
805  for (Int_t i=0; i<3; i++)
806  local[i] = master[i]-tr[i];
807 }
808 
809 ////////////////////////////////////////////////////////////////////////////////
810 /// convert a vector from MARS to local
811 
812 void TGeoTranslation::MasterToLocalVect(const Double_t *master, Double_t *local) const
813 {
814  memcpy(local, master, kN3);
815 }
816 
817 ////////////////////////////////////////////////////////////////////////////////
818 /// convert a point by multiplying its column vector (x, y, z, 1) to matrix
819 
820 void TGeoTranslation::MasterToLocalBomb(const Double_t *master, Double_t *local) const
821 {
822  const Double_t *tr = GetTranslation();
823  Double_t bombtr[3] = {0.,0.,0.};
824  gGeoManager->UnbombTranslation(tr, &bombtr[0]);
825  for (Int_t i=0; i<3; i++)
826  local[i] = master[i]-bombtr[i];
827 }
828 
829 ////////////////////////////////////////////////////////////////////////////////
830 /// Save a primitive as a C++ statement(s) on output stream "out".
831 
832 void TGeoTranslation::SavePrimitive(std::ostream &out, Option_t * /*option*/ /*= ""*/)
833 {
834  if (TestBit(kGeoSavePrimitive)) return;
835  out << " // Translation: " << GetName() << std::endl;
836  out << " dx = " << fTranslation[0] << ";" << std::endl;
837  out << " dy = " << fTranslation[1] << ";" << std::endl;
838  out << " dz = " << fTranslation[2] << ";" << std::endl;
839  out << " TGeoTranslation *" << GetPointerName() << " = new TGeoTranslation(\"" << GetName() << "\",dx,dy,dz);" << std::endl;
841 }
842 
843 /** \class TGeoRotation
844 \ingroup Geometry_classes
845 Class describing rotations. A rotation is a 3*3 array
846 Column vectors has to be orthogonal unit vectors.
847 */
848 
850 
851 ////////////////////////////////////////////////////////////////////////////////
852 /// Default constructor.
853 
855 {
856  for (Int_t i=0; i<9; i++) {
857  if (i%4) fRotationMatrix[i] = 0;
858  else fRotationMatrix[i] = 1.0;
859  }
860 }
861 
862 ////////////////////////////////////////////////////////////////////////////////
863 /// Copy ctor.
864 
866  :TGeoMatrix(other)
867 {
868  SetRotation(other);
869 }
870 
871 ////////////////////////////////////////////////////////////////////////////////
872 /// Copy ctor.
873 
875  :TGeoMatrix(other)
876 {
879  SetRotation(other);
880 }
881 
882 ////////////////////////////////////////////////////////////////////////////////
883 /// Named rotation constructor
884 
886  :TGeoMatrix(name)
887 {
888  for (Int_t i=0; i<9; i++) {
889  if (i%4) fRotationMatrix[i] = 0;
890  else fRotationMatrix[i] = 1.0;
891  }
892 }
893 
894 ////////////////////////////////////////////////////////////////////////////////
895 /// Default rotation constructor with Euler angles. Phi is the rotation angle about
896 /// Z axis and is done first, theta is the rotation about new Y and is done
897 /// second, psi is the rotation angle about new Z and is done third. All angles are in
898 /// degrees.
899 
901  :TGeoMatrix(name)
902 {
903  SetAngles(phi, theta, psi);
904 }
905 
906 ////////////////////////////////////////////////////////////////////////////////
907 /// Rotation constructor a la GEANT3. Angles theta(i), phi(i) are the polar and azimuthal
908 /// angles of the (i) axis of the rotated system with respect to the initial non-rotated
909 /// system.
910 /// Example : the identity matrix (no rotation) is composed by
911 /// theta1=90, phi1=0, theta2=90, phi2=90, theta3=0, phi3=0
912 /// SetBit(kGeoRotation);
913 
914 TGeoRotation::TGeoRotation(const char *name, Double_t theta1, Double_t phi1, Double_t theta2, Double_t phi2,
915  Double_t theta3, Double_t phi3)
916  :TGeoMatrix(name)
917 {
918  SetAngles(theta1, phi1, theta2, phi2, theta3, phi3);
919 }
920 
921 ////////////////////////////////////////////////////////////////////////////////
922 /// Assignment from a general matrix
923 
925 {
926  if (&other == this) return *this;
927  Bool_t registered = TestBit(kGeoRegistered);
928  TNamed::operator=(other);
929  SetRotation(other);
930  SetBit(kGeoRegistered,registered);
933  return *this;
934 }
935 
936 ////////////////////////////////////////////////////////////////////////////////
937 /// Composition
938 
940 {
941  if (!right.IsRotation()) return *this;
942  MultiplyBy(&right, true);
943  return *this;
944 }
945 
947 {
948  TGeoRotation r = *this;
949  r *= right;
950  return r;
951 }
952 
954 {
955  TGeoHMatrix t = *this;
956  t *= right;
957  return t;
958 }
959 
960 ////////////////////////////////////////////////////////////////////////////////
961 /// Is-equal operator
962 
964 {
965  if (&other == this) return kTRUE;
966  const Double_t *rot = GetRotationMatrix();
967  const Double_t *orot = other.GetRotationMatrix();
968  for (auto i=0; i<9; i++)
969  if (TMath::Abs(rot[i]-orot[i])>1.E-10) return kFALSE;
970  return kTRUE;
971 }
972 
973 ////////////////////////////////////////////////////////////////////////////////
974 /// Return a temporary inverse of this.
975 
977 {
978  TGeoHMatrix h;
979  h = *this;
980  Double_t newrot[9];
981  newrot[0] = fRotationMatrix[0];
982  newrot[1] = fRotationMatrix[3];
983  newrot[2] = fRotationMatrix[6];
984  newrot[3] = fRotationMatrix[1];
985  newrot[4] = fRotationMatrix[4];
986  newrot[5] = fRotationMatrix[7];
987  newrot[6] = fRotationMatrix[2];
988  newrot[7] = fRotationMatrix[5];
989  newrot[8] = fRotationMatrix[8];
990  h.SetRotation(newrot);
991  return h;
992 }
993 
994 ////////////////////////////////////////////////////////////////////////////////
995 /// Perform orthogonality test for rotation.
996 
998 {
999  const Double_t *r = fRotationMatrix;
1000  Double_t cij;
1001  for (Int_t i=0; i<2; i++) {
1002  for (Int_t j=i+1; j<3; j++) {
1003  // check columns
1004  cij = TMath::Abs(r[i]*r[j]+r[i+3]*r[j+3]+r[i+6]*r[j+6]);
1005  if (cij>1E-4) return kFALSE;
1006  // check rows
1007  cij = TMath::Abs(r[3*i]*r[3*j]+r[3*i+1]*r[3*j+1]+r[3*i+2]*r[3*j+2]);
1008  if (cij>1E-4) return kFALSE;
1009  }
1010  }
1011  return kTRUE;
1012 }
1013 
1014 ////////////////////////////////////////////////////////////////////////////////
1015 /// reset data members
1016 
1018 {
1021 }
1022 
1023 ////////////////////////////////////////////////////////////////////////////////
1024 /// Perform a rotation about Z having the sine/cosine of the rotation angle.
1025 
1027 {
1028  fRotationMatrix[0] = sincos[1];
1029  fRotationMatrix[1] = -sincos[0];
1030  fRotationMatrix[3] = sincos[0];
1031  fRotationMatrix[4] = sincos[1];
1033 }
1034 
1035 ////////////////////////////////////////////////////////////////////////////////
1036 /// Returns rotation angle about Z axis in degrees. If the rotation is a pure
1037 /// rotation about Z, fixX parameter does not matter, otherwise its meaning is:
1038 /// - fixX = true : result is the phi angle of the projection of the rotated X axis in the un-rotated XY
1039 /// - fixX = false : result is the phi angle of the projection of the rotated Y axis - 90 degrees
1040 
1042 {
1043  Double_t phi;
1044  if (fixX) phi = 180.*TMath::ATan2(-fRotationMatrix[1],fRotationMatrix[4])/TMath::Pi();
1045  else phi = 180.*TMath::ATan2(fRotationMatrix[3], fRotationMatrix[0])/TMath::Pi();
1046  return phi;
1047 }
1048 
1049 ////////////////////////////////////////////////////////////////////////////////
1050 /// convert a point by multiplying its column vector (x, y, z, 1) to matrix inverse
1051 
1052 void TGeoRotation::LocalToMaster(const Double_t *local, Double_t *master) const
1053 {
1054  const Double_t *rot = GetRotationMatrix();
1055  for (Int_t i=0; i<3; i++) {
1056  master[i] = local[0]*rot[3*i]
1057  + local[1]*rot[3*i+1]
1058  + local[2]*rot[3*i+2];
1059  }
1060 }
1061 
1062 ////////////////////////////////////////////////////////////////////////////////
1063 /// convert a point by multiplying its column vector (x, y, z, 1) to matrix
1064 
1065 void TGeoRotation::MasterToLocal(const Double_t *master, Double_t *local) const
1066 {
1067  const Double_t *rot = GetRotationMatrix();
1068  for (Int_t i=0; i<3; i++) {
1069  local[i] = master[0]*rot[i]
1070  + master[1]*rot[i+3]
1071  + master[2]*rot[i+6];
1072  }
1073 }
1074 
1075 ////////////////////////////////////////////////////////////////////////////////
1076 /// Make a clone of this matrix.
1077 
1079 {
1080  TGeoMatrix *matrix = new TGeoRotation(*this);
1081  return matrix;
1082 }
1083 
1084 ////////////////////////////////////////////////////////////////////////////////
1085 /// Rotate about X axis of the master frame with angle expressed in degrees.
1086 
1088 {
1090  Double_t phi = angle*TMath::DegToRad();
1091  Double_t c = TMath::Cos(phi);
1092  Double_t s = TMath::Sin(phi);
1093  Double_t v[9];
1094  v[0] = fRotationMatrix[0];
1095  v[1] = fRotationMatrix[1];
1096  v[2] = fRotationMatrix[2];
1097  v[3] = c*fRotationMatrix[3]-s*fRotationMatrix[6];
1098  v[4] = c*fRotationMatrix[4]-s*fRotationMatrix[7];
1099  v[5] = c*fRotationMatrix[5]-s*fRotationMatrix[8];
1100  v[6] = s*fRotationMatrix[3]+c*fRotationMatrix[6];
1101  v[7] = s*fRotationMatrix[4]+c*fRotationMatrix[7];
1102  v[8] = s*fRotationMatrix[5]+c*fRotationMatrix[8];
1103 
1104  memcpy(fRotationMatrix, v, kN9);
1105 }
1106 
1107 ////////////////////////////////////////////////////////////////////////////////
1108 /// Rotate about Y axis of the master frame with angle expressed in degrees.
1109 
1111 {
1113  Double_t phi = angle*TMath::DegToRad();
1114  Double_t c = TMath::Cos(phi);
1115  Double_t s = TMath::Sin(phi);
1116  Double_t v[9];
1117  v[0] = c*fRotationMatrix[0]+s*fRotationMatrix[6];
1118  v[1] = c*fRotationMatrix[1]+s*fRotationMatrix[7];
1119  v[2] = c*fRotationMatrix[2]+s*fRotationMatrix[8];
1120  v[3] = fRotationMatrix[3];
1121  v[4] = fRotationMatrix[4];
1122  v[5] = fRotationMatrix[5];
1123  v[6] = -s*fRotationMatrix[0]+c*fRotationMatrix[6];
1124  v[7] = -s*fRotationMatrix[1]+c*fRotationMatrix[7];
1125  v[8] = -s*fRotationMatrix[2]+c*fRotationMatrix[8];
1126 
1127  memcpy(fRotationMatrix, v, kN9);
1128 }
1129 
1130 ////////////////////////////////////////////////////////////////////////////////
1131 /// Rotate about Z axis of the master frame with angle expressed in degrees.
1132 
1134 {
1136  Double_t phi = angle*TMath::DegToRad();
1137  Double_t c = TMath::Cos(phi);
1138  Double_t s = TMath::Sin(phi);
1139  Double_t v[9];
1140  v[0] = c*fRotationMatrix[0]-s*fRotationMatrix[3];
1141  v[1] = c*fRotationMatrix[1]-s*fRotationMatrix[4];
1142  v[2] = c*fRotationMatrix[2]-s*fRotationMatrix[5];
1143  v[3] = s*fRotationMatrix[0]+c*fRotationMatrix[3];
1144  v[4] = s*fRotationMatrix[1]+c*fRotationMatrix[4];
1145  v[5] = s*fRotationMatrix[2]+c*fRotationMatrix[5];
1146  v[6] = fRotationMatrix[6];
1147  v[7] = fRotationMatrix[7];
1148  v[8] = fRotationMatrix[8];
1149 
1150  memcpy(&fRotationMatrix[0],v,kN9);
1151 }
1152 
1153 ////////////////////////////////////////////////////////////////////////////////
1154 /// Multiply by a reflection respect to YZ.
1155 
1157 {
1158  if (leftside) {
1162  } else {
1166  }
1169 }
1170 
1171 ////////////////////////////////////////////////////////////////////////////////
1172 /// Multiply by a reflection respect to ZX.
1173 
1175 {
1176  if (leftside) {
1180  } else {
1184  }
1187 }
1188 
1189 ////////////////////////////////////////////////////////////////////////////////
1190 /// Multiply by a reflection respect to XY.
1191 
1193 {
1194  if (leftside) {
1198  } else {
1202  }
1205 }
1206 
1207 ////////////////////////////////////////////////////////////////////////////////
1208 /// Save a primitive as a C++ statement(s) on output stream "out".
1209 
1210 void TGeoRotation::SavePrimitive(std::ostream &out, Option_t * /*option*/ /*= ""*/)
1211 {
1212  if (TestBit(kGeoSavePrimitive)) return;
1213  out << " // Rotation: " << GetName() << std::endl;
1214  Double_t th1,ph1,th2,ph2,th3,ph3;
1215  GetAngles(th1,ph1,th2,ph2,th3,ph3);
1216  out << " thx = " << th1 << "; phx = " << ph1 << ";" << std::endl;
1217  out << " thy = " << th2 << "; phy = " << ph2 << ";" << std::endl;
1218  out << " thz = " << th3 << "; phz = " << ph3 << ";" << std::endl;
1219  out << " TGeoRotation *" << GetPointerName() << " = new TGeoRotation(\"" << GetName() << "\",thx,phx,thy,phy,thz,phz);" << std::endl;
1221 }
1222 
1223 ////////////////////////////////////////////////////////////////////////////////
1224 /// Copy rotation elements from other rotation matrix.
1225 
1227 {
1228  SetBit(kGeoRotation, other.IsRotation());
1229  SetMatrix(other.GetRotationMatrix());
1230 }
1231 
1232 ////////////////////////////////////////////////////////////////////////////////
1233 /// Set matrix elements according to Euler angles
1234 
1236 {
1237  Double_t degrad = TMath::Pi()/180.;
1238  Double_t sinphi = TMath::Sin(degrad*phi);
1239  Double_t cosphi = TMath::Cos(degrad*phi);
1240  Double_t sinthe = TMath::Sin(degrad*theta);
1241  Double_t costhe = TMath::Cos(degrad*theta);
1242  Double_t sinpsi = TMath::Sin(degrad*psi);
1243  Double_t cospsi = TMath::Cos(degrad*psi);
1244 
1245  fRotationMatrix[0] = cospsi*cosphi - costhe*sinphi*sinpsi;
1246  fRotationMatrix[1] = -sinpsi*cosphi - costhe*sinphi*cospsi;
1247  fRotationMatrix[2] = sinthe*sinphi;
1248  fRotationMatrix[3] = cospsi*sinphi + costhe*cosphi*sinpsi;
1249  fRotationMatrix[4] = -sinpsi*sinphi + costhe*cosphi*cospsi;
1250  fRotationMatrix[5] = -sinthe*cosphi;
1251  fRotationMatrix[6] = sinpsi*sinthe;
1252  fRotationMatrix[7] = cospsi*sinthe;
1253  fRotationMatrix[8] = costhe;
1254 
1255  if (!IsValid()) Error("SetAngles", "invalid rotation (Euler angles : phi=%f theta=%f psi=%f)",phi,theta,psi);
1256  CheckMatrix();
1257 }
1258 
1259 ////////////////////////////////////////////////////////////////////////////////
1260 /// Set matrix elements in the GEANT3 way
1261 
1263  Double_t theta3, Double_t phi3)
1264 {
1265  Double_t degrad = TMath::Pi()/180.;
1266  fRotationMatrix[0] = TMath::Cos(degrad*phi1)*TMath::Sin(degrad*theta1);
1267  fRotationMatrix[3] = TMath::Sin(degrad*phi1)*TMath::Sin(degrad*theta1);
1268  fRotationMatrix[6] = TMath::Cos(degrad*theta1);
1269  fRotationMatrix[1] = TMath::Cos(degrad*phi2)*TMath::Sin(degrad*theta2);
1270  fRotationMatrix[4] = TMath::Sin(degrad*phi2)*TMath::Sin(degrad*theta2);
1271  fRotationMatrix[7] = TMath::Cos(degrad*theta2);
1272  fRotationMatrix[2] = TMath::Cos(degrad*phi3)*TMath::Sin(degrad*theta3);
1273  fRotationMatrix[5] = TMath::Sin(degrad*phi3)*TMath::Sin(degrad*theta3);
1274  fRotationMatrix[8] = TMath::Cos(degrad*theta3);
1275  // do the trick to eliminate most of the floating point errors
1276  for (Int_t i=0; i<9; i++) {
1277  if (TMath::Abs(fRotationMatrix[i])<1E-15) fRotationMatrix[i] = 0;
1278  if (TMath::Abs(fRotationMatrix[i]-1)<1E-15) fRotationMatrix[i] = 1;
1279  if (TMath::Abs(fRotationMatrix[i]+1)<1E-15) fRotationMatrix[i] = -1;
1280  }
1281  if (!IsValid()) Error("SetAngles", "invalid rotation (G3 angles, th1=%f phi1=%f, th2=%f ph2=%f, th3=%f phi3=%f)",
1282  theta1,phi1,theta2,phi2,theta3,phi3);
1283  CheckMatrix();
1284 }
1285 
1286 ////////////////////////////////////////////////////////////////////////////////
1287 /// Retrieve rotation angles
1288 
1289 void TGeoRotation::GetAngles(Double_t &theta1, Double_t &phi1, Double_t &theta2, Double_t &phi2,
1290  Double_t &theta3, Double_t &phi3) const
1291 {
1292  Double_t raddeg = 180./TMath::Pi();
1293  theta1 = raddeg*TMath::ACos(fRotationMatrix[6]);
1294  theta2 = raddeg*TMath::ACos(fRotationMatrix[7]);
1295  theta3 = raddeg*TMath::ACos(fRotationMatrix[8]);
1296  if (TMath::Abs(fRotationMatrix[0])<1E-6 && TMath::Abs(fRotationMatrix[3])<1E-6) phi1=0.;
1297  else phi1 = raddeg*TMath::ATan2(fRotationMatrix[3],fRotationMatrix[0]);
1298  if (phi1<0) phi1+=360.;
1299  if (TMath::Abs(fRotationMatrix[1])<1E-6 && TMath::Abs(fRotationMatrix[4])<1E-6) phi2=0.;
1300  else phi2 = raddeg*TMath::ATan2(fRotationMatrix[4],fRotationMatrix[1]);
1301  if (phi2<0) phi2+=360.;
1302  if (TMath::Abs(fRotationMatrix[2])<1E-6 && TMath::Abs(fRotationMatrix[5])<1E-6) phi3=0.;
1303  else phi3 = raddeg*TMath::ATan2(fRotationMatrix[5],fRotationMatrix[2]);
1304  if (phi3<0) phi3+=360.;
1305 }
1306 
1307 ////////////////////////////////////////////////////////////////////////////////
1308 /// Retrieve Euler angles.
1309 
1310 void TGeoRotation::GetAngles(Double_t &phi, Double_t &theta, Double_t &psi) const
1311 {
1312  const Double_t *m = fRotationMatrix;
1313  // Check if theta is 0 or 180.
1314  if (TMath::Abs(1.-TMath::Abs(m[8]))<1.e-9) {
1315  theta = TMath::ACos(m[8])*TMath::RadToDeg();
1316  phi = TMath::ATan2(-m[8]*m[1],m[0])*TMath::RadToDeg();
1317  psi = 0.; // convention, phi+psi matters
1318  return;
1319  }
1320  // sin(theta) != 0
1321  phi = TMath::ATan2(m[2],-m[5]);
1322  Double_t sphi = TMath::Sin(phi);
1323  if (TMath::Abs(sphi)<1.e-9) theta = -TMath::ASin(m[5]/TMath::Cos(phi))*TMath::RadToDeg();
1324  else theta = TMath::ASin(m[2]/sphi)*TMath::RadToDeg();
1325  phi *= TMath::RadToDeg();
1326  psi = TMath::ATan2(m[6],m[7])*TMath::RadToDeg();
1327 }
1328 
1329 ////////////////////////////////////////////////////////////////////////////////
1330 /// computes determinant of the rotation matrix
1331 
1333 {
1334  Double_t
1341  return det;
1342 }
1343 
1344 ////////////////////////////////////////////////////////////////////////////////
1345 /// performes an orthogonality check and finds if the matrix is a reflection
1346 /// Warning("CheckMatrix", "orthogonality check not performed yet");
1347 
1349 {
1350  if (Determinant() < 0) SetBit(kGeoReflection);
1352  if (TMath::Abs(dd) < 1.E-12) ResetBit(kGeoRotation);
1353  else SetBit(kGeoRotation);
1354 }
1355 
1356 ////////////////////////////////////////////////////////////////////////////////
1357 /// Get the inverse rotation matrix (which is simply the transpose)
1358 
1360 {
1361  if (!invmat) {
1362  Error("GetInverse", "no place to store the inverse matrix");
1363  return;
1364  }
1365  for (Int_t i=0; i<3; i++) {
1366  for (Int_t j=0; j<3; j++) {
1367  invmat[3*i+j] = fRotationMatrix[3*j+i];
1368  }
1369  }
1370 }
1371 
1372 ////////////////////////////////////////////////////////////////////////////////
1373 /// Multiply this rotation with the one specified by ROT.
1374 /// - after=TRUE (default): THIS*ROT
1375 /// - after=FALSE : ROT*THIS
1376 
1378 {
1379  const Double_t *matleft, *matright;
1381  Double_t newmat[9] = {0};
1382  if (after) {
1383  matleft = &fRotationMatrix[0];
1384  matright = rot->GetRotationMatrix();
1385  } else {
1386  matleft = rot->GetRotationMatrix();
1387  matright = &fRotationMatrix[0];
1388  }
1389  for (Int_t i=0; i<3; i++) {
1390  for (Int_t j=0; j<3; j++) {
1391  for (Int_t k=0; k<3; k++) {
1392  newmat[3*i+j] += matleft[3*i+k] * matright[3*k+j];
1393  }
1394  }
1395  }
1396  memcpy(&fRotationMatrix[0], &newmat[0], kN9);
1397 }
1398 
1399 /** \class TGeoScale
1400 \ingroup Geometry_classes
1401 Class describing scale transformations. A scale is an
1402 array of 3 doubles (sx, sy, sz) multiplying elements 0, 5 and 10
1403 of the homogenous matrix. A scale is normalized : sx*sy*sz = 1
1404 */
1405 
1407 
1408 ////////////////////////////////////////////////////////////////////////////////
1409 /// default constructor
1410 
1412 {
1413  SetBit(kGeoScale);
1414  for (Int_t i=0; i<3; i++) fScale[i] = 1.;
1415 }
1416 
1417 ////////////////////////////////////////////////////////////////////////////////
1418 /// Copy constructor
1419 
1421  :TGeoMatrix(other)
1422 {
1423  SetScale(other);
1424 }
1425 
1426 ////////////////////////////////////////////////////////////////////////////////
1427 /// Ctor. based on a general matrix
1428 
1430  :TGeoMatrix(other)
1431 {
1434  SetScale(other);
1435 }
1436 
1437 ////////////////////////////////////////////////////////////////////////////////
1438 /// default constructor
1439 
1441  :TGeoMatrix("")
1442 {
1443  SetBit(kGeoScale);
1444  SetScale(sx, sy, sz);
1445 }
1446 
1447 ////////////////////////////////////////////////////////////////////////////////
1448 /// default constructor
1449 
1451  :TGeoMatrix(name)
1452 {
1453  SetBit(kGeoScale);
1454  SetScale(sx, sy, sz);
1455 }
1456 
1457 ////////////////////////////////////////////////////////////////////////////////
1458 /// destructor
1459 
1461 {
1462 }
1463 
1464 ////////////////////////////////////////////////////////////////////////////////
1465 /// Assignment from a general matrix
1466 
1468 {
1469  if (&matrix == this) return *this;
1470  Bool_t registered = TestBit(kGeoRegistered);
1471  TNamed::operator=(matrix);
1472  SetScale(matrix);
1473  SetBit(kGeoRegistered,registered);
1476  return *this;
1477 }
1478 
1479 ////////////////////////////////////////////////////////////////////////////////
1480 /// Scale composition
1481 
1483 {
1484  const Double_t *scl = right.GetScale();
1485  fScale[0] *= scl[0];
1486  fScale[1] *= scl[1];
1487  fScale[2] *= scl[2];
1488  SetBit(kGeoReflection, fScale[0] * fScale[1] * fScale[2] < 0);
1489  if (!IsScale()) SetBit(kGeoScale, right.IsScale());
1490  return *this;
1491 }
1492 
1494 {
1495  TGeoScale s = *this;
1496  s *= right;
1497  return s;
1498 }
1499 
1501 {
1502  TGeoHMatrix t = *this;
1503  t *= right;
1504  return t;
1505 }
1506 
1507 ////////////////////////////////////////////////////////////////////////////////
1508 /// Is-equal operator
1509 
1511 {
1512  if (&other == this) return kTRUE;
1513  const Double_t *scl = GetScale();
1514  const Double_t *oscl = other.GetScale();
1515  for (auto i=0; i<3; i++)
1516  if (TMath::Abs(scl[i]-oscl[i])>1.E-10) return kFALSE;
1517  return kTRUE;
1518 }
1519 
1520 ////////////////////////////////////////////////////////////////////////////////
1521 /// Return a temporary inverse of this.
1522 
1524 {
1525  TGeoHMatrix h;
1526  h = *this;
1527  Double_t scale[3];
1528  scale[0] = 1./fScale[0];
1529  scale[1] = 1./fScale[1];
1530  scale[2] = 1./fScale[2];
1531  h.SetScale(scale);
1532  return h;
1533 }
1534 
1535 ////////////////////////////////////////////////////////////////////////////////
1536 /// scale setter
1537 
1539 {
1540  if (TMath::Abs(sx*sy*sz) < 1.E-10) {
1541  Error("SetScale", "Invalid scale %f, %f, %f for transformation %s",sx,sy,sx,GetName());
1542  return;
1543  }
1544  fScale[0] = sx;
1545  fScale[1] = sy;
1546  fScale[2] = sz;
1547  if (sx*sy*sz<0) SetBit(kGeoReflection);
1548  else SetBit(kGeoReflection, kFALSE);
1549 }
1550 
1551 ////////////////////////////////////////////////////////////////////////////////
1552 /// Set scale from other transformation
1553 
1555 {
1556  SetBit(kGeoScale, other.IsScale());
1558  memcpy(fScale, other.GetScale(), kN3);
1559 }
1560 
1561 ////////////////////////////////////////////////////////////////////////////////
1562 /// Convert a local point to the master frame.
1563 
1564 void TGeoScale::LocalToMaster(const Double_t *local, Double_t *master) const
1565 {
1566  master[0] = local[0]*fScale[0];
1567  master[1] = local[1]*fScale[1];
1568  master[2] = local[2]*fScale[2];
1569 }
1570 
1571 ////////////////////////////////////////////////////////////////////////////////
1572 /// Convert the local distance along unit vector DIR to master frame. If DIR
1573 /// is not specified perform a conversion such as the returned distance is the
1574 /// the minimum for all possible directions.
1575 
1577 {
1578  Double_t scale;
1579  if (!dir) {
1580  scale = TMath::Abs(fScale[0]);
1581  if (TMath::Abs(fScale[1])<scale) scale = TMath::Abs(fScale[1]);
1582  if (TMath::Abs(fScale[2])<scale) scale = TMath::Abs(fScale[2]);
1583  } else {
1584  scale = fScale[0]*fScale[0]*dir[0]*dir[0] +
1585  fScale[1]*fScale[1]*dir[1]*dir[1] +
1586  fScale[2]*fScale[2]*dir[2]*dir[2];
1587  scale = TMath::Sqrt(scale);
1588  }
1589  return scale*dist;
1590 }
1591 
1592 ////////////////////////////////////////////////////////////////////////////////
1593 /// Make a clone of this matrix.
1594 
1596 {
1597  TGeoMatrix *matrix = new TGeoScale(*this);
1598  return matrix;
1599 }
1600 
1601 ////////////////////////////////////////////////////////////////////////////////
1602 /// Convert a global point to local frame.
1603 
1604 void TGeoScale::MasterToLocal(const Double_t *master, Double_t *local) const
1605 {
1606  local[0] = master[0]/fScale[0];
1607  local[1] = master[1]/fScale[1];
1608  local[2] = master[2]/fScale[2];
1609 }
1610 
1611 ////////////////////////////////////////////////////////////////////////////////
1612 /// Convert the distance along unit vector DIR to local frame. If DIR
1613 /// is not specified perform a conversion such as the returned distance is the
1614 /// the minimum for all possible directions.
1615 
1617 {
1618  Double_t scale;
1619  if (!dir) {
1620  scale = TMath::Abs(fScale[0]);
1621  if (TMath::Abs(fScale[1])>scale) scale = TMath::Abs(fScale[1]);
1622  if (TMath::Abs(fScale[2])>scale) scale = TMath::Abs(fScale[2]);
1623  scale = 1./scale;
1624  } else {
1625  scale = (dir[0]*dir[0])/(fScale[0]*fScale[0]) +
1626  (dir[1]*dir[1])/(fScale[1]*fScale[1]) +
1627  (dir[2]*dir[2])/(fScale[2]*fScale[2]);
1628  scale = TMath::Sqrt(scale);
1629  }
1630  return scale*dist;
1631 }
1632 
1633 /** \class TGeoCombiTrans
1634 \ingroup Geometry_classes
1635 Class describing rotation + translation. Most frequently used in the description
1636 of TGeoNode 's
1637 */
1638 
1640 
1641 ////////////////////////////////////////////////////////////////////////////////
1642 /// dummy ctor
1643 
1645 {
1646  for (Int_t i=0; i<3; i++) fTranslation[i] = 0.0;
1647  fRotation = 0;
1648 }
1649 
1650 ////////////////////////////////////////////////////////////////////////////////
1651 /// Copy ctor from generic matrix.
1652 
1654  :TGeoMatrix(other)
1655 {
1657  if (other.IsTranslation()) {
1659  memcpy(fTranslation,other.GetTranslation(),kN3);
1660  } else {
1661  for (Int_t i=0; i<3; i++) fTranslation[i] = 0.0;
1662  }
1663  if (other.IsRotation()) {
1666  fRotation = new TGeoRotation(other);
1667  }
1668  else fRotation = 0;
1669 }
1670 
1671 ////////////////////////////////////////////////////////////////////////////////
1672 /// Constructor from a translation and a rotation.
1673 
1675 {
1676  if (tr.IsTranslation()) {
1678  const Double_t *trans = tr.GetTranslation();
1679  memcpy(fTranslation, trans, kN3);
1680  } else {
1681  for (Int_t i=0; i<3; i++) fTranslation[i] = 0.0;
1682  }
1683  if (rot.IsRotation()) {
1686  fRotation = new TGeoRotation(rot);
1688  }
1689  else fRotation = 0;
1690 }
1691 
1692 ////////////////////////////////////////////////////////////////////////////////
1693 /// Named ctor.
1694 
1696  :TGeoMatrix(name)
1697 {
1698  for (Int_t i=0; i<3; i++) fTranslation[i] = 0.0;
1699  fRotation = 0;
1700 }
1701 
1702 ////////////////////////////////////////////////////////////////////////////////
1703 /// Constructor from a translation specified by X,Y,Z and a pointer to a rotation. The rotation will not be owned by this.
1704 
1706  :TGeoMatrix("")
1707 {
1708  SetTranslation(dx, dy, dz);
1709  fRotation = 0;
1710  SetRotation(rot);
1711 }
1712 
1713 ////////////////////////////////////////////////////////////////////////////////
1714 /// Named ctor
1715 
1717  :TGeoMatrix(name)
1718 {
1719  SetTranslation(dx, dy, dz);
1720  fRotation = 0;
1721  SetRotation(rot);
1722 }
1723 
1724 ////////////////////////////////////////////////////////////////////////////////
1725 /// Assignment operator with generic matrix.
1726 
1728 {
1729  if (&matrix == this) return *this;
1730  Bool_t registered = TestBit(kGeoRegistered);
1731  Clear();
1732  TNamed::operator=(matrix);
1733 
1734  if (matrix.IsTranslation()) {
1735  memcpy(fTranslation,matrix.GetTranslation(),kN3);
1736  }
1737  if (matrix.IsRotation()) {
1738  if (!fRotation) {
1739  fRotation = new TGeoRotation();
1741  } else {
1742  if (!TestBit(kGeoMatrixOwned)) {
1743  fRotation = new TGeoRotation();
1745  }
1746  }
1750  } else {
1751  if (fRotation && TestBit(kGeoMatrixOwned)) delete fRotation;
1753  fRotation = 0;
1754  }
1755  SetBit(kGeoRegistered,registered);
1757  return *this;
1758 }
1759 
1760 ////////////////////////////////////////////////////////////////////////////////
1761 /// Is-equal operator
1762 
1764 {
1765  if (&other == this) return kTRUE;
1766  const Double_t *tr = GetTranslation();
1767  const Double_t *otr = other.GetTranslation();
1768  for (auto i=0; i<3; i++) if (TMath::Abs(tr[i]-otr[i])>1.E-10) return kFALSE;
1769  const Double_t *rot = GetRotationMatrix();
1770  const Double_t *orot = other.GetRotationMatrix();
1771  for (auto i=0; i<9; i++) if (TMath::Abs(rot[i]-orot[i])>1.E-10) return kFALSE;
1772  return kTRUE;
1773 }
1774 
1775 ////////////////////////////////////////////////////////////////////////////////
1776 /// Composition
1777 
1779 {
1780  Multiply(&right);
1781  return *this;
1782 }
1783 
1785 {
1786  TGeoHMatrix h = *this;
1787  h *= right;
1788  return h;
1789 }
1790 
1791 ////////////////////////////////////////////////////////////////////////////////
1792 /// destructor
1793 
1795 {
1796  if (fRotation) {
1798  }
1799 }
1800 
1801 ////////////////////////////////////////////////////////////////////////////////
1802 /// Reset translation/rotation to identity
1803 
1805 {
1806  if (IsTranslation()) {
1808  memset(fTranslation, 0, kN3);
1809  }
1810  if (fRotation) {
1811  if (TestBit(kGeoMatrixOwned)) delete fRotation;
1812  fRotation = 0;
1813  }
1817 }
1818 
1819 ////////////////////////////////////////////////////////////////////////////////
1820 /// Return a temporary inverse of this.
1821 
1823 {
1824  TGeoHMatrix h;
1825  h = *this;
1826  Bool_t is_tr = IsTranslation();
1827  Bool_t is_rot = IsRotation();
1828  Double_t tr[3];
1829  Double_t newrot[9];
1830  const Double_t *rot = GetRotationMatrix();
1831  tr[0] = -fTranslation[0]*rot[0] - fTranslation[1]*rot[3] - fTranslation[2]*rot[6];
1832  tr[1] = -fTranslation[0]*rot[1] - fTranslation[1]*rot[4] - fTranslation[2]*rot[7];
1833  tr[2] = -fTranslation[0]*rot[2] - fTranslation[1]*rot[5] - fTranslation[2]*rot[8];
1834  h.SetTranslation(tr);
1835  newrot[0] = rot[0];
1836  newrot[1] = rot[3];
1837  newrot[2] = rot[6];
1838  newrot[3] = rot[1];
1839  newrot[4] = rot[4];
1840  newrot[5] = rot[7];
1841  newrot[6] = rot[2];
1842  newrot[7] = rot[5];
1843  newrot[8] = rot[8];
1844  h.SetRotation(newrot);
1845  h.SetBit(kGeoTranslation,is_tr);
1846  h.SetBit(kGeoRotation,is_rot);
1847  return h;
1848 }
1849 
1850 ////////////////////////////////////////////////////////////////////////////////
1851 /// Make a clone of this matrix.
1852 
1854 {
1855  TGeoMatrix *matrix = new TGeoCombiTrans(*this);
1856  return matrix;
1857 }
1858 
1859 ////////////////////////////////////////////////////////////////////////////////
1860 /// multiply to the right with an other transformation
1861 /// if right is identity matrix, just return
1862 
1864 {
1865  if (right->IsIdentity()) return;
1866  TGeoHMatrix h = *this;
1867  h.Multiply(right);
1868  operator=(h);
1869 }
1870 
1871 ////////////////////////////////////////////////////////////////////////////////
1872 /// Register the matrix in the current manager, which will become the owner.
1873 
1875 {
1878 }
1879 
1880 ////////////////////////////////////////////////////////////////////////////////
1881 /// Rotate about X axis with angle expressed in degrees.
1882 
1884 {
1885  if (!fRotation || !TestBit(kGeoMatrixOwned)) {
1887  else fRotation = new TGeoRotation();
1889  }
1891  const Double_t *rot = fRotation->GetRotationMatrix();
1892  Double_t phi = angle*TMath::DegToRad();
1893  Double_t c = TMath::Cos(phi);
1894  Double_t s = TMath::Sin(phi);
1895  Double_t v[9];
1896  v[0] = rot[0];
1897  v[1] = rot[1];
1898  v[2] = rot[2];
1899  v[3] = c*rot[3]-s*rot[6];
1900  v[4] = c*rot[4]-s*rot[7];
1901  v[5] = c*rot[5]-s*rot[8];
1902  v[6] = s*rot[3]+c*rot[6];
1903  v[7] = s*rot[4]+c*rot[7];
1904  v[8] = s*rot[5]+c*rot[8];
1905  fRotation->SetMatrix(v);
1907  if (!IsTranslation()) return;
1908  v[0] = fTranslation[0];
1909  v[1] = c*fTranslation[1]-s*fTranslation[2];
1910  v[2] = s*fTranslation[1]+c*fTranslation[2];
1911  memcpy(fTranslation,v,kN3);
1912 }
1913 
1914 ////////////////////////////////////////////////////////////////////////////////
1915 /// Rotate about Y axis with angle expressed in degrees.
1916 
1918 {
1919  if (!fRotation || !TestBit(kGeoMatrixOwned)) {
1921  else fRotation = new TGeoRotation();
1923  }
1925  const Double_t *rot = fRotation->GetRotationMatrix();
1926  Double_t phi = angle*TMath::DegToRad();
1927  Double_t c = TMath::Cos(phi);
1928  Double_t s = TMath::Sin(phi);
1929  Double_t v[9];
1930  v[0] = c*rot[0]+s*rot[6];
1931  v[1] = c*rot[1]+s*rot[7];
1932  v[2] = c*rot[2]+s*rot[8];
1933  v[3] = rot[3];
1934  v[4] = rot[4];
1935  v[5] = rot[5];
1936  v[6] = -s*rot[0]+c*rot[6];
1937  v[7] = -s*rot[1]+c*rot[7];
1938  v[8] = -s*rot[2]+c*rot[8];
1939  fRotation->SetMatrix(v);
1941  if (!IsTranslation()) return;
1942  v[0] = c*fTranslation[0]+s*fTranslation[2];
1943  v[1] = fTranslation[1];
1944  v[2] = -s*fTranslation[0]+c*fTranslation[2];
1945  memcpy(fTranslation,v,kN3);
1946 }
1947 
1948 ////////////////////////////////////////////////////////////////////////////////
1949 /// Rotate about Z axis with angle expressed in degrees.
1950 
1952 {
1953  if (!fRotation || !TestBit(kGeoMatrixOwned)) {
1955  else fRotation = new TGeoRotation();
1957  }
1959  const Double_t *rot = fRotation->GetRotationMatrix();
1960  Double_t phi = angle*TMath::DegToRad();
1961  Double_t c = TMath::Cos(phi);
1962  Double_t s = TMath::Sin(phi);
1963  Double_t v[9];
1964  v[0] = c*rot[0]-s*rot[3];
1965  v[1] = c*rot[1]-s*rot[4];
1966  v[2] = c*rot[2]-s*rot[5];
1967  v[3] = s*rot[0]+c*rot[3];
1968  v[4] = s*rot[1]+c*rot[4];
1969  v[5] = s*rot[2]+c*rot[5];
1970  v[6] = rot[6];
1971  v[7] = rot[7];
1972  v[8] = rot[8];
1973  fRotation->SetMatrix(v);
1975  if (!IsTranslation()) return;
1976  v[0] = c*fTranslation[0]-s*fTranslation[1];
1977  v[1] = s*fTranslation[0]+c*fTranslation[1];
1978  v[2] = fTranslation[2];
1979  memcpy(fTranslation,v,kN3);
1980 }
1981 
1982 ////////////////////////////////////////////////////////////////////////////////
1983 /// Multiply by a reflection respect to YZ.
1984 
1985 void TGeoCombiTrans::ReflectX(Bool_t leftside, Bool_t rotonly)
1986 {
1987  if (leftside && !rotonly) fTranslation[0] = -fTranslation[0];
1988  if (!fRotation || !TestBit(kGeoMatrixOwned)) {
1990  else fRotation = new TGeoRotation();
1992  }
1994  fRotation->ReflectX(leftside);
1996 }
1997 
1998 ////////////////////////////////////////////////////////////////////////////////
1999 /// Multiply by a reflection respect to ZX.
2000 
2001 void TGeoCombiTrans::ReflectY(Bool_t leftside, Bool_t rotonly)
2002 {
2003  if (leftside && !rotonly) fTranslation[1] = -fTranslation[1];
2004  if (!fRotation || !TestBit(kGeoMatrixOwned)) {
2006  else fRotation = new TGeoRotation();
2008  }
2010  fRotation->ReflectY(leftside);
2012 }
2013 
2014 ////////////////////////////////////////////////////////////////////////////////
2015 /// Multiply by a reflection respect to XY.
2016 
2017 void TGeoCombiTrans::ReflectZ(Bool_t leftside, Bool_t rotonly)
2018 {
2019  if (leftside && !rotonly) fTranslation[2] = -fTranslation[2];
2020  if (!fRotation || !TestBit(kGeoMatrixOwned)) {
2022  else fRotation = new TGeoRotation();
2024  }
2026  fRotation->ReflectZ(leftside);
2028 }
2029 
2030 ////////////////////////////////////////////////////////////////////////////////
2031 /// Save a primitive as a C++ statement(s) on output stream "out".
2032 
2033 void TGeoCombiTrans::SavePrimitive(std::ostream &out, Option_t *option /*= ""*/)
2034 {
2035  if (TestBit(kGeoSavePrimitive)) return;
2036  out << " // Combi transformation: " << GetName() << std::endl;
2037  out << " dx = " << fTranslation[0] << ";" << std::endl;
2038  out << " dy = " << fTranslation[1] << ";" << std::endl;
2039  out << " dz = " << fTranslation[2] << ";" << std::endl;
2040  if (fRotation && fRotation->IsRotation()) {
2041  fRotation->SavePrimitive(out,option);
2042  out << " " << GetPointerName() << " = new TGeoCombiTrans(\"" << GetName() << "\", dx,dy,dz,";
2043  out << fRotation->GetPointerName() << ");" << std::endl;
2044  } else {
2045  out << " " << GetPointerName() << " = new TGeoCombiTrans(\"" << GetName() << "\");" << std::endl;
2046  out << " " << GetPointerName() << "->SetTranslation(dx,dy,dz);" << std::endl;
2047  }
2049 }
2050 
2051 ////////////////////////////////////////////////////////////////////////////////
2052 /// Assign a foreign rotation to the combi. The rotation is NOT owned by this.
2053 
2055 {
2056  if (fRotation && TestBit(kGeoMatrixOwned)) delete fRotation;
2057  fRotation = 0;
2061  if (!rot) return;
2062  if (!rot->IsRotation()) return;
2063 
2066  TGeoRotation *rr = (TGeoRotation*)rot;
2067  fRotation = rr;
2068 }
2069 
2070 ////////////////////////////////////////////////////////////////////////////////
2071 /// Copy the rotation from another one.
2072 
2074 {
2075  if (fRotation && TestBit(kGeoMatrixOwned)) delete fRotation;
2076  fRotation = 0;
2077  if (!rot.IsRotation()) {
2081  return;
2082  }
2083 
2086  fRotation = new TGeoRotation(rot);
2088 }
2089 
2090 ////////////////////////////////////////////////////////////////////////////////
2091 /// copy the translation component
2092 
2094 {
2095  if (tr.IsTranslation()) {
2097  const Double_t *trans = tr.GetTranslation();
2098  memcpy(fTranslation, trans, kN3);
2099  } else {
2100  if (!IsTranslation()) return;
2101  memset(fTranslation, 0, kN3);
2103  }
2104 }
2105 
2106 ////////////////////////////////////////////////////////////////////////////////
2107 /// set the translation component
2108 
2110 {
2111  fTranslation[0] = dx;
2112  fTranslation[1] = dy;
2113  fTranslation[2] = dz;
2115  else ResetBit(kGeoTranslation);
2116 }
2117 
2118 ////////////////////////////////////////////////////////////////////////////////
2119 /// set the translation component
2120 
2122 {
2123  fTranslation[0] = vect[0];
2124  fTranslation[1] = vect[1];
2125  fTranslation[2] = vect[2];
2127  else ResetBit(kGeoTranslation);
2128 }
2129 
2130 ////////////////////////////////////////////////////////////////////////////////
2131 /// get the rotation array
2132 
2134 {
2135  if (!fRotation) return kIdentityMatrix;
2136  return fRotation->GetRotationMatrix();
2137 }
2138 
2139 /** \class TGeoGenTrans
2140 \ingroup Geometry_classes
2141 Most general transformation, holding a translation, a rotation and a scale
2142 */
2143 
2145 
2146 ////////////////////////////////////////////////////////////////////////////////
2147 /// dummy ctor
2148 
2150 {
2152  for (Int_t i=0; i<3; i++) fTranslation[i] = 0.0;
2153  for (Int_t j=0; j<3; j++) fScale[j] = 1.0;
2154  fRotation = 0;
2155 }
2156 
2157 ////////////////////////////////////////////////////////////////////////////////
2158 /// constructor
2159 
2161  :TGeoCombiTrans(name)
2162 {
2164  for (Int_t i=0; i<3; i++) fTranslation[i] = 0.0;
2165  for (Int_t j=0; j<3; j++) fScale[j] = 1.0;
2166  fRotation = 0;
2167 }
2168 
2169 ////////////////////////////////////////////////////////////////////////////////
2170 /// constructor
2171 
2173  Double_t sx, Double_t sy, Double_t sz, TGeoRotation *rot)
2174  :TGeoCombiTrans("")
2175 {
2177  SetTranslation(dx, dy, dz);
2178  SetScale(sx, sy, sz);
2179  SetRotation(rot);
2180 }
2181 
2182 ////////////////////////////////////////////////////////////////////////////////
2183 /// constructor
2184 
2186  Double_t sx, Double_t sy, Double_t sz, TGeoRotation *rot)
2187  :TGeoCombiTrans(name)
2188 {
2190  SetTranslation(dx, dy, dz);
2191  SetScale(sx, sy, sz);
2192  SetRotation(rot);
2193 }
2194 
2195 ////////////////////////////////////////////////////////////////////////////////
2196 /// destructor
2197 
2199 {
2200 }
2201 
2202 ////////////////////////////////////////////////////////////////////////////////
2203 /// clear the fields of this transformation
2204 
2206 {
2207  memset(&fTranslation[0], 0, kN3);
2208  memset(&fScale[0], 0, kN3);
2209  if (fRotation) fRotation->Clear();
2210 }
2211 
2212 ////////////////////////////////////////////////////////////////////////////////
2213 /// set the scale
2214 
2216 {
2217  if (sx<1.E-5 || sy<1.E-5 || sz<1.E-5) {
2218  Error("ctor", "Invalid scale");
2219  return;
2220  }
2221  fScale[0] = sx;
2222  fScale[1] = sy;
2223  fScale[2] = sz;
2224 }
2225 
2226 ////////////////////////////////////////////////////////////////////////////////
2227 /// Return a temporary inverse of this.
2228 
2230 {
2231  TGeoHMatrix h = *this;
2232  return h;
2233 }
2234 
2235 ////////////////////////////////////////////////////////////////////////////////
2236 /// A scale transformation should be normalized by sx*sy*sz factor
2237 
2239 {
2240  Double_t normfactor = fScale[0]*fScale[1]*fScale[2];
2241  if (normfactor <= 1E-5) return kFALSE;
2242  for (Int_t i=0; i<3; i++)
2243  fScale[i] /= normfactor;
2244  return kTRUE;
2245 }
2246 
2247 /** \class TGeoIdentity
2248 \ingroup Geometry_classes
2249 An identity transformation. It holds no data member
2250 and returns pointers to static null translation and identity
2251 transformations for rotation and scale
2252 */
2253 
2255 
2256 ////////////////////////////////////////////////////////////////////////////////
2257 /// dummy ctor
2258 
2260 {
2261  if (!gGeoIdentity) gGeoIdentity = this;
2262  RegisterYourself();
2263 }
2264 
2265 ////////////////////////////////////////////////////////////////////////////////
2266 /// constructor
2267 
2269  :TGeoMatrix(name)
2270 {
2271  if (!gGeoIdentity) gGeoIdentity = this;
2272  RegisterYourself();
2273 }
2274 
2275 ////////////////////////////////////////////////////////////////////////////////
2276 /// Return a temporary inverse of this.
2277 
2279 {
2281  return h;
2282 }
2283 
2284 /** \class TGeoHMatrix
2285 \ingroup Geometry_classes
2286 
2287 Matrix class used for computing global transformations
2288 Should NOT be used for node definition. An instance of this class
2289 is generally used to pile-up local transformations starting from
2290 the top level physical node, down to the current node.
2291 */
2292 
2294 
2295 ////////////////////////////////////////////////////////////////////////////////
2296 /// dummy ctor
2297 
2299 {
2300  memset(&fTranslation[0], 0, kN3);
2301  memcpy(fRotationMatrix,kIdentityMatrix,kN9);
2302  memcpy(fScale,kUnitScale,kN3);
2303 }
2304 
2305 ////////////////////////////////////////////////////////////////////////////////
2306 /// constructor
2307 
2309  :TGeoMatrix(name)
2310 {
2311  memset(&fTranslation[0], 0, kN3);
2313  memcpy(fScale,kUnitScale,kN3);
2314 }
2315 
2316 ////////////////////////////////////////////////////////////////////////////////
2317 /// assignment
2318 
2320  :TGeoMatrix(matrix)
2321 {
2322  memset(&fTranslation[0], 0, kN3);
2324  memcpy(fScale,kUnitScale,kN3);
2325  if (matrix.IsIdentity()) return;
2326  if (matrix.IsTranslation())
2327  SetTranslation(matrix.GetTranslation());
2328  if (matrix.IsRotation())
2329  memcpy(fRotationMatrix,matrix.GetRotationMatrix(),kN9);
2330  if (matrix.IsScale())
2331  memcpy(fScale,matrix.GetScale(),kN3);
2332 }
2333 
2334 ////////////////////////////////////////////////////////////////////////////////
2335 /// destructor
2336 
2338 {
2339 }
2340 
2341 ////////////////////////////////////////////////////////////////////////////////
2342 /// assignment
2343 
2345 {
2346  return TGeoHMatrix::operator=(*matrix);
2347 }
2348 
2349 ////////////////////////////////////////////////////////////////////////////////
2350 /// assignment
2351 
2353 {
2354  if (&matrix == this) return *this;
2355  Clear();
2356  Bool_t registered = TestBit(kGeoRegistered);
2357  TNamed::operator=(matrix);
2358  if (matrix.IsIdentity()) return *this;
2359  if (matrix.IsTranslation())
2360  memcpy(fTranslation,matrix.GetTranslation(),kN3);
2361  if (matrix.IsRotation())
2362  memcpy(fRotationMatrix,matrix.GetRotationMatrix(),kN9);
2363  if (matrix.IsScale())
2364  memcpy(fScale,matrix.GetScale(),kN3);
2365  SetBit(kGeoRegistered,registered);
2366  return *this;
2367 }
2368 
2369 ////////////////////////////////////////////////////////////////////////////////
2370 /// Composition
2371 
2373 {
2374  Multiply(&right);
2375  return *this;
2376 }
2377 
2379 {
2380  TGeoHMatrix h = *this;
2381  h *= right;
2382  return h;
2383 }
2384 
2385 ////////////////////////////////////////////////////////////////////////////////
2386 /// Is-equal operator
2387 
2389 {
2390  if (&other == this) return kTRUE;
2391  const Double_t *tr = GetTranslation();
2392  const Double_t *otr = other.GetTranslation();
2393  for (auto i=0; i<3; i++) if (TMath::Abs(tr[i]-otr[i])>1.E-10) return kFALSE;
2394  const Double_t *rot = GetRotationMatrix();
2395  const Double_t *orot = other.GetRotationMatrix();
2396  for (auto i=0; i<9; i++) if (TMath::Abs(rot[i]-orot[i])>1.E-10) return kFALSE;
2397  const Double_t *scl = GetScale();
2398  const Double_t *oscl = other.GetScale();
2399  for (auto i=0; i<3; i++) if (TMath::Abs(scl[i]-oscl[i])>1.E-10) return kFALSE;
2400  return kTRUE;
2401 }
2402 
2403 ////////////////////////////////////////////////////////////////////////////////
2404 /// Fast copy method.
2405 
2407 {
2409  SetBit(kGeoRotation, other->IsRotation());
2410  SetBit(kGeoReflection, other->IsReflection());
2411  memcpy(fTranslation,other->GetTranslation(),kN3);
2412  memcpy(fRotationMatrix,other->GetRotationMatrix(),kN9);
2413 }
2414 
2415 ////////////////////////////////////////////////////////////////////////////////
2416 /// clear the data for this matrix
2417 
2419 {
2421  if (IsIdentity()) return;
2425  memcpy(fTranslation,kNullVector,kN3);
2427  memcpy(fScale,kUnitScale,kN3);
2428 }
2429 
2430 ////////////////////////////////////////////////////////////////////////////////
2431 /// Make a clone of this matrix.
2432 
2434 {
2435  TGeoMatrix *matrix = new TGeoHMatrix(*this);
2436  return matrix;
2437 }
2438 
2439 ////////////////////////////////////////////////////////////////////////////////
2440 /// Perform a rotation about Z having the sine/cosine of the rotation angle.
2441 
2442 void TGeoHMatrix::FastRotZ(const Double_t *sincos)
2443 {
2444  fRotationMatrix[0] = sincos[1];
2445  fRotationMatrix[1] = -sincos[0];
2446  fRotationMatrix[3] = sincos[0];
2447  fRotationMatrix[4] = sincos[1];
2449 }
2450 
2451 ////////////////////////////////////////////////////////////////////////////////
2452 /// Return a temporary inverse of this.
2453 
2455 {
2456  TGeoHMatrix h;
2457  h = *this;
2458  if (IsTranslation()) {
2459  Double_t tr[3];
2461  tr[1] = -fTranslation[0]*fRotationMatrix[1] - fTranslation[1]*fRotationMatrix[4] - fTranslation[2]*fRotationMatrix[7];
2462  tr[2] = -fTranslation[0]*fRotationMatrix[2] - fTranslation[1]*fRotationMatrix[5] - fTranslation[2]*fRotationMatrix[8];
2463  h.SetTranslation(tr);
2464  }
2465  if (IsRotation()) {
2466  Double_t newrot[9];
2467  newrot[0] = fRotationMatrix[0];
2468  newrot[1] = fRotationMatrix[3];
2469  newrot[2] = fRotationMatrix[6];
2470  newrot[3] = fRotationMatrix[1];
2471  newrot[4] = fRotationMatrix[4];
2472  newrot[5] = fRotationMatrix[7];
2473  newrot[6] = fRotationMatrix[2];
2474  newrot[7] = fRotationMatrix[5];
2475  newrot[8] = fRotationMatrix[8];
2476  h.SetRotation(newrot);
2477  }
2478  if (IsScale()) {
2479  Double_t sc[3];
2480  sc[0] = 1./fScale[0];
2481  sc[1] = 1./fScale[1];
2482  sc[2] = 1./fScale[2];
2483  h.SetScale(sc);
2484  }
2485  return h;
2486 }
2487 
2488 ////////////////////////////////////////////////////////////////////////////////
2489 /// computes determinant of the rotation matrix
2490 
2492 {
2493  Double_t
2500  return det;
2501 }
2502 
2503 ////////////////////////////////////////////////////////////////////////////////
2504 /// multiply to the right with an other transformation
2505 /// if right is identity matrix, just return
2506 
2508 {
2509  if (right->IsIdentity()) return;
2510  const Double_t *r_tra = right->GetTranslation();
2511  const Double_t *r_rot = right->GetRotationMatrix();
2512  const Double_t *r_scl = right->GetScale();
2513  if (IsIdentity()) {
2514  if (right->IsRotation()) {
2516  memcpy(fRotationMatrix,r_rot,kN9);
2518  }
2519  if (right->IsScale()) {
2520  SetBit(kGeoScale);
2521  memcpy(fScale,r_scl,kN3);
2522  }
2523  if (right->IsTranslation()) {
2525  memcpy(fTranslation,r_tra,kN3);
2526  }
2527  return;
2528  }
2529  Int_t i, j;
2530  Double_t new_rot[9];
2531 
2532  if (right->IsRotation()) {
2535  }
2536  if (right->IsScale()) SetBit(kGeoScale);
2537  if (right->IsTranslation()) SetBit(kGeoTranslation);
2538 
2539  // new translation
2540  if (IsTranslation()) {
2541  for (i=0; i<3; i++) {
2542  fTranslation[i] += fRotationMatrix[3*i]*r_tra[0]
2543  + fRotationMatrix[3*i+1]*r_tra[1]
2544  + fRotationMatrix[3*i+2]*r_tra[2];
2545  }
2546  }
2547  if (IsRotation()) {
2548  // new rotation
2549  for (i=0; i<3; i++) {
2550  for (j=0; j<3; j++) {
2551  new_rot[3*i+j] = fRotationMatrix[3*i]*r_rot[j] +
2552  fRotationMatrix[3*i+1]*r_rot[3+j] +
2553  fRotationMatrix[3*i+2]*r_rot[6+j];
2554  }
2555  }
2556  memcpy(fRotationMatrix,new_rot,kN9);
2557  }
2558  // new scale
2559  if (IsScale()) {
2560  for (i=0; i<3; i++) fScale[i] *= r_scl[i];
2561  }
2562 }
2563 
2564 ////////////////////////////////////////////////////////////////////////////////
2565 /// multiply to the left with an other transformation
2566 /// if right is identity matrix, just return
2567 
2569 {
2570  if (left == gGeoIdentity) return;
2571  const Double_t *l_tra = left->GetTranslation();
2572  const Double_t *l_rot = left->GetRotationMatrix();
2573  const Double_t *l_scl = left->GetScale();
2574  if (IsIdentity()) {
2575  if (left->IsRotation()) {
2578  memcpy(fRotationMatrix,l_rot,kN9);
2579  }
2580  if (left->IsScale()) {
2581  SetBit(kGeoScale);
2582  memcpy(fScale,l_scl,kN3);
2583  }
2584  if (left->IsTranslation()) {
2586  memcpy(fTranslation,l_tra,kN3);
2587  }
2588  return;
2589  }
2590  Int_t i, j;
2591  Double_t new_tra[3];
2592  Double_t new_rot[9];
2593 
2594  if (left->IsRotation()) {
2597  }
2598  if (left->IsScale()) SetBit(kGeoScale);
2599  if (left->IsTranslation()) SetBit(kGeoTranslation);
2600 
2601  // new translation
2602  if (IsTranslation()) {
2603  for (i=0; i<3; i++) {
2604  new_tra[i] = l_tra[i]
2605  + l_rot[3*i]* fTranslation[0]
2606  + l_rot[3*i+1]*fTranslation[1]
2607  + l_rot[3*i+2]*fTranslation[2];
2608  }
2609  memcpy(fTranslation,new_tra,kN3);
2610  }
2611  if (IsRotation()) {
2612  // new rotation
2613  for (i=0; i<3; i++) {
2614  for (j=0; j<3; j++) {
2615  new_rot[3*i+j] = l_rot[3*i]*fRotationMatrix[j] +
2616  l_rot[3*i+1]*fRotationMatrix[3+j] +
2617  l_rot[3*i+2]*fRotationMatrix[6+j];
2618  }
2619  }
2620  memcpy(fRotationMatrix,new_rot,kN9);
2621  }
2622  // new scale
2623  if (IsScale()) {
2624  for (i=0; i<3; i++) fScale[i] *= l_scl[i];
2625  }
2626 }
2627 
2628 ////////////////////////////////////////////////////////////////////////////////
2629 /// Rotate about X axis with angle expressed in degrees.
2630 
2632 {
2634  Double_t phi = angle*TMath::DegToRad();
2635  Double_t c = TMath::Cos(phi);
2636  Double_t s = TMath::Sin(phi);
2637  Double_t v[9];
2638  v[0] = fRotationMatrix[0];
2639  v[1] = fRotationMatrix[1];
2640  v[2] = fRotationMatrix[2];
2641  v[3] = c*fRotationMatrix[3]-s*fRotationMatrix[6];
2642  v[4] = c*fRotationMatrix[4]-s*fRotationMatrix[7];
2643  v[5] = c*fRotationMatrix[5]-s*fRotationMatrix[8];
2644  v[6] = s*fRotationMatrix[3]+c*fRotationMatrix[6];
2645  v[7] = s*fRotationMatrix[4]+c*fRotationMatrix[7];
2646  v[8] = s*fRotationMatrix[5]+c*fRotationMatrix[8];
2647  memcpy(fRotationMatrix, v, kN9);
2648 
2649  v[0] = fTranslation[0];
2650  v[1] = c*fTranslation[1]-s*fTranslation[2];
2651  v[2] = s*fTranslation[1]+c*fTranslation[2];
2652  memcpy(fTranslation,v,kN3);
2653 }
2654 
2655 ////////////////////////////////////////////////////////////////////////////////
2656 /// Rotate about Y axis with angle expressed in degrees.
2657 
2659 {
2661  Double_t phi = angle*TMath::DegToRad();
2662  Double_t c = TMath::Cos(phi);
2663  Double_t s = TMath::Sin(phi);
2664  Double_t v[9];
2665  v[0] = c*fRotationMatrix[0]+s*fRotationMatrix[6];
2666  v[1] = c*fRotationMatrix[1]+s*fRotationMatrix[7];
2667  v[2] = c*fRotationMatrix[2]+s*fRotationMatrix[8];
2668  v[3] = fRotationMatrix[3];
2669  v[4] = fRotationMatrix[4];
2670  v[5] = fRotationMatrix[5];
2671  v[6] = -s*fRotationMatrix[0]+c*fRotationMatrix[6];
2672  v[7] = -s*fRotationMatrix[1]+c*fRotationMatrix[7];
2673  v[8] = -s*fRotationMatrix[2]+c*fRotationMatrix[8];
2674  memcpy(fRotationMatrix, v, kN9);
2675 
2676  v[0] = c*fTranslation[0]+s*fTranslation[2];
2677  v[1] = fTranslation[1];
2678  v[2] = -s*fTranslation[0]+c*fTranslation[2];
2679  memcpy(fTranslation,v,kN3);
2680 }
2681 
2682 ////////////////////////////////////////////////////////////////////////////////
2683 /// Rotate about Z axis with angle expressed in degrees.
2684 
2686 {
2688  Double_t phi = angle*TMath::DegToRad();
2689  Double_t c = TMath::Cos(phi);
2690  Double_t s = TMath::Sin(phi);
2691  Double_t v[9];
2692  v[0] = c*fRotationMatrix[0]-s*fRotationMatrix[3];
2693  v[1] = c*fRotationMatrix[1]-s*fRotationMatrix[4];
2694  v[2] = c*fRotationMatrix[2]-s*fRotationMatrix[5];
2695  v[3] = s*fRotationMatrix[0]+c*fRotationMatrix[3];
2696  v[4] = s*fRotationMatrix[1]+c*fRotationMatrix[4];
2697  v[5] = s*fRotationMatrix[2]+c*fRotationMatrix[5];
2698  v[6] = fRotationMatrix[6];
2699  v[7] = fRotationMatrix[7];
2700  v[8] = fRotationMatrix[8];
2701  memcpy(&fRotationMatrix[0],v,kN9);
2702 
2703  v[0] = c*fTranslation[0]-s*fTranslation[1];
2704  v[1] = s*fTranslation[0]+c*fTranslation[1];
2705  v[2] = fTranslation[2];
2706  memcpy(fTranslation,v,kN3);
2707 }
2708 
2709 ////////////////////////////////////////////////////////////////////////////////
2710 /// Multiply by a reflection respect to YZ.
2711 
2712 void TGeoHMatrix::ReflectX(Bool_t leftside, Bool_t rotonly)
2713 {
2714  if (leftside && !rotonly) fTranslation[0] = -fTranslation[0];
2715  if (leftside) {
2719  } else {
2723  }
2726 }
2727 
2728 ////////////////////////////////////////////////////////////////////////////////
2729 /// Multiply by a reflection respect to ZX.
2730 
2731 void TGeoHMatrix::ReflectY(Bool_t leftside, Bool_t rotonly)
2732 {
2733  if (leftside && !rotonly) fTranslation[1] = -fTranslation[1];
2734  if (leftside) {
2738  } else {
2742  }
2745 }
2746 
2747 ////////////////////////////////////////////////////////////////////////////////
2748 /// Multiply by a reflection respect to XY.
2749 
2750 void TGeoHMatrix::ReflectZ(Bool_t leftside, Bool_t rotonly)
2751 {
2752  if (leftside && !rotonly) fTranslation[2] = -fTranslation[2];
2753  if (leftside) {
2757  } else {
2761  }
2764 }
2765 
2766 ////////////////////////////////////////////////////////////////////////////////
2767 /// Save a primitive as a C++ statement(s) on output stream "out".
2768 
2769 void TGeoHMatrix::SavePrimitive(std::ostream &out, Option_t * /*option*/ /*= ""*/)
2770 {
2771  if (TestBit(kGeoSavePrimitive)) return;
2772  const Double_t *tr = fTranslation;
2773  const Double_t *rot = fRotationMatrix;
2774  out << " // HMatrix: " << GetName() << std::endl;
2775  out << " tr[0] = " << tr[0] << "; " << "tr[1] = " << tr[1] << "; " << "tr[2] = " << tr[2] << ";" << std::endl;
2776  out << " rot[0] =" << rot[0] << "; " << "rot[1] = " << rot[1] << "; " << "rot[2] = " << rot[2] << ";" << std::endl;
2777  out << " rot[3] =" << rot[3] << "; " << "rot[4] = " << rot[4] << "; " << "rot[5] = " << rot[5] << ";" << std::endl;
2778  out << " rot[6] =" << rot[6] << "; " << "rot[7] = " << rot[7] << "; " << "rot[8] = " << rot[8] << ";" << std::endl;
2779  char *name = GetPointerName();
2780  out << " TGeoHMatrix *" << name << " = new TGeoHMatrix(\"" << GetName() << "\");" << std::endl;
2781  out << " " << name << "->SetTranslation(tr);" << std::endl;
2782  out << " " << name << "->SetRotation(rot);" << std::endl;
2783  if (IsTranslation()) out << " " << name << "->SetBit(TGeoMatrix::kGeoTranslation);" << std::endl;
2784  if (IsRotation()) out << " " << name << "->SetBit(TGeoMatrix::kGeoRotation);" << std::endl;
2785  if (IsReflection()) out << " " << name << "->SetBit(TGeoMatrix::kGeoReflection);" << std::endl;
2787 }
void Subtract(const TGeoTranslation *other)
Subtracting a translation from this one.
Definition: TGeoMatrix.cxx:740
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:47
virtual UInt_t GetUniqueID() const
Return the unique object id.
Definition: TObject.cxx:375
virtual void LocalToMaster(const Double_t *local, Double_t *master) const
convert a point by multiplying its column vector (x, y, z, 1) to matrix inverse
double dist(Rotation3D const &r1, Rotation3D const &r2)
Definition: 3DDistances.cxx:48
const Double_t kIdentityMatrix[3 *3]
Definition: TGeoMatrix.h:26
void SetRotation(const TGeoRotation &other)
Copy the rotation from another one.
An array of TObjects.
Definition: TObjArray.h:37
void Print(Option_t *option="") const
print the matrix in 4x4 format
Definition: TGeoMatrix.cxx:486
virtual void MasterToLocal(const Double_t *master, Double_t *local) const
convert a point by multiplying its column vector (x, y, z, 1) to matrix
Double_t fRotationMatrix[9]
Definition: TGeoMatrix.h:424
TGeoMatrix()
dummy constructor
Definition: TGeoMatrix.cxx:231
Bool_t IsGeneral() const
Definition: TGeoMatrix.h:75
virtual void MasterToLocalVect(const Double_t *master, Double_t *local) const
convert a point by multiplying its column vector (x, y, z, 1) to matrix
Definition: TGeoMatrix.cxx:431
auto * m
Definition: textangle.C:8
void FastRotZ(const Double_t *sincos)
Perform a rotation about Z having the sine/cosine of the rotation angle.
TGeoHMatrix operator*(const TGeoMatrix &other) const
TGeoScale & operator*=(const TGeoScale &other)
Scale composition.
void FastRotZ(const Double_t *sincos)
Perform a rotation about Z having the sine/cosine of the rotation angle.
void MultiplyLeft(const TGeoMatrix *left)
multiply to the left with an other transformation if right is identity matrix, just return ...
virtual ~TGeoScale()
destructor
void BombTranslation(const Double_t *tr, Double_t *bombtr)
Get the new &#39;bombed&#39; translation vector according current exploded view mode.
const char Option_t
Definition: RtypesCore.h:62
Geometrical transformation package.
Definition: TGeoMatrix.h:40
Bool_t operator==(const TGeoRotation &other) const
Is-equal operator.
Definition: TGeoMatrix.cxx:963
Bool_t operator==(const TGeoMatrix &other) const
Is-equal operator.
virtual const Double_t * GetRotationMatrix() const
Definition: TGeoMatrix.h:468
virtual const Double_t * GetTranslation() const
Definition: TGeoMatrix.h:467
virtual TGeoMatrix * MakeClone() const
Make a clone of this matrix.
virtual void ReflectX(Bool_t leftside, Bool_t rotonly=kFALSE)
Multiply by a reflection respect to YZ.
virtual const Double_t * GetRotationMatrix() const =0
const Double_t kNullVector[3]
Definition: TGeoMatrix.h:24
virtual void SetName(const char *name)
Set the name of the TNamed.
Definition: TNamed.cxx:140
TH1 * h
Definition: legend2.C:5
virtual void MasterToLocal(const Double_t *master, Double_t *local) const
Convert a global point to local frame.
virtual void ReflectZ(Bool_t leftside, Bool_t rotonly=kFALSE)
Multiply by a reflection respect to XY.
An identity transformation.
Definition: TGeoMatrix.h:383
TGeoCombiTrans operator*(const TGeoMatrix &other) const
virtual void RotateX(Double_t angle)
Rotate about X axis of the master frame with angle expressed in degrees.
Most general transformation, holding a translation, a rotation and a scale.
Definition: TGeoMatrix.h:350
TGeoCombiTrans()
dummy ctor
void SetTranslation(const Double_t *vect)
Definition: TGeoMatrix.h:462
TGeoRotation()
Default constructor.
Definition: TGeoMatrix.cxx:854
TGeoTranslation operator*(const TGeoTranslation &right) const
Definition: TGeoMatrix.cxx:652
Double_t fScale[3]
Definition: TGeoMatrix.h:425
Class describing translations.
Definition: TGeoMatrix.h:121
virtual TObject * Remove(TObject *obj)
Remove object from array.
Definition: TObjArray.cxx:703
Bool_t operator==(const TGeoScale &other) const
Is-equal operator.
R__ALWAYS_INLINE Bool_t TestBit(UInt_t f) const
Definition: TObject.h:172
Double_t fTranslation[3]
Definition: TGeoMatrix.h:423
virtual void MasterToLocalBomb(const Double_t *master, Double_t *local) const
convert a point by multiplying its column vector (x, y, z, 1) to matrix
Definition: TGeoMatrix.cxx:448
virtual const Double_t * GetScale() const
Definition: TGeoMatrix.h:469
Basic string class.
Definition: TString.h:125
Matrix class used for computing global transformations Should NOT be used for node definition...
Definition: TGeoMatrix.h:420
void Multiply(const TGeoMatrix *right)
multiply to the right with an other transformation if right is identity matrix, just return ...
int Int_t
Definition: RtypesCore.h:41
bool Bool_t
Definition: RtypesCore.h:59
void GetInverse(Double_t *invmat) const
Get the inverse rotation matrix (which is simply the transpose)
void Add(const TGeoTranslation *other)
Adding a translation to this one.
Definition: TGeoMatrix.cxx:697
const Double_t kUnitScale[3]
Definition: TGeoMatrix.h:30
virtual void RotateY(Double_t angle)
Rotate about Y axis with angle expressed in degrees.
void SetTranslation(const TGeoTranslation &tr)
copy the translation component
virtual ~TGeoCombiTrans()
destructor
virtual const Double_t * GetScale() const
Definition: TGeoMatrix.h:279
auto * th1
Definition: textalign.C:13
TGeoHMatrix Inverse() const
Return a temporary inverse of this.
Definition: TGeoMatrix.cxx:976
Short_t Abs(Short_t d)
Definition: TMathBase.h:108
virtual void ReflectY(Bool_t leftside, Bool_t rotonly=kFALSE)
Multiply by a reflection respect to ZX.
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
Definition: TObject.cxx:694
virtual void RotateY(Double_t angle)
Rotate about Y axis with angle expressed in degrees.
TGeoRotation & operator=(const TGeoRotation &other)
Definition: TGeoMatrix.h:191
virtual void RotateX(Double_t angle)
Rotate about X axis with angle expressed in degrees.
TGeoHMatrix Inverse() const
Return a temporary inverse of this.
TGeoHMatrix Inverse() const
Return a temporary inverse of this.
Double_t fTranslation[3]
Definition: TGeoMatrix.h:294
TGeoScale operator*(const TGeoScale &other) const
virtual void RotateX(Double_t angle)
Rotate about X axis with angle expressed in degrees.
virtual void SavePrimitive(std::ostream &out, Option_t *option="")
Save a primitive as a C++ statement(s) on output stream "out".
Definition: TGeoMatrix.cxx:832
virtual void RotateZ(Double_t angle)
Rotate about Z axis with angle expressed in degrees.
virtual void ReflectY(Bool_t leftside, Bool_t rotonly=kFALSE)
Multiply by a reflection respect to ZX.
virtual ~TGeoHMatrix()
destructor
static TString Format(const char *fmt,...)
Static method which formats a string using a printf style format descriptor and return a TString...
Definition: TString.cxx:2365
Bool_t Normalize()
A scale transformation should be normalized by sx*sy*sz factor.
Double_t GetPhiRotation(Bool_t fixX=kFALSE) const
Returns rotation angle about Z axis in degrees.
The TNamed class is the base class for all named ROOT classes.
Definition: TNamed.h:29
Double_t Determinant() const
computes determinant of the rotation matrix
virtual void ReflectZ(Bool_t leftside, Bool_t rotonly=kFALSE)
Multiply by a reflection respect to XY.
constexpr Double_t DegToRad()
Definition: TMath.h:64
virtual ~TGeoGenTrans()
destructor
Bool_t IsShared() const
Definition: TGeoMatrix.h:71
Bool_t IsIdentity() const
Definition: TGeoMatrix.h:66
void Multiply(const TGeoMatrix *right)
multiply to the right with an other transformation if right is identity matrix, just return ...
TGeoHMatrix()
dummy ctor
Bool_t IsOwned() const
Definition: TGeoMatrix.h:72
TGeoRotation operator*(const TGeoRotation &other) const
Definition: TGeoMatrix.cxx:946
Double_t ATan2(Double_t, Double_t)
Definition: TMath.h:580
auto * th3
Definition: textalign.C:21
void CopyFrom(const TGeoMatrix *other)
Fast copy method.
virtual void LocalToMasterVect(const Double_t *local, Double_t *master) const
convert a vector by multiplying its column vector (x, y, z, 1) to matrix inverse
Definition: TGeoMatrix.cxx:363
virtual void RotateY(Double_t angle)
Rotate about Y axis of the master frame with angle expressed in degrees.
constexpr Double_t Pi()
Definition: TMath.h:40
char * GetPointerName() const
Provide a pointer name containing uid.
Definition: TGeoMatrix.cxx:294
virtual const Double_t * GetTranslation() const
Definition: TGeoMatrix.h:160
TGeoHMatrix Inverse() const
Return a temporary inverse of this.
virtual TGeoMatrix * MakeClone() const
Make a clone of this matrix.
virtual void ReflectX(Bool_t leftside, Bool_t rotonly=kFALSE)
Multiply by a reflection respect to YZ.
TGeoTranslation & operator*=(const TGeoTranslation &other)
Translation composition.
Definition: TGeoMatrix.cxx:642
TGeoHMatrix & operator*=(const TGeoMatrix &other)
Composition.
const Int_t kN3
Definition: TGeoMatrix.cxx:221
virtual const Double_t * GetRotationMatrix() const
Definition: TGeoMatrix.h:230
virtual void LocalToMaster(const Double_t *local, Double_t *master) const
Convert a local point to the master frame.
Double_t fScale[3]
Definition: TGeoMatrix.h:247
TGeoHMatrix Inverse() const
Return a temporary inverse of this.
TNamed & operator=(const TNamed &rhs)
TNamed assignment operator.
Definition: TNamed.cxx:51
Bool_t operator==(const TGeoMatrix &other) const
Is-equal operator.
ROOT::R::TRInterface & r
Definition: Object.C:4
virtual void RegisterYourself()
Register the matrix in the current manager, which will become the owner.
void Clear(Option_t *option="")
clear the data for this matrix
Class describing rotation + translation.
Definition: TGeoMatrix.h:291
SVector< double, 2 > v
Definition: Dict.h:5
void Clear(Option_t *option="")
clear the fields of this transformation
virtual void MasterToLocal(const Double_t *master, Double_t *local) const
convert a point by multiplying its column vector (x, y, z, 1) to matrix
Definition: TGeoMatrix.cxx:802
virtual void LocalToMasterVect(const Double_t *local, Double_t *master) const
convert a vector to MARS
Definition: TGeoMatrix.cxx:782
virtual const Double_t * GetRotationMatrix() const
get the rotation array
void Clear(Option_t *option="")
reset data members
void SetDefaultName()
If no name was supplied in the ctor, the type of transformation is checked.
Definition: TGeoMatrix.cxx:549
void CheckMatrix()
performes an orthogonality check and finds if the matrix is a reflection Warning("CheckMatrix", "orthogonality check not performed yet");
Bool_t IsRegistered() const
Definition: TGeoMatrix.h:77
virtual void LocalToMaster(const Double_t *local, Double_t *master) const
convert a point by multiplying its column vector (x, y, z, 1) to matrix inverse
Definition: TGeoMatrix.cxx:772
Int_t GetEntriesFast() const
Definition: TObjArray.h:64
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition: TObject.cxx:880
virtual TGeoMatrix * MakeClone() const
Make a clone of this matrix.
Definition: TGeoMatrix.cxx:707
virtual void RegisterYourself()
Register the matrix in the current manager, which will become the owner.
Definition: TGeoMatrix.cxx:526
TGeoTranslation & operator=(const TGeoTranslation &other)
Definition: TGeoMatrix.h:133
virtual void ReflectY(Bool_t leftside, Bool_t rotonly=kFALSE)
Multiply by a reflection respect to ZX.
Definition: TGeoMatrix.cxx:512
static void Normalize(Double_t *vect)
Normalize a vector.
Definition: TGeoMatrix.cxx:473
virtual const Double_t * GetTranslation() const
Definition: TGeoMatrix.h:336
void Clear(Option_t *option="")
Reset translation/rotation to identity.
Double_t ACos(Double_t)
Definition: TMath.h:571
virtual void ReflectY(Bool_t leftside, Bool_t rotonly=kFALSE)
Multiply by a reflection respect to ZX.
virtual Int_t GetByteCount() const
Get total size in bytes of this.
Definition: TGeoMatrix.cxx:282
void GetHomogenousMatrix(Double_t *hmat) const
The homogenous matrix associated with the transformation is used for piling up&#39;s and visualization...
Definition: TGeoMatrix.cxx:314
TGeoGenTrans()
dummy ctor
TObjArray * GetListOfMatrices() const
Definition: TGeoManager.h:462
virtual void RotateZ(Double_t angle)
Rotate about Z axis of the master frame with angle expressed in degrees.
constexpr Double_t E()
Definition: TMath.h:74
TGeoIdentity * gGeoIdentity
Definition: TGeoMatrix.cxx:220
virtual void LocalToMaster(const Double_t *local, Double_t *master) const
convert a point by multiplying its column vector (x, y, z, 1) to matrix inverse
Definition: TGeoMatrix.cxx:339
Double_t Cos(Double_t)
Definition: TMath.h:550
Class describing rotations.
Definition: TGeoMatrix.h:174
virtual void RotateZ(Double_t angle)
Rotate about Z axis of the master frame with angle expressed in degrees.
Definition: TGeoMatrix.cxx:732
Double_t fRotationMatrix[3 *3]
Definition: TGeoMatrix.h:177
const Bool_t kFALSE
Definition: RtypesCore.h:88
Bool_t IsValid() const
Perform orthogonality test for rotation.
Definition: TGeoMatrix.cxx:997
Bool_t IsRotation() const
Definition: TGeoMatrix.h:68
TGeoHMatrix Inverse() const
Return a temporary inverse of this.
virtual void ReflectZ(Bool_t leftside, Bool_t rotonly=kFALSE)
Multiply by a reflection respect to XY.
Definition: TGeoMatrix.cxx:519
Class describing scale transformations.
Definition: TGeoMatrix.h:244
#define ClassImp(name)
Definition: Rtypes.h:359
TGeoIdentity()
dummy ctor
virtual void ReflectX(Bool_t leftside, Bool_t rotonly=kFALSE)
Multiply by a reflection respect to YZ.
R__EXTERN TGeoManager * gGeoManager
Definition: TGeoManager.h:559
void GetAngles(Double_t &theta1, Double_t &phi1, Double_t &theta2, Double_t &phi2, Double_t &theta3, Double_t &phi3) const
Retrieve rotation angles.
virtual void MasterToLocal(const Double_t *master, Double_t *local) const
convert a point by multiplying its column vector (x, y, z, 1) to matrix
Definition: TGeoMatrix.cxx:406
TGeoTranslation()
Default constructor.
Definition: TGeoMatrix.cxx:579
double Double_t
Definition: RtypesCore.h:55
Bool_t IsCombi() const
Definition: TGeoMatrix.h:73
TGeoScale & operator=(const TGeoScale &other)
Definition: TGeoMatrix.h:256
const Int_t kN9
Definition: TGeoMatrix.cxx:222
virtual void ReflectZ(Bool_t leftside, Bool_t rotonly=kFALSE)
Multiply by a reflection respect to XY.
int type
Definition: TGX11.cxx:120
TGeoHMatrix Inverse() const
Return a temporary inverse of this.
Definition: TGeoMatrix.cxx:682
void RegisterMatrix(const TGeoMatrix *matrix)
Register a matrix to the list of matrices.
TGeoScale()
default constructor
static constexpr double s
you should not use this method at all Int_t Int_t Double_t Double_t Double_t e
Definition: TRolke.cxx:630
Bool_t IsScale() const
Definition: TGeoMatrix.h:70
void SetRotation(const TGeoMatrix &other)
Copy rotation elements from other rotation matrix.
Double_t Determinant() const
computes determinant of the rotation matrix
TGeoCombiTrans & operator=(const TGeoCombiTrans &other)
Definition: TGeoMatrix.h:305
TGeoCombiTrans & operator*=(const TGeoMatrix &other)
Composition.
Bool_t IsReflection() const
Definition: TGeoMatrix.h:69
virtual TGeoMatrix * MakeClone() const
Make a clone of this matrix.
virtual void SavePrimitive(std::ostream &out, Option_t *option="")
Save a primitive as a C++ statement(s) on output stream "out".
void MultiplyBy(const TGeoRotation *rot, Bool_t after=kTRUE)
Multiply this rotation with the one specified by ROT.
void SetScale(const Double_t *scale)
Definition: TGeoMatrix.h:464
void SetMatrix(const Double_t *rot)
Definition: TGeoMatrix.h:225
TGeoHMatrix & operator=(const TGeoHMatrix &other)
Definition: TGeoMatrix.h:434
constexpr Double_t RadToDeg()
Definition: TMath.h:60
Bool_t operator==(const TGeoTranslation &other) const
Is-equal operator.
Definition: TGeoMatrix.cxx:669
TGeoRotation & operator*=(const TGeoRotation &other)
Composition.
Definition: TGeoMatrix.cxx:939
void SetRotation(const Double_t *matrix)
Definition: TGeoMatrix.h:463
Bool_t IsCleaning() const
Definition: TGeoManager.h:456
virtual ~TGeoMatrix()
Destructor.
Definition: TGeoMatrix.cxx:256
TGeoRotation * fRotation
Definition: TGeoMatrix.h:295
virtual TGeoMatrix * MakeClone() const
Make a clone of this matrix.
Double_t Sin(Double_t)
Definition: TMath.h:547
Double_t ASin(Double_t)
Definition: TMath.h:565
Bool_t IsTranslation() const
Definition: TGeoMatrix.h:67
auto * th2
Definition: textalign.C:17
virtual void ReflectX(Bool_t leftside, Bool_t rotonly=kFALSE)
Multiply by a reflection respect to YZ.
Definition: TGeoMatrix.cxx:505
void SetScale(Double_t sx, Double_t sy, Double_t sz)
scale setter
virtual void MasterToLocalBomb(const Double_t *master, Double_t *local) const
convert a point by multiplying its column vector (x, y, z, 1) to matrix
Definition: TGeoMatrix.cxx:820
virtual void RotateX(Double_t angle)
Rotate about X axis of the master frame with angle expressed in degrees.
Definition: TGeoMatrix.cxx:716
virtual void RotateY(Double_t angle)
Rotate about Y axis of the master frame with angle expressed in degrees.
Definition: TGeoMatrix.cxx:724
void ResetBit(UInt_t f)
Definition: TObject.h:171
void SetAngles(Double_t phi, Double_t theta, Double_t psi)
Set matrix elements according to Euler angles.
virtual void LocalToMasterBomb(const Double_t *local, Double_t *master) const
convert a point by multiplying its column vector (x, y, z, 1) to matrix inverse
Definition: TGeoMatrix.cxx:380
Double_t Sqrt(Double_t x)
Definition: TMath.h:590
void UnbombTranslation(const Double_t *tr, Double_t *bombtr)
Get the new &#39;unbombed&#39; translation vector according current exploded view mode.
virtual void MasterToLocalVect(const Double_t *master, Double_t *local) const
convert a vector from MARS to local
Definition: TGeoMatrix.cxx:812
virtual void RotateZ(Double_t angle)
Rotate about Z axis with angle expressed in degrees.
virtual void SavePrimitive(std::ostream &out, Option_t *option="")
Save a primitive as a C++ statement(s) on output stream "out".
const Bool_t kTRUE
Definition: RtypesCore.h:87
virtual const Double_t * GetTranslation() const =0
Bool_t IsRotAboutZ() const
Returns true if no rotation or the rotation is about Z axis.
Definition: TGeoMatrix.cxx:269
virtual const Double_t * GetScale() const =0
void SetTranslation(Double_t dx, Double_t dy, Double_t dz)
Set translation components.
Definition: TGeoMatrix.cxx:750
char name[80]
Definition: TGX11.cxx:109
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition: TObject.cxx:866
virtual void SavePrimitive(std::ostream &out, Option_t *option="")
Save a primitive as a C++ statement(s) on output stream "out".
Double_t fTranslation[3]
Definition: TGeoMatrix.h:124
virtual const char * GetTitle() const
Returns title of object.
Definition: TNamed.h:48
virtual void LocalToMasterBomb(const Double_t *local, Double_t *master) const
convert a point by multiplying its column vector (x, y, z, 1) to matrix inverse
Definition: TGeoMatrix.cxx:790
void SetScale(Double_t sx, Double_t sy, Double_t sz)
set the scale
Double_t fScale[3]
Definition: TGeoMatrix.h:353
const char * Data() const
Definition: TString.h:345