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