ROOT   6.14/05 Reference Guide
TGeoMatrix.cxx
Go to the documentation of this file.
1 // @(#)root/geom:$Id$
2 // Author: Andrei Gheata 25/10/01
3
4 /*************************************************************************
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 {
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 {
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 {
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 {
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 {
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 {
1296  if (TMath::Abs(fRotationMatrix[0])<1E-6 && TMath::Abs(fRotationMatrix[3])<1E-6) phi1=0.;
1298  if (phi1<0) phi1+=360.;
1299  if (TMath::Abs(fRotationMatrix[1])<1E-6 && TMath::Abs(fRotationMatrix[4])<1E-6) phi2=0.;
1301  if (phi2<0) phi2+=360.;
1302  if (TMath::Abs(fRotationMatrix[2])<1E-6 && TMath::Abs(fRotationMatrix[5])<1E-6) phi3=0.;
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) {
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();
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();
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();
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();
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 {
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 {
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 {
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
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:131
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)
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:2286
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.
Conversion from degree to radian: .
Definition: TMath.h:82
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:678
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:38
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:667
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:465
virtual void RotateZ(Double_t angle)
Rotate about Z axis of the master frame with angle expressed in degrees.
constexpr Double_t E()
Base of natural log: .
Definition: TMath.h:97
TGeoIdentity * gGeoIdentity
Definition: TGeoMatrix.cxx:220
#define h(i)
Definition: RSha256.hxx:106
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:640
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:562
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
Conversion from radian to degree: .
Definition: TMath.h:74
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:459
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:636
Double_t ASin(Double_t)
Definition: TMath.h:660
Bool_t IsTranslation() const
Definition: TGeoMatrix.h:67
#define c(i)
Definition: RSha256.hxx:101
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:690
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
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:364