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