Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
TGeoMatrix.cxx
Go to the documentation of this file.
1// @(#)root/geom:$Id$
2// Author: Andrei Gheata 25/10/01
3
4/*************************************************************************
5 * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. *
6 * All rights reserved. *
7 * *
8 * For the licensing terms see $ROOTSYS/LICENSE. *
9 * For the list of contributors see $ROOTSYS/README/CREDITS. *
10 *************************************************************************/
11
12/** \class TGeoMatrix
13\ingroup Geometry_classes
14
15Geometrical transformation package.
16
17 All geometrical transformations handled by the modeller are provided as a
18built-in package. This was designed to minimize memory requirements and
19optimize performance of point/vector master-to-local and local-to-master
20computation. We need to have in mind that a transformation in TGeo has 2
21major use-cases. The first one is for defining the placement of a volume
22with respect to its container reference frame. This frame will be called
23'master' and the frame of the positioned volume - 'local'. If T is a
24transformation used for positioning volume daughters, then:
25
26~~~ {.cpp}
27 MASTER = T * LOCAL
28~~~
29
30 Therefore a local-to-master conversion will be performed by using T, while
31a master-to-local by using its inverse. The second use case is the computation
32of the global transformation of a given object in the geometry. Since the
33geometry is built as 'volumes-inside-volumes', this global transformation
34represent the pile-up of all local transformations in the corresponding
35branch. The conversion from the global reference frame and the given object
36is also called master-to-local, but it is handled by the manager class.
37 A general homogenous transformation is defined as a 4x4 matrix embedding
38a rotation, a translation and a scale. The advantage of this description
39is that each basic transformation can be represented as a homogenous matrix,
40composition being performed as simple matrix multiplication.
41
42 Rotation: Inverse rotation:
43
44~~~ {.cpp}
45 r11 r12 r13 0 r11 r21 r31 0
46 r21 r22 r23 0 r12 r22 r32 0
47 r31 r32 r33 0 r13 r23 r33 0
48 0 0 0 1 0 0 0 1
49~~~
50
51 Translation: Inverse translation:
52
53~~~ {.cpp}
54 1 0 0 tx 1 0 0 -tx
55 0 1 0 ty 0 1 0 -ty
56 0 0 1 tz 0 0 1 -tz
57 0 0 0 1 0 0 0 1
58~~~
59
60 Scale: Inverse scale:
61
62~~~ {.cpp}
63 sx 0 0 0 1/sx 0 0 0
64 0 sy 0 0 0 1/sy 0 0
65 0 0 sz 0 0 0 1/sz 0
66 0 0 0 1 0 0 0 1
67~~~
68
69 where:
70 - `rij` are the 3x3 rotation matrix components,
71 - `tx`, `ty`, `tz` are the translation components
72 - `sx`, `sy`, `sz` are arbitrary scale constants on each axis,
73
74 The disadvantage in using this approach is that computation for 4x4 matrices
75is expensive. Even combining two translation would become a multiplication
76of their corresponding matrices, which is quite an undesired effect. On the
77other hand, it is not a good idea to store a translation as a block of 16
78numbers. We have therefore chosen to implement each basic transformation type
79as a class deriving from the same basic abstract class and handling its specific
80data and point/vector transformation algorithms.
81
82\image html geom_transf.jpg
83
84### The base class TGeoMatrix defines abstract metods for:
85
86#### translation, rotation and scale getters. Every derived class stores only
87 its specific data, e.g. a translation stores an array of 3 doubles and a
88 rotation an array of 9. However, asking which is the rotation array of a
89 TGeoTranslation through the base TGeoMatrix interface is a legal operation.
90 The answer in this case is a pointer to a global constant array representing
91 an identity rotation.
92
93~~~ {.cpp}
94 Double_t *TGeoMatrix::GetTranslation()
95 Double_t *TGeoMatrix::GetRotation()
96 Double_t *TGeoMatrix::GetScale()
97~~~
98
99#### MasterToLocal() and LocalToMaster() point and vector transformations :
100
101~~~ {.cpp}
102 void TGeoMatrix::MasterToLocal(const Double_t *master, Double_t *local)
103 void TGeoMatrix::LocalToMaster(const Double_t *local, Double_t *master)
104 void TGeoMatrix::MasterToLocalVect(const Double_t *master, Double_t *local)
105 void TGeoMatrix::LocalToMasterVect(const Double_t *local, Double_t *master)
106~~~
107
108 These allow correct conversion also for reflections.
109
110#### Transformation type getters :
111
112~~~ {.cpp}
113 Bool_t TGeoMatrix::IsIdentity()
114 Bool_t TGeoMatrix::IsTranslation()
115 Bool_t TGeoMatrix::IsRotation()
116 Bool_t TGeoMatrix::IsScale()
117 Bool_t TGeoMatrix::IsCombi() (translation + rotation)
118 Bool_t TGeoMatrix::IsGeneral() (translation + rotation + scale)
119~~~
120
121 Combinations of basic transformations are represented by specific classes
122deriving from TGeoMatrix. In order to define a matrix as a combination of several
123others, a special class TGeoHMatrix is provided. Here is an example of matrix
124creation :
125
126### Matrix creation example:
127
128~~~ {.cpp}
129 root[0] TGeoRotation r1,r2;
130 r1.SetAngles(90,0,30); // rotation defined by Euler angles
131 r2.SetAngles(90,90,90,180,0,0); // rotation defined by GEANT3 angles
132 TGeoTranslation t1(-10,10,0);
133 TGeoTranslation t2(10,-10,5);
134 TGeoCombiTrans c1(t1,r1);
135 TGeoCombiTrans c2(t2,r2);
136 TGeoHMatrix h = c1 * c2; // composition is done via TGeoHMatrix class
137 root[7] TGeoHMatrix *ph = new TGeoHMatrix(hm); // this is the one we want to
138 // use for positioning a volume
139 root[8] ph->Print();
140 ...
141 pVolume->AddNode(pVolDaughter,id,ph) // now ph is owned by the manager
142~~~
143
144### Rule for matrix creation:
145 Unless explicitly used for positioning nodes (TGeoVolume::AddNode()) all
146matrices deletion have to be managed by users. Matrices passed to geometry
147have to be created by using new() operator and their deletion is done by
148TGeoManager class.
149
150### Available geometrical transformations
151
152#### TGeoTranslation
153Represent a (dx,dy,dz) translation. Data members:
154 Double_t fTranslation[3]. Translations can be added/subtracted.
155
156~~~ {.cpp}
157 TGeoTranslation t1;
158 t1->SetTranslation(-5,10,4);
159 TGeoTranslation *t2 = new TGeoTranslation(4,3,10);
160 t2->Subtract(&t1);
161~~~
162
163#### Rotations
164 Represent a pure rotation. Data members: Double_t fRotationMatrix[3*3].
165 Rotations can be defined either by Euler angles, either, by GEANT3 angles :
166
167~~~ {.cpp}
168 TGeoRotation *r1 = new TGeoRotation();
169 r1->SetAngles(phi, theta, psi); // all angles in degrees
170~~~
171
172 This represent the composition of : first a rotation about Z axis with
173 angle phi, then a rotation with theta about the rotated X axis, and
174 finally a rotation with psi about the new Z axis.
175
176~~~ {.cpp}
177 r1->SetAngles(th1,phi1, th2,phi2, th3,phi3)
178~~~
179
180 This is a rotation defined in GEANT3 style. Theta and phi are the spherical
181 angles of each axis of the rotated coordinate system with respect to the
182 initial one. This construction allows definition of malformed rotations,
183 e.g. not orthogonal. A check is performed and an error message is issued
184 in this case.
185
186 Specific utilities : determinant, inverse.
187
188#### Scale transformations
189 Represent a scale shrinking/enlargement. Data
190 members :Double_t fScale[3]. Not fully implemented yet.
191
192#### Combined transformations
193Represent a rotation followed by a translation.
194Data members: Double_t fTranslation[3], TGeoRotation *fRotation.
195
196~~~ {.cpp}
197 TGeoRotation *rot = new TGeoRotation("rot",10,20,30);
198 TGeoTranslation trans;
199 ...
200 TGeoCombiTrans *c1 = new TGeoCombiTrans(trans, rot);
201 TGeoCombiTrans *c2 = new TGeoCombiTrans("somename",10,20,30,rot)
202~~~
203
204
205#### TGeoGenTrans
206Combined transformations including a scale. Not implemented.
207
208#### TGeoIdentity
209A generic singleton matrix representing a identity transformation
210 NOTE: identified by the global variable gGeoIdentity.
211*/
212
213#include <iostream>
214#include "TObjArray.h"
215
216#include "TGeoManager.h"
217#include "TGeoMatrix.h"
218#include "TMath.h"
219
221const Int_t kN3 = 3 * sizeof(Double_t);
222const Int_t kN9 = 9 * sizeof(Double_t);
223
224// statics and globals
225
226
227////////////////////////////////////////////////////////////////////////////////
228/// dummy constructor
229
234
235////////////////////////////////////////////////////////////////////////////////
236/// copy constructor
237
242
243////////////////////////////////////////////////////////////////////////////////
244/// Constructor
245
247
248////////////////////////////////////////////////////////////////////////////////
249/// Destructor
250
252{
253 if (IsRegistered() && gGeoManager) {
254 if (!gGeoManager->IsCleaning()) {
256 Warning("dtor", "Registered matrix %s was removed", GetName());
257 }
258 }
259}
260
261////////////////////////////////////////////////////////////////////////////////
262/// Returns true if no rotation or the rotation is about Z axis
263
265{
266 if (IsIdentity())
267 return kTRUE;
268 const Double_t *rot = GetRotationMatrix();
269 if (TMath::Abs(rot[6]) > 1E-9)
270 return kFALSE;
271 if (TMath::Abs(rot[7]) > 1E-9)
272 return kFALSE;
273 if ((1. - TMath::Abs(rot[8])) > 1E-9)
274 return kFALSE;
275 return kTRUE;
276}
277
278////////////////////////////////////////////////////////////////////////////////
279/// Get total size in bytes of this
280
282{
283 Int_t count = 4 + 28 + strlen(GetName()) + strlen(GetTitle()); // fId + TNamed
284 if (IsTranslation())
285 count += 12;
286 if (IsScale())
287 count += 12;
288 if (IsCombi() || IsGeneral())
289 count += 4 + 36;
290 return count;
291}
292
293////////////////////////////////////////////////////////////////////////////////
294/// Provide a pointer name containing uid.
295
296const char *TGeoMatrix::GetPointerName() const
297{
298 static TString name;
299 name.Form("pMatrix%d", GetUniqueID());
300 return name.Data();
301}
302
303////////////////////////////////////////////////////////////////////////////////
304/// The homogenous matrix associated with the transformation is used for
305/// piling up's and visualization. A homogenous matrix is a 4*4 array
306/// containing the translation, the rotation and the scale components
307/// ~~~ {.cpp}
308/// | R00*sx R01 R02 dx |
309/// | R10 R11*sy R12 dy |
310/// | R20 R21 R22*sz dz |
311/// | 0 0 0 1 |
312/// ~~~
313/// where Rij is the rotation matrix, (sx, sy, sz) is the scale
314/// transformation and (dx, dy, dz) is the translation.
315
317{
319 const Double_t *mat = GetRotationMatrix();
320 for (Int_t i = 0; i < 3; i++) {
322 mat += 3;
323 hmatrix += 3;
324 *hmatrix = 0.0;
325 hmatrix++;
326 }
328 hmatrix = hmat;
329 if (IsScale()) {
330 for (Int_t i = 0; i < 3; i++) {
331 *hmatrix *= GetScale()[i];
332 hmatrix += 5;
333 }
334 }
335 hmatrix[15] = 1.;
336}
337
338////////////////////////////////////////////////////////////////////////////////
339/// convert a point by multiplying its column vector (x, y, z, 1) to matrix inverse
340
342{
343 if (IsIdentity()) {
345 return;
346 }
347 Int_t i;
348 const Double_t *tr = GetTranslation();
349 if (!IsRotation()) {
350 for (i = 0; i < 3; i++)
351 master[i] = tr[i] + local[i];
352 return;
353 }
354 const Double_t *rot = GetRotationMatrix();
355 for (i = 0; i < 3; i++) {
356 master[i] = tr[i] + local[0] * rot[3 * i] + local[1] * rot[3 * i + 1] + local[2] * rot[3 * i + 2];
357 }
358}
359
360////////////////////////////////////////////////////////////////////////////////
361/// convert a vector by multiplying its column vector (x, y, z, 1) to matrix inverse
362
364{
365 if (!IsRotation()) {
367 return;
368 }
369 const Double_t *rot = GetRotationMatrix();
370 for (Int_t i = 0; i < 3; i++) {
371 master[i] = local[0] * rot[3 * i] + local[1] * rot[3 * i + 1] + local[2] * rot[3 * i + 2];
372 }
373}
374
375////////////////////////////////////////////////////////////////////////////////
376/// convert a point by multiplying its column vector (x, y, z, 1) to matrix inverse
377
379{
380 if (IsIdentity()) {
382 return;
383 }
384 Int_t i;
385 const Double_t *tr = GetTranslation();
386 Double_t bombtr[3] = {0., 0., 0.};
388 if (!IsRotation()) {
389 for (i = 0; i < 3; i++)
390 master[i] = bombtr[i] + local[i];
391 return;
392 }
393 const Double_t *rot = GetRotationMatrix();
394 for (i = 0; i < 3; i++) {
395 master[i] = bombtr[i] + local[0] * rot[3 * i] + local[1] * rot[3 * i + 1] + local[2] * rot[3 * i + 2];
396 }
397}
398
399////////////////////////////////////////////////////////////////////////////////
400/// convert a point by multiplying its column vector (x, y, z, 1) to matrix
401
403{
404 if (IsIdentity()) {
406 return;
407 }
408 const Double_t *tr = GetTranslation();
409 Double_t mt0 = master[0] - tr[0];
410 Double_t mt1 = master[1] - tr[1];
411 Double_t mt2 = master[2] - tr[2];
412 if (!IsRotation()) {
413 local[0] = mt0;
414 local[1] = mt1;
415 local[2] = mt2;
416 return;
417 }
418 const Double_t *rot = GetRotationMatrix();
419 local[0] = mt0 * rot[0] + mt1 * rot[3] + mt2 * rot[6];
420 local[1] = mt0 * rot[1] + mt1 * rot[4] + mt2 * rot[7];
421 local[2] = mt0 * rot[2] + mt1 * rot[5] + mt2 * rot[8];
422}
423
424////////////////////////////////////////////////////////////////////////////////
425/// convert a point by multiplying its column vector (x, y, z, 1) to matrix
426
428{
429 if (!IsRotation()) {
431 return;
432 }
433 const Double_t *rot = GetRotationMatrix();
434 for (Int_t i = 0; i < 3; i++) {
435 local[i] = master[0] * rot[i] + master[1] * rot[i + 3] + master[2] * rot[i + 6];
436 }
437}
438
439////////////////////////////////////////////////////////////////////////////////
440/// convert a point by multiplying its column vector (x, y, z, 1) to matrix
441
443{
444 if (IsIdentity()) {
446 return;
447 }
448 const Double_t *tr = GetTranslation();
449 Double_t bombtr[3] = {0., 0., 0.};
450 Int_t i;
452 if (!IsRotation()) {
453 for (i = 0; i < 3; i++)
454 local[i] = master[i] - bombtr[i];
455 return;
456 }
457 const Double_t *rot = GetRotationMatrix();
458 for (i = 0; i < 3; i++) {
459 local[i] =
460 (master[0] - bombtr[0]) * rot[i] + (master[1] - bombtr[1]) * rot[i + 3] + (master[2] - bombtr[2]) * rot[i + 6];
461 }
462}
463
464////////////////////////////////////////////////////////////////////////////////
465/// Normalize a vector.
466
468{
469 Double_t normfactor = vect[0] * vect[0] + vect[1] * vect[1] + vect[2] * vect[2];
470 if (normfactor <= 1E-10)
471 return;
473 vect[0] *= normfactor;
474 vect[1] *= normfactor;
475 vect[2] *= normfactor;
476}
477
478////////////////////////////////////////////////////////////////////////////////
479/// print the matrix in 4x4 format
480
482{
483 const Double_t *rot = GetRotationMatrix();
484 const Double_t *tr = GetTranslation();
485 printf("matrix %s - tr=%d rot=%d refl=%d scl=%d shr=%d reg=%d own=%d\n", GetName(), (Int_t)IsTranslation(),
487 (Int_t)IsOwned());
488 printf("%10.6f%12.6f%12.6f Tx = %10.6f\n", rot[0], rot[1], rot[2], tr[0]);
489 printf("%10.6f%12.6f%12.6f Ty = %10.6f\n", rot[3], rot[4], rot[5], tr[1]);
490 printf("%10.6f%12.6f%12.6f Tz = %10.6f\n", rot[6], rot[7], rot[8], tr[2]);
491 if (IsScale()) {
492 const Double_t *scl = GetScale();
493 printf("Sx=%10.6fSy=%12.6fSz=%12.6f\n", scl[0], scl[1], scl[2]);
494 }
495}
496
497////////////////////////////////////////////////////////////////////////////////
498/// Multiply by a reflection respect to YZ.
499
501
502////////////////////////////////////////////////////////////////////////////////
503/// Multiply by a reflection respect to ZX.
504
506
507////////////////////////////////////////////////////////////////////////////////
508/// Multiply by a reflection respect to XY.
509
511
512////////////////////////////////////////////////////////////////////////////////
513/// Register the matrix in the current manager, which will become the owner.
514
516{
517 if (!gGeoManager) {
518 Warning("RegisterYourself", "cannot register without geometry");
519 return;
520 }
521 if (!IsRegistered()) {
524 }
525}
526
527////////////////////////////////////////////////////////////////////////////////
528/// If no name was supplied in the ctor, the type of transformation is checked.
529/// A letter will be prepended to the name :
530/// - t - translation
531/// - r - rotation
532/// - s - scale
533/// - c - combi (translation + rotation)
534/// - g - general (tr+rot+scale)
535/// The index of the transformation in gGeoManager list of transformations will
536/// be appended.
537
539{
540 if (!gGeoManager)
541 return;
542 if (strlen(GetName()))
543 return;
544 char type = 'n';
545 if (IsTranslation())
546 type = 't';
547 if (IsRotation())
548 type = 'r';
549 if (IsScale())
550 type = 's';
551 if (IsCombi())
552 type = 'c';
553 if (IsGeneral())
554 type = 'g';
556 Int_t index = 0;
557 if (matrices)
558 index = matrices->GetEntriesFast() - 1;
560 SetName(name);
561}
562
563/** \class TGeoTranslation
564\ingroup Geometry_classes
565
566Class describing translations. A translation is
567basically an array of 3 doubles matching the positions 12, 13
568and 14 in the homogenous matrix description.
569*/
570
571
572////////////////////////////////////////////////////////////////////////////////
573/// Default constructor
574
576{
577 for (Int_t i = 0; i < 3; i++)
578 fTranslation[i] = 0;
579}
580
581////////////////////////////////////////////////////////////////////////////////
582/// Copy ctor.
583
588
589////////////////////////////////////////////////////////////////////////////////
590/// Ctor. based on a general matrix
591
598
599////////////////////////////////////////////////////////////////////////////////
600/// Default constructor defining the translation
601
608
609////////////////////////////////////////////////////////////////////////////////
610/// Default constructor defining the translation
611
618
619////////////////////////////////////////////////////////////////////////////////
620/// Assignment from a general matrix
621
634
635////////////////////////////////////////////////////////////////////////////////
636/// Translation composition
637
639{
640 const Double_t *tr = right.GetTranslation();
641 fTranslation[0] += tr[0];
642 fTranslation[1] += tr[1];
643 fTranslation[2] += tr[2];
644 if (!IsTranslation())
646 return *this;
647}
648
650{
651 TGeoTranslation t = *this;
652 t *= right;
653 return t;
654}
655
657{
658 TGeoHMatrix t = *this;
659 t *= right;
660 return t;
661}
662
663////////////////////////////////////////////////////////////////////////////////
664/// Is-equal operator
665
667{
668 if (&other == this)
669 return kTRUE;
670 const Double_t *tr = GetTranslation();
671 const Double_t *otr = other.GetTranslation();
672 for (auto i = 0; i < 3; i++)
673 if (TMath::Abs(tr[i] - otr[i]) > 1.E-10)
674 return kFALSE;
675 return kTRUE;
676}
677
678////////////////////////////////////////////////////////////////////////////////
679/// Return a temporary inverse of this.
680
682{
684 h = *this;
686 Double_t tr[3];
687 tr[0] = -fTranslation[0];
688 tr[1] = -fTranslation[1];
689 tr[2] = -fTranslation[2];
690 h.SetTranslation(tr);
691 return h;
692}
693
694////////////////////////////////////////////////////////////////////////////////
695/// Adding a translation to this one
696
698{
699 const Double_t *trans = other->GetTranslation();
700 for (Int_t i = 0; i < 3; i++)
701 fTranslation[i] += trans[i];
702}
703
704////////////////////////////////////////////////////////////////////////////////
705/// Make a clone of this matrix.
706
708{
709 TGeoMatrix *matrix = new TGeoTranslation(*this);
710 return matrix;
711}
712
713////////////////////////////////////////////////////////////////////////////////
714/// Rotate about X axis of the master frame with angle expressed in degrees.
715
717{
718 Warning("RotateX", "Not implemented. Use TGeoCombiTrans instead");
719}
720
721////////////////////////////////////////////////////////////////////////////////
722/// Rotate about Y axis of the master frame with angle expressed in degrees.
723
725{
726 Warning("RotateY", "Not implemented. Use TGeoCombiTrans instead");
727}
728
729////////////////////////////////////////////////////////////////////////////////
730/// Rotate about Z axis of the master frame with angle expressed in degrees.
731
733{
734 Warning("RotateZ", "Not implemented. Use TGeoCombiTrans instead");
735}
736
737////////////////////////////////////////////////////////////////////////////////
738/// Subtracting a translation from this one
739
741{
742 const Double_t *trans = other->GetTranslation();
743 for (Int_t i = 0; i < 3; i++)
744 fTranslation[i] -= trans[i];
745}
746
747////////////////////////////////////////////////////////////////////////////////
748/// Set translation components
749
760
761////////////////////////////////////////////////////////////////////////////////
762/// Set translation components
763
765{
766 SetBit(kGeoTranslation, other.IsTranslation());
767 const Double_t *transl = other.GetTranslation();
769}
770
771////////////////////////////////////////////////////////////////////////////////
772/// convert a point by multiplying its column vector (x, y, z, 1) to matrix inverse
773
775{
776 const Double_t *tr = GetTranslation();
777 for (Int_t i = 0; i < 3; i++)
778 master[i] = tr[i] + local[i];
779}
780
781////////////////////////////////////////////////////////////////////////////////
782/// convert a vector to MARS
783
788
789////////////////////////////////////////////////////////////////////////////////
790/// convert a point by multiplying its column vector (x, y, z, 1) to matrix inverse
791
793{
794 const Double_t *tr = GetTranslation();
795 Double_t bombtr[3] = {0., 0., 0.};
797 for (Int_t i = 0; i < 3; i++)
798 master[i] = bombtr[i] + local[i];
799}
800
801////////////////////////////////////////////////////////////////////////////////
802/// convert a point by multiplying its column vector (x, y, z, 1) to matrix
803
805{
806 const Double_t *tr = GetTranslation();
807 for (Int_t i = 0; i < 3; i++)
808 local[i] = master[i] - tr[i];
809}
810
811////////////////////////////////////////////////////////////////////////////////
812/// convert a vector from MARS to local
813
818
819////////////////////////////////////////////////////////////////////////////////
820/// convert a point by multiplying its column vector (x, y, z, 1) to matrix
821
823{
824 const Double_t *tr = GetTranslation();
825 Double_t bombtr[3] = {0., 0., 0.};
827 for (Int_t i = 0; i < 3; i++)
828 local[i] = master[i] - bombtr[i];
829}
830
831////////////////////////////////////////////////////////////////////////////////
832/// Save a primitive as a C++ statement(s) on output stream "out".
833
834void TGeoTranslation::SavePrimitive(std::ostream &out, Option_t * /*option*/ /*= ""*/)
835{
837 return;
838 out << " // Translation: " << GetName() << std::endl;
839 out << " dx = " << fTranslation[0] << ";" << std::endl;
840 out << " dy = " << fTranslation[1] << ";" << std::endl;
841 out << " dz = " << fTranslation[2] << ";" << std::endl;
842 out << " TGeoTranslation *" << GetPointerName() << " = new TGeoTranslation(\"" << GetName() << "\",dx,dy,dz);"
843 << std::endl;
845}
846
847/** \class TGeoRotation
848\ingroup Geometry_classes
849Class describing rotations. A rotation is a 3*3 array
850Column vectors has to be orthogonal unit vectors.
851*/
852
853
854////////////////////////////////////////////////////////////////////////////////
855/// Default constructor.
856
858{
859 for (Int_t i = 0; i < 9; i++) {
860 if (i % 4)
861 fRotationMatrix[i] = 0;
862 else
863 fRotationMatrix[i] = 1.0;
864 }
865}
866
867////////////////////////////////////////////////////////////////////////////////
868/// Copy ctor.
869
874
875////////////////////////////////////////////////////////////////////////////////
876/// Copy ctor.
877
884
885////////////////////////////////////////////////////////////////////////////////
886/// Named rotation constructor
887
889{
890 for (Int_t i = 0; i < 9; i++) {
891 if (i % 4)
892 fRotationMatrix[i] = 0;
893 else
894 fRotationMatrix[i] = 1.0;
895 }
896}
897
898////////////////////////////////////////////////////////////////////////////////
899/// Default rotation constructor with Euler angles. Phi is the rotation angle about
900/// Z axis and is done first, theta is the rotation about new X and is done
901/// second, psi is the rotation angle about new Z and is done third. All angles are in
902/// degrees.
903
905{
906 SetAngles(phi, theta, psi);
907}
908
909////////////////////////////////////////////////////////////////////////////////
910/// Rotation constructor a la GEANT3. Angles theta(i), phi(i) are the polar and azimuthal
911/// angles of the (i) axis of the rotated system with respect to the initial non-rotated
912/// system.
913/// Example : the identity matrix (no rotation) is composed by
914/// theta1=90, phi1=0, theta2=90, phi2=90, theta3=0, phi3=0
915/// SetBit(kGeoRotation);
916
923
924////////////////////////////////////////////////////////////////////////////////
925/// Assignment from a general matrix
926
939
940////////////////////////////////////////////////////////////////////////////////
941/// Composition
942
944{
945 if (!right.IsRotation())
946 return *this;
947 MultiplyBy(&right, true);
948 return *this;
949}
950
952{
953 TGeoRotation r = *this;
954 r *= right;
955 return r;
956}
957
959{
960 TGeoHMatrix t = *this;
961 t *= right;
962 return t;
963}
964
965////////////////////////////////////////////////////////////////////////////////
966/// Is-equal operator
967
969{
970 if (&other == this)
971 return kTRUE;
972 const Double_t *rot = GetRotationMatrix();
973 const Double_t *orot = other.GetRotationMatrix();
974 for (auto i = 0; i < 9; i++)
975 if (TMath::Abs(rot[i] - orot[i]) > 1.E-10)
976 return kFALSE;
977 return kTRUE;
978}
979
980////////////////////////////////////////////////////////////////////////////////
981/// Return a temporary inverse of this.
982
984{
986 h = *this;
988 Double_t newrot[9];
989 newrot[0] = fRotationMatrix[0];
990 newrot[1] = fRotationMatrix[3];
991 newrot[2] = fRotationMatrix[6];
992 newrot[3] = fRotationMatrix[1];
993 newrot[4] = fRotationMatrix[4];
994 newrot[5] = fRotationMatrix[7];
995 newrot[6] = fRotationMatrix[2];
996 newrot[7] = fRotationMatrix[5];
997 newrot[8] = fRotationMatrix[8];
998 h.SetRotation(newrot);
999 return h;
1000}
1001
1002////////////////////////////////////////////////////////////////////////////////
1003/// Perform orthogonality test for rotation.
1004
1006{
1007 const Double_t *r = fRotationMatrix;
1008 Double_t cij;
1009 for (Int_t i = 0; i < 2; i++) {
1010 for (Int_t j = i + 1; j < 3; j++) {
1011 // check columns
1012 cij = TMath::Abs(r[i] * r[j] + r[i + 3] * r[j + 3] + r[i + 6] * r[j + 6]);
1013 if (cij > 1E-4)
1014 return kFALSE;
1015 // check rows
1016 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]);
1017 if (cij > 1E-4)
1018 return kFALSE;
1019 }
1020 }
1021 return kTRUE;
1022}
1023
1024////////////////////////////////////////////////////////////////////////////////
1025/// reset data members
1026
1032
1033////////////////////////////////////////////////////////////////////////////////
1034/// Perform a rotation about Z having the sine/cosine of the rotation angle.
1035
1037{
1038 fRotationMatrix[0] = sincos[1];
1039 fRotationMatrix[1] = -sincos[0];
1040 fRotationMatrix[3] = sincos[0];
1041 fRotationMatrix[4] = sincos[1];
1043}
1044
1045////////////////////////////////////////////////////////////////////////////////
1046/// Returns rotation angle about Z axis in degrees. If the rotation is a pure
1047/// rotation about Z, fixX parameter does not matter, otherwise its meaning is:
1048/// - fixX = true : result is the phi angle of the projection of the rotated X axis in the un-rotated XY
1049/// - fixX = false : result is the phi angle of the projection of the rotated Y axis - 90 degrees
1050
1052{
1053 Double_t phi;
1054 if (fixX)
1055 phi = 180. * TMath::ATan2(-fRotationMatrix[1], fRotationMatrix[4]) / TMath::Pi();
1056 else
1057 phi = 180. * TMath::ATan2(fRotationMatrix[3], fRotationMatrix[0]) / TMath::Pi();
1058 return phi;
1059}
1060
1061////////////////////////////////////////////////////////////////////////////////
1062/// convert a point by multiplying its column vector (x, y, z, 1) to matrix inverse
1063
1065{
1066 const Double_t *rot = GetRotationMatrix();
1067 for (Int_t i = 0; i < 3; i++) {
1068 master[i] = local[0] * rot[3 * i] + local[1] * rot[3 * i + 1] + local[2] * rot[3 * i + 2];
1069 }
1070}
1071
1072////////////////////////////////////////////////////////////////////////////////
1073/// convert a point by multiplying its column vector (x, y, z, 1) to matrix
1074
1076{
1077 const Double_t *rot = GetRotationMatrix();
1078 for (Int_t i = 0; i < 3; i++) {
1079 local[i] = master[0] * rot[i] + master[1] * rot[i + 3] + master[2] * rot[i + 6];
1080 }
1081}
1082
1083////////////////////////////////////////////////////////////////////////////////
1084/// Make a clone of this matrix.
1085
1087{
1088 TGeoMatrix *matrix = new TGeoRotation(*this);
1089 return matrix;
1090}
1091
1092////////////////////////////////////////////////////////////////////////////////
1093/// Rotate about X axis of the master frame with angle expressed in degrees.
1094
1096{
1098 Double_t phi = angle * TMath::DegToRad();
1099 Double_t c = TMath::Cos(phi);
1100 Double_t s = TMath::Sin(phi);
1101 Double_t v[9];
1102 v[0] = fRotationMatrix[0];
1103 v[1] = fRotationMatrix[1];
1104 v[2] = fRotationMatrix[2];
1105 v[3] = c * fRotationMatrix[3] - s * fRotationMatrix[6];
1106 v[4] = c * fRotationMatrix[4] - s * fRotationMatrix[7];
1107 v[5] = c * fRotationMatrix[5] - s * fRotationMatrix[8];
1108 v[6] = s * fRotationMatrix[3] + c * fRotationMatrix[6];
1109 v[7] = s * fRotationMatrix[4] + c * fRotationMatrix[7];
1110 v[8] = s * fRotationMatrix[5] + c * fRotationMatrix[8];
1111
1113}
1114
1115////////////////////////////////////////////////////////////////////////////////
1116/// Rotate about Y axis of the master frame with angle expressed in degrees.
1117
1119{
1121 Double_t phi = angle * TMath::DegToRad();
1122 Double_t c = TMath::Cos(phi);
1123 Double_t s = TMath::Sin(phi);
1124 Double_t v[9];
1125 v[0] = c * fRotationMatrix[0] + s * fRotationMatrix[6];
1126 v[1] = c * fRotationMatrix[1] + s * fRotationMatrix[7];
1127 v[2] = c * fRotationMatrix[2] + s * fRotationMatrix[8];
1128 v[3] = fRotationMatrix[3];
1129 v[4] = fRotationMatrix[4];
1130 v[5] = fRotationMatrix[5];
1131 v[6] = -s * fRotationMatrix[0] + c * fRotationMatrix[6];
1132 v[7] = -s * fRotationMatrix[1] + c * fRotationMatrix[7];
1133 v[8] = -s * fRotationMatrix[2] + c * fRotationMatrix[8];
1134
1136}
1137
1138////////////////////////////////////////////////////////////////////////////////
1139/// Rotate about Z axis of the master frame with angle expressed in degrees.
1140
1142{
1144 Double_t phi = angle * TMath::DegToRad();
1145 Double_t c = TMath::Cos(phi);
1146 Double_t s = TMath::Sin(phi);
1147 Double_t v[9];
1148 v[0] = c * fRotationMatrix[0] - s * fRotationMatrix[3];
1149 v[1] = c * fRotationMatrix[1] - s * fRotationMatrix[4];
1150 v[2] = c * fRotationMatrix[2] - s * fRotationMatrix[5];
1151 v[3] = s * fRotationMatrix[0] + c * fRotationMatrix[3];
1152 v[4] = s * fRotationMatrix[1] + c * fRotationMatrix[4];
1153 v[5] = s * fRotationMatrix[2] + c * fRotationMatrix[5];
1154 v[6] = fRotationMatrix[6];
1155 v[7] = fRotationMatrix[7];
1156 v[8] = fRotationMatrix[8];
1157
1158 memcpy(&fRotationMatrix[0], v, kN9);
1159}
1160
1161////////////////////////////////////////////////////////////////////////////////
1162/// Multiply by a reflection respect to YZ.
1163
1178
1179////////////////////////////////////////////////////////////////////////////////
1180/// Multiply by a reflection respect to ZX.
1181
1196
1197////////////////////////////////////////////////////////////////////////////////
1198/// Multiply by a reflection respect to XY.
1199
1214
1215////////////////////////////////////////////////////////////////////////////////
1216/// Save a primitive as a C++ statement(s) on output stream "out".
1217
1218void TGeoRotation::SavePrimitive(std::ostream &out, Option_t * /*option*/ /*= ""*/)
1219{
1221 return;
1222 out << " // Rotation: " << GetName() << std::endl;
1223 Double_t th1, ph1, th2, ph2, th3, ph3;
1224 GetAngles(th1, ph1, th2, ph2, th3, ph3);
1225 out << " thx = " << th1 << "; phx = " << ph1 << ";" << std::endl;
1226 out << " thy = " << th2 << "; phy = " << ph2 << ";" << std::endl;
1227 out << " thz = " << th3 << "; phz = " << ph3 << ";" << std::endl;
1228 out << " TGeoRotation *" << GetPointerName() << " = new TGeoRotation(\"" << GetName()
1229 << "\",thx,phx,thy,phy,thz,phz);" << std::endl;
1231}
1232
1233////////////////////////////////////////////////////////////////////////////////
1234/// Copy rotation elements from other rotation matrix.
1235
1237{
1238 SetBit(kGeoRotation, other.IsRotation());
1239 SetMatrix(other.GetRotationMatrix());
1240}
1241
1242////////////////////////////////////////////////////////////////////////////////
1243/// Set matrix elements according to Euler angles. Phi is the rotation angle about
1244/// Z axis and is done first, theta is the rotation about new X and is done
1245/// second, psi is the rotation angle about new Z and is done third. All angles are in
1246/// degrees.
1247
1249{
1250 Double_t degrad = TMath::Pi() / 180.;
1253 Double_t sinthe = TMath::Sin(degrad * theta);
1254 Double_t costhe = TMath::Cos(degrad * theta);
1257
1267
1268 if (!IsValid())
1269 Error("SetAngles", "invalid rotation (Euler angles : phi=%f theta=%f psi=%f)", phi, theta, psi);
1270 CheckMatrix();
1271}
1272
1273////////////////////////////////////////////////////////////////////////////////
1274/// Set matrix elements in the GEANT3 way
1275
1277 Double_t phi3)
1278{
1279 Double_t degrad = TMath::Pi() / 180.;
1289 // do the trick to eliminate most of the floating point errors
1290 for (Int_t i = 0; i < 9; i++) {
1291 if (TMath::Abs(fRotationMatrix[i]) < 1E-15)
1292 fRotationMatrix[i] = 0;
1293 if (TMath::Abs(fRotationMatrix[i] - 1) < 1E-15)
1294 fRotationMatrix[i] = 1;
1295 if (TMath::Abs(fRotationMatrix[i] + 1) < 1E-15)
1296 fRotationMatrix[i] = -1;
1297 }
1298 if (!IsValid())
1299 Error("SetAngles", "invalid rotation (G3 angles, th1=%f phi1=%f, th2=%f ph2=%f, th3=%f phi3=%f)", theta1, phi1,
1300 theta2, phi2, theta3, phi3);
1301 CheckMatrix();
1302}
1303
1304////////////////////////////////////////////////////////////////////////////////
1305/// Retrieve rotation angles
1306
1308 Double_t &phi3) const
1309{
1310 Double_t raddeg = 180. / TMath::Pi();
1314 if (TMath::Abs(fRotationMatrix[0]) < 1E-6 && TMath::Abs(fRotationMatrix[3]) < 1E-6)
1315 phi1 = 0.;
1316 else
1318 if (phi1 < 0)
1319 phi1 += 360.;
1320 if (TMath::Abs(fRotationMatrix[1]) < 1E-6 && TMath::Abs(fRotationMatrix[4]) < 1E-6)
1321 phi2 = 0.;
1322 else
1324 if (phi2 < 0)
1325 phi2 += 360.;
1326 if (TMath::Abs(fRotationMatrix[2]) < 1E-6 && TMath::Abs(fRotationMatrix[5]) < 1E-6)
1327 phi3 = 0.;
1328 else
1330 if (phi3 < 0)
1331 phi3 += 360.;
1332}
1333
1334////////////////////////////////////////////////////////////////////////////////
1335/// Retrieve Euler angles.
1336
1338{
1339 const Double_t *m = fRotationMatrix;
1340 // Check if theta is 0 or 180.
1341 if (TMath::Abs(1. - TMath::Abs(m[8])) < 1.e-9) {
1342 theta = TMath::ACos(m[8]) * TMath::RadToDeg();
1343 phi = TMath::ATan2(-m[8] * m[1], m[0]) * TMath::RadToDeg();
1344 psi = 0.; // convention, phi+psi matters
1345 return;
1346 }
1347 // sin(theta) != 0
1348 phi = TMath::ATan2(m[2], -m[5]);
1349 Double_t sphi = TMath::Sin(phi);
1350 if (TMath::Abs(sphi) < 1.e-9)
1351 theta = -TMath::ASin(m[5] / TMath::Cos(phi)) * TMath::RadToDeg();
1352 else
1353 theta = TMath::ASin(m[2] / sphi) * TMath::RadToDeg();
1354 phi *= TMath::RadToDeg();
1355 psi = TMath::ATan2(m[6], m[7]) * TMath::RadToDeg();
1356}
1357
1358////////////////////////////////////////////////////////////////////////////////
1359/// computes determinant of the rotation matrix
1360
1371
1372////////////////////////////////////////////////////////////////////////////////
1373/// performes an orthogonality check and finds if the matrix is a reflection
1374/// Warning("CheckMatrix", "orthogonality check not performed yet");
1375
1377{
1378 if (Determinant() < 0)
1381 if (TMath::Abs(dd) < 1.E-12)
1383 else
1385}
1386
1387////////////////////////////////////////////////////////////////////////////////
1388/// Get the inverse rotation matrix (which is simply the transpose)
1389
1391{
1392 if (!invmat) {
1393 Error("GetInverse", "no place to store the inverse matrix");
1394 return;
1395 }
1396 for (Int_t i = 0; i < 3; i++) {
1397 for (Int_t j = 0; j < 3; j++) {
1398 invmat[3 * i + j] = fRotationMatrix[3 * j + i];
1399 }
1400 }
1401}
1402
1403////////////////////////////////////////////////////////////////////////////////
1404/// Multiply this rotation with the one specified by ROT.
1405/// - after=TRUE (default): THIS*ROT
1406/// - after=FALSE : ROT*THIS
1407
1409{
1410 const Double_t *matleft, *matright;
1412 Double_t newmat[9] = {0};
1413 if (after) {
1415 matright = rot->GetRotationMatrix();
1416 } else {
1417 matleft = rot->GetRotationMatrix();
1419 }
1420 for (Int_t i = 0; i < 3; i++) {
1421 for (Int_t j = 0; j < 3; j++) {
1422 for (Int_t k = 0; k < 3; k++) {
1423 newmat[3 * i + j] += matleft[3 * i + k] * matright[3 * k + j];
1424 }
1425 }
1426 }
1427 memcpy(&fRotationMatrix[0], &newmat[0], kN9);
1428}
1429
1430/** \class TGeoScale
1431\ingroup Geometry_classes
1432Class describing scale transformations. A scale is an
1433array of 3 doubles (sx, sy, sz) multiplying elements 0, 5 and 10
1434of the homogenous matrix. A scale is normalized : sx*sy*sz = 1
1435*/
1436
1437
1438////////////////////////////////////////////////////////////////////////////////
1439/// default constructor
1440
1442{
1444 for (Int_t i = 0; i < 3; i++)
1445 fScale[i] = 1.;
1446}
1447
1448////////////////////////////////////////////////////////////////////////////////
1449/// Copy constructor
1450
1455
1456////////////////////////////////////////////////////////////////////////////////
1457/// Ctor. based on a general matrix
1458
1465
1466////////////////////////////////////////////////////////////////////////////////
1467/// default constructor
1468
1474
1475////////////////////////////////////////////////////////////////////////////////
1476/// default constructor
1477
1483
1484////////////////////////////////////////////////////////////////////////////////
1485/// destructor
1486
1488
1489////////////////////////////////////////////////////////////////////////////////
1490/// Assignment from a general matrix
1491
1493{
1494 if (&matrix == this)
1495 return *this;
1502 return *this;
1503}
1504
1505////////////////////////////////////////////////////////////////////////////////
1506/// Scale composition
1507
1509{
1510 const Double_t *scl = right.GetScale();
1511 fScale[0] *= scl[0];
1512 fScale[1] *= scl[1];
1513 fScale[2] *= scl[2];
1514 SetBit(kGeoReflection, fScale[0] * fScale[1] * fScale[2] < 0);
1515 if (!IsScale())
1516 SetBit(kGeoScale, right.IsScale());
1517 return *this;
1518}
1519
1521{
1522 TGeoScale s = *this;
1523 s *= right;
1524 return s;
1525}
1526
1528{
1529 TGeoHMatrix t = *this;
1530 t *= right;
1531 return t;
1532}
1533
1534////////////////////////////////////////////////////////////////////////////////
1535/// Is-equal operator
1536
1538{
1539 if (&other == this)
1540 return kTRUE;
1541 const Double_t *scl = GetScale();
1542 const Double_t *oscl = other.GetScale();
1543 for (auto i = 0; i < 3; i++)
1544 if (TMath::Abs(scl[i] - oscl[i]) > 1.E-10)
1545 return kFALSE;
1546 return kTRUE;
1547}
1548
1549////////////////////////////////////////////////////////////////////////////////
1550/// Return a temporary inverse of this.
1551
1553{
1554 TGeoHMatrix h;
1555 h = *this;
1557 Double_t scale[3];
1558 scale[0] = 1. / fScale[0];
1559 scale[1] = 1. / fScale[1];
1560 scale[2] = 1. / fScale[2];
1561 h.SetScale(scale);
1562 return h;
1563}
1564
1565////////////////////////////////////////////////////////////////////////////////
1566/// scale setter
1567
1569{
1570 if (TMath::Abs(sx * sy * sz) < 1.E-10) {
1571 Error("SetScale", "Invalid scale %f, %f, %f for transformation %s", sx, sy, sx, GetName());
1572 return;
1573 }
1574 fScale[0] = sx;
1575 fScale[1] = sy;
1576 fScale[2] = sz;
1577 if (sx * sy * sz < 0)
1579 else
1581}
1582
1583////////////////////////////////////////////////////////////////////////////////
1584/// Set scale from other transformation
1585
1587{
1588 SetBit(kGeoScale, other.IsScale());
1589 SetBit(kGeoReflection, other.IsReflection());
1590 memcpy(fScale, other.GetScale(), kN3);
1591}
1592
1593////////////////////////////////////////////////////////////////////////////////
1594/// Convert a local point to the master frame.
1595
1597{
1598 master[0] = local[0] * fScale[0];
1599 master[1] = local[1] * fScale[1];
1600 master[2] = local[2] * fScale[2];
1601}
1602
1603////////////////////////////////////////////////////////////////////////////////
1604/// Convert the local distance along unit vector DIR to master frame. If DIR
1605/// is not specified perform a conversion such as the returned distance is the
1606/// the minimum for all possible directions.
1607
1609{
1611 if (!dir) {
1612 scale = TMath::Abs(fScale[0]);
1613 if (TMath::Abs(fScale[1]) < scale)
1614 scale = TMath::Abs(fScale[1]);
1615 if (TMath::Abs(fScale[2]) < scale)
1616 scale = TMath::Abs(fScale[2]);
1617 } else {
1618 scale = fScale[0] * fScale[0] * dir[0] * dir[0] + fScale[1] * fScale[1] * dir[1] * dir[1] +
1619 fScale[2] * fScale[2] * dir[2] * dir[2];
1621 }
1622 return scale * dist;
1623}
1624
1625////////////////////////////////////////////////////////////////////////////////
1626/// Make a clone of this matrix.
1627
1629{
1630 TGeoMatrix *matrix = new TGeoScale(*this);
1631 return matrix;
1632}
1633
1634////////////////////////////////////////////////////////////////////////////////
1635/// Convert a global point to local frame.
1636
1638{
1639 local[0] = master[0] / fScale[0];
1640 local[1] = master[1] / fScale[1];
1641 local[2] = master[2] / fScale[2];
1642}
1643
1644////////////////////////////////////////////////////////////////////////////////
1645/// Convert the distance along unit vector DIR to local frame. If DIR
1646/// is not specified perform a conversion such as the returned distance is the
1647/// the minimum for all possible directions.
1648
1650{
1652 if (!dir) {
1653 scale = TMath::Abs(fScale[0]);
1654 if (TMath::Abs(fScale[1]) > scale)
1655 scale = TMath::Abs(fScale[1]);
1656 if (TMath::Abs(fScale[2]) > scale)
1657 scale = TMath::Abs(fScale[2]);
1658 scale = 1. / scale;
1659 } else {
1660 scale = (dir[0] * dir[0]) / (fScale[0] * fScale[0]) + (dir[1] * dir[1]) / (fScale[1] * fScale[1]) +
1661 (dir[2] * dir[2]) / (fScale[2] * fScale[2]);
1663 }
1664 return scale * dist;
1665}
1666
1667/** \class TGeoCombiTrans
1668\ingroup Geometry_classes
1669Class describing rotation + translation. Most frequently used in the description
1670of TGeoNode 's
1671*/
1672
1673
1674////////////////////////////////////////////////////////////////////////////////
1675/// dummy ctor
1676
1678{
1679 for (Int_t i = 0; i < 3; i++)
1680 fTranslation[i] = 0.0;
1681 fRotation = nullptr;
1682}
1683
1684////////////////////////////////////////////////////////////////////////////////
1685/// Copy ctor from generic matrix.
1686
1688{
1690 if (other.IsTranslation()) {
1692 memcpy(fTranslation, other.GetTranslation(), kN3);
1693 } else {
1694 for (Int_t i = 0; i < 3; i++)
1695 fTranslation[i] = 0.0;
1696 }
1697 if (other.IsRotation()) {
1701 } else
1702 fRotation = nullptr;
1703}
1704
1705////////////////////////////////////////////////////////////////////////////////
1706/// Constructor from a translation and a rotation.
1707
1709{
1710 if (tr.IsTranslation()) {
1712 const Double_t *trans = tr.GetTranslation();
1713 memcpy(fTranslation, trans, kN3);
1714 } else {
1715 for (Int_t i = 0; i < 3; i++)
1716 fTranslation[i] = 0.0;
1717 }
1718 if (rot.IsRotation()) {
1721 fRotation = new TGeoRotation(rot);
1723 } else
1724 fRotation = nullptr;
1725}
1726
1727////////////////////////////////////////////////////////////////////////////////
1728/// Named ctor.
1729
1731{
1732 for (Int_t i = 0; i < 3; i++)
1733 fTranslation[i] = 0.0;
1734 fRotation = nullptr;
1735}
1736
1737////////////////////////////////////////////////////////////////////////////////
1738/// Constructor from a translation specified by X,Y,Z and a pointer to a rotation. The rotation will not be owned by
1739/// this.
1740
1747
1748////////////////////////////////////////////////////////////////////////////////
1749/// Named ctor
1750
1758
1759////////////////////////////////////////////////////////////////////////////////
1760/// Assignment operator with generic matrix.
1761
1763{
1764 if (&matrix == this)
1765 return *this;
1767 Clear();
1769
1770 if (matrix.IsTranslation()) {
1771 memcpy(fTranslation, matrix.GetTranslation(), kN3);
1772 }
1773 if (matrix.IsRotation()) {
1774 if (!fRotation) {
1775 fRotation = new TGeoRotation();
1777 } else {
1778 if (!TestBit(kGeoMatrixOwned)) {
1779 fRotation = new TGeoRotation();
1781 }
1782 }
1783 fRotation->SetMatrix(matrix.GetRotationMatrix());
1786 } else {
1788 delete fRotation;
1790 fRotation = nullptr;
1791 }
1794 return *this;
1795}
1796
1797////////////////////////////////////////////////////////////////////////////////
1798/// Is-equal operator
1799
1801{
1802 if (&other == this)
1803 return kTRUE;
1804 const Double_t *tr = GetTranslation();
1805 const Double_t *otr = other.GetTranslation();
1806 for (auto i = 0; i < 3; i++)
1807 if (TMath::Abs(tr[i] - otr[i]) > 1.E-10)
1808 return kFALSE;
1809 const Double_t *rot = GetRotationMatrix();
1810 const Double_t *orot = other.GetRotationMatrix();
1811 for (auto i = 0; i < 9; i++)
1812 if (TMath::Abs(rot[i] - orot[i]) > 1.E-10)
1813 return kFALSE;
1814 return kTRUE;
1815}
1816
1817////////////////////////////////////////////////////////////////////////////////
1818/// Composition
1819
1821{
1822 Multiply(&right);
1823 return *this;
1824}
1825
1827{
1828 TGeoHMatrix h = *this;
1829 h *= right;
1830 return h;
1831}
1832
1833////////////////////////////////////////////////////////////////////////////////
1834/// destructor
1835
1843
1844////////////////////////////////////////////////////////////////////////////////
1845/// Reset translation/rotation to identity
1846
1848{
1849 if (IsTranslation()) {
1851 memset(fTranslation, 0, kN3);
1852 }
1853 if (fRotation) {
1855 delete fRotation;
1856 fRotation = nullptr;
1857 }
1861}
1862
1863////////////////////////////////////////////////////////////////////////////////
1864/// Return a temporary inverse of this.
1865
1867{
1868 TGeoHMatrix h;
1869 h = *this;
1873 Double_t tr[3];
1874 Double_t newrot[9];
1875 const Double_t *rot = GetRotationMatrix();
1876 tr[0] = -fTranslation[0] * rot[0] - fTranslation[1] * rot[3] - fTranslation[2] * rot[6];
1877 tr[1] = -fTranslation[0] * rot[1] - fTranslation[1] * rot[4] - fTranslation[2] * rot[7];
1878 tr[2] = -fTranslation[0] * rot[2] - fTranslation[1] * rot[5] - fTranslation[2] * rot[8];
1879 h.SetTranslation(tr);
1880 newrot[0] = rot[0];
1881 newrot[1] = rot[3];
1882 newrot[2] = rot[6];
1883 newrot[3] = rot[1];
1884 newrot[4] = rot[4];
1885 newrot[5] = rot[7];
1886 newrot[6] = rot[2];
1887 newrot[7] = rot[5];
1888 newrot[8] = rot[8];
1889 h.SetRotation(newrot);
1890 h.SetBit(kGeoTranslation, is_tr);
1891 h.SetBit(kGeoRotation, is_rot);
1892 return h;
1893}
1894
1895////////////////////////////////////////////////////////////////////////////////
1896/// Make a clone of this matrix.
1897
1899{
1900 TGeoMatrix *matrix = new TGeoCombiTrans(*this);
1901 return matrix;
1902}
1903
1904////////////////////////////////////////////////////////////////////////////////
1905/// multiply to the right with an other transformation
1906/// if right is identity matrix, just return
1907
1909{
1910 if (right->IsIdentity())
1911 return;
1912 TGeoHMatrix h = *this;
1913 h.Multiply(right);
1914 operator=(h);
1915}
1916
1917////////////////////////////////////////////////////////////////////////////////
1918/// Register the matrix in the current manager, which will become the owner.
1919
1926
1927////////////////////////////////////////////////////////////////////////////////
1928/// Rotate about X axis with angle expressed in degrees.
1929
1931{
1932 if (!fRotation || !TestBit(kGeoMatrixOwned)) {
1933 if (fRotation)
1935 else
1936 fRotation = new TGeoRotation();
1938 }
1941 Double_t phi = angle * TMath::DegToRad();
1942 Double_t c = TMath::Cos(phi);
1943 Double_t s = TMath::Sin(phi);
1944 Double_t v[9];
1945 v[0] = rot[0];
1946 v[1] = rot[1];
1947 v[2] = rot[2];
1948 v[3] = c * rot[3] - s * rot[6];
1949 v[4] = c * rot[4] - s * rot[7];
1950 v[5] = c * rot[5] - s * rot[8];
1951 v[6] = s * rot[3] + c * rot[6];
1952 v[7] = s * rot[4] + c * rot[7];
1953 v[8] = s * rot[5] + c * rot[8];
1956 if (!IsTranslation())
1957 return;
1958 v[0] = fTranslation[0];
1959 v[1] = c * fTranslation[1] - s * fTranslation[2];
1960 v[2] = s * fTranslation[1] + c * fTranslation[2];
1962}
1963
1964////////////////////////////////////////////////////////////////////////////////
1965/// Rotate about Y axis with angle expressed in degrees.
1966
1968{
1969 if (!fRotation || !TestBit(kGeoMatrixOwned)) {
1970 if (fRotation)
1972 else
1973 fRotation = new TGeoRotation();
1975 }
1978 Double_t phi = angle * TMath::DegToRad();
1979 Double_t c = TMath::Cos(phi);
1980 Double_t s = TMath::Sin(phi);
1981 Double_t v[9];
1982 v[0] = c * rot[0] + s * rot[6];
1983 v[1] = c * rot[1] + s * rot[7];
1984 v[2] = c * rot[2] + s * rot[8];
1985 v[3] = rot[3];
1986 v[4] = rot[4];
1987 v[5] = rot[5];
1988 v[6] = -s * rot[0] + c * rot[6];
1989 v[7] = -s * rot[1] + c * rot[7];
1990 v[8] = -s * rot[2] + c * rot[8];
1993 if (!IsTranslation())
1994 return;
1995 v[0] = c * fTranslation[0] + s * fTranslation[2];
1996 v[1] = fTranslation[1];
1997 v[2] = -s * fTranslation[0] + c * fTranslation[2];
1999}
2000
2001////////////////////////////////////////////////////////////////////////////////
2002/// Rotate about Z axis with angle expressed in degrees.
2003
2005{
2006 if (!fRotation || !TestBit(kGeoMatrixOwned)) {
2007 if (fRotation)
2009 else
2010 fRotation = new TGeoRotation();
2012 }
2015 Double_t phi = angle * TMath::DegToRad();
2016 Double_t c = TMath::Cos(phi);
2017 Double_t s = TMath::Sin(phi);
2018 Double_t v[9];
2019 v[0] = c * rot[0] - s * rot[3];
2020 v[1] = c * rot[1] - s * rot[4];
2021 v[2] = c * rot[2] - s * rot[5];
2022 v[3] = s * rot[0] + c * rot[3];
2023 v[4] = s * rot[1] + c * rot[4];
2024 v[5] = s * rot[2] + c * rot[5];
2025 v[6] = rot[6];
2026 v[7] = rot[7];
2027 v[8] = rot[8];
2030 if (!IsTranslation())
2031 return;
2032 v[0] = c * fTranslation[0] - s * fTranslation[1];
2033 v[1] = s * fTranslation[0] + c * fTranslation[1];
2034 v[2] = fTranslation[2];
2036}
2037
2038////////////////////////////////////////////////////////////////////////////////
2039/// Multiply by a reflection respect to YZ.
2040
2056
2057////////////////////////////////////////////////////////////////////////////////
2058/// Multiply by a reflection respect to ZX.
2059
2075
2076////////////////////////////////////////////////////////////////////////////////
2077/// Multiply by a reflection respect to XY.
2078
2094
2095////////////////////////////////////////////////////////////////////////////////
2096/// Save a primitive as a C++ statement(s) on output stream "out".
2097
2098void TGeoCombiTrans::SavePrimitive(std::ostream &out, Option_t *option /*= ""*/)
2099{
2101 return;
2102 out << " // Combi transformation: " << GetName() << std::endl;
2103 out << " dx = " << fTranslation[0] << ";" << std::endl;
2104 out << " dy = " << fTranslation[1] << ";" << std::endl;
2105 out << " dz = " << fTranslation[2] << ";" << std::endl;
2106 if (fRotation && fRotation->IsRotation()) {
2108 out << " auto " << GetPointerName() << " = new TGeoCombiTrans(\"" << GetName() << "\", dx, dy, dz, "
2109 << fRotation->GetPointerName() << ");" << std::endl;
2110 } else {
2111 out << " auto " << GetPointerName() << " = new TGeoCombiTrans(\"" << GetName() << "\");" << std::endl;
2112 out << " " << GetPointerName() << "->SetTranslation(dx, dy, dz);" << std::endl;
2113 }
2115}
2116
2117////////////////////////////////////////////////////////////////////////////////
2118/// Assign a foreign rotation to the combi. The rotation is NOT owned by this.
2119
2121{
2123 delete fRotation;
2124 fRotation = nullptr;
2128 if (!rot)
2129 return;
2130 if (!rot->IsRotation())
2131 return;
2132
2136 fRotation = rr;
2137}
2138
2139////////////////////////////////////////////////////////////////////////////////
2140/// Copy the rotation from another one.
2141
2143{
2145 delete fRotation;
2146 fRotation = nullptr;
2147 if (!rot.IsRotation()) {
2151 return;
2152 }
2153
2156 fRotation = new TGeoRotation(rot);
2158}
2159
2160////////////////////////////////////////////////////////////////////////////////
2161/// copy the translation component
2162
2164{
2165 if (tr.IsTranslation()) {
2167 const Double_t *trans = tr.GetTranslation();
2168 memcpy(fTranslation, trans, kN3);
2169 } else {
2170 if (!IsTranslation())
2171 return;
2172 memset(fTranslation, 0, kN3);
2174 }
2175}
2176
2177////////////////////////////////////////////////////////////////////////////////
2178/// set the translation component
2179
2190
2191////////////////////////////////////////////////////////////////////////////////
2192/// set the translation component
2193
2195{
2196 fTranslation[0] = vect[0];
2197 fTranslation[1] = vect[1];
2198 fTranslation[2] = vect[2];
2199 if (fTranslation[0] || fTranslation[1] || fTranslation[2])
2201 else
2203}
2204
2205////////////////////////////////////////////////////////////////////////////////
2206/// get the rotation array
2207
2209{
2210 if (!fRotation)
2211 return kIdentityMatrix;
2212 return fRotation->GetRotationMatrix();
2213}
2214
2215/** \class TGeoGenTrans
2216\ingroup Geometry_classes
2217Most general transformation, holding a translation, a rotation and a scale
2218*/
2219
2220
2221////////////////////////////////////////////////////////////////////////////////
2222/// dummy ctor
2223
2225{
2227 for (Int_t i = 0; i < 3; i++)
2228 fTranslation[i] = 0.0;
2229 for (Int_t j = 0; j < 3; j++)
2230 fScale[j] = 1.0;
2231 fRotation = nullptr;
2232}
2233
2234////////////////////////////////////////////////////////////////////////////////
2235/// constructor
2236
2238{
2240 for (Int_t i = 0; i < 3; i++)
2241 fTranslation[i] = 0.0;
2242 for (Int_t j = 0; j < 3; j++)
2243 fScale[j] = 1.0;
2244 fRotation = nullptr;
2245}
2246
2247////////////////////////////////////////////////////////////////////////////////
2248/// constructor
2249
2259
2260////////////////////////////////////////////////////////////////////////////////
2261/// constructor
2262
2272
2273////////////////////////////////////////////////////////////////////////////////
2274/// destructor
2275
2277
2278////////////////////////////////////////////////////////////////////////////////
2279/// clear the fields of this transformation
2280
2282{
2283 memset(&fTranslation[0], 0, kN3);
2284 memset(&fScale[0], 0, kN3);
2285 if (fRotation)
2286 fRotation->Clear();
2287}
2288
2289////////////////////////////////////////////////////////////////////////////////
2290/// set the scale
2291
2293{
2294 if (sx < 1.E-5 || sy < 1.E-5 || sz < 1.E-5) {
2295 Error("ctor", "Invalid scale");
2296 return;
2297 }
2298 fScale[0] = sx;
2299 fScale[1] = sy;
2300 fScale[2] = sz;
2301}
2302
2303////////////////////////////////////////////////////////////////////////////////
2304/// Return a temporary inverse of this.
2305
2307{
2308 TGeoHMatrix h = *this;
2310 return h;
2311}
2312
2313////////////////////////////////////////////////////////////////////////////////
2314/// A scale transformation should be normalized by sx*sy*sz factor
2315
2317{
2318 Double_t normfactor = fScale[0] * fScale[1] * fScale[2];
2319 if (normfactor <= 1E-5)
2320 return kFALSE;
2321 for (Int_t i = 0; i < 3; i++)
2322 fScale[i] /= normfactor;
2323 return kTRUE;
2324}
2325
2326/** \class TGeoIdentity
2327\ingroup Geometry_classes
2328An identity transformation. It holds no data member
2329and returns pointers to static null translation and identity
2330transformations for rotation and scale
2331*/
2332
2333
2334////////////////////////////////////////////////////////////////////////////////
2335/// dummy ctor
2336
2338{
2339 if (!gGeoIdentity)
2340 gGeoIdentity = this;
2342}
2343
2344////////////////////////////////////////////////////////////////////////////////
2345/// constructor
2346
2348{
2349 if (!gGeoIdentity)
2350 gGeoIdentity = this;
2352}
2353
2354////////////////////////////////////////////////////////////////////////////////
2355/// Return a temporary inverse of this.
2356
2358{
2360 return h;
2361}
2362
2363/** \class TGeoHMatrix
2364\ingroup Geometry_classes
2365
2366Matrix class used for computing global transformations
2367Should NOT be used for node definition. An instance of this class
2368is generally used to pile-up local transformations starting from
2369the top level physical node, down to the current node.
2370*/
2371
2372
2373////////////////////////////////////////////////////////////////////////////////
2374/// dummy ctor
2375
2382
2383////////////////////////////////////////////////////////////////////////////////
2384/// constructor
2385
2392
2393////////////////////////////////////////////////////////////////////////////////
2394/// assignment
2395
2397{
2398 memset(&fTranslation[0], 0, kN3);
2401 if (matrix.IsIdentity())
2402 return;
2403 if (matrix.IsTranslation())
2404 SetTranslation(matrix.GetTranslation());
2405 if (matrix.IsRotation())
2406 memcpy(fRotationMatrix, matrix.GetRotationMatrix(), kN9);
2407 if (matrix.IsScale())
2408 memcpy(fScale, matrix.GetScale(), kN3);
2409}
2410
2411////////////////////////////////////////////////////////////////////////////////
2412/// destructor
2413
2415
2416////////////////////////////////////////////////////////////////////////////////
2417/// assignment
2418
2423
2424////////////////////////////////////////////////////////////////////////////////
2425/// assignment
2426
2428{
2429 if (&matrix == this)
2430 return *this;
2431 Clear();
2434 if (matrix.IsIdentity()) {
2436 return *this;
2437 }
2438 if (matrix.IsTranslation())
2439 memcpy(fTranslation, matrix.GetTranslation(), kN3);
2440 if (matrix.IsRotation())
2441 memcpy(fRotationMatrix, matrix.GetRotationMatrix(), kN9);
2442 if (matrix.IsScale())
2443 memcpy(fScale, matrix.GetScale(), kN3);
2445 return *this;
2446}
2447
2448////////////////////////////////////////////////////////////////////////////////
2449/// Composition
2450
2452{
2453 Multiply(&right);
2454 return *this;
2455}
2456
2458{
2459 TGeoHMatrix h = *this;
2460 h *= right;
2461 return h;
2462}
2463
2464////////////////////////////////////////////////////////////////////////////////
2465/// Is-equal operator
2466
2468{
2469 if (&other == this)
2470 return kTRUE;
2471 const Double_t *tr = GetTranslation();
2472 const Double_t *otr = other.GetTranslation();
2473 for (auto i = 0; i < 3; i++)
2474 if (TMath::Abs(tr[i] - otr[i]) > 1.E-10)
2475 return kFALSE;
2476 const Double_t *rot = GetRotationMatrix();
2477 const Double_t *orot = other.GetRotationMatrix();
2478 for (auto i = 0; i < 9; i++)
2479 if (TMath::Abs(rot[i] - orot[i]) > 1.E-10)
2480 return kFALSE;
2481 const Double_t *scl = GetScale();
2482 const Double_t *oscl = other.GetScale();
2483 for (auto i = 0; i < 3; i++)
2484 if (TMath::Abs(scl[i] - oscl[i]) > 1.E-10)
2485 return kFALSE;
2486 return kTRUE;
2487}
2488
2489////////////////////////////////////////////////////////////////////////////////
2490/// Fast copy method.
2491
2493{
2494 SetBit(kGeoTranslation, other->IsTranslation());
2495 SetBit(kGeoRotation, other->IsRotation());
2496 SetBit(kGeoReflection, other->IsReflection());
2497 memcpy(fTranslation, other->GetTranslation(), kN3);
2498 memcpy(fRotationMatrix, other->GetRotationMatrix(), kN9);
2499}
2500
2501////////////////////////////////////////////////////////////////////////////////
2502/// clear the data for this matrix
2503
2516
2517////////////////////////////////////////////////////////////////////////////////
2518/// Make a clone of this matrix.
2519
2521{
2522 TGeoMatrix *matrix = new TGeoHMatrix(*this);
2523 return matrix;
2524}
2525
2526////////////////////////////////////////////////////////////////////////////////
2527/// Perform a rotation about Z having the sine/cosine of the rotation angle.
2528
2530{
2531 fRotationMatrix[0] = sincos[1];
2532 fRotationMatrix[1] = -sincos[0];
2533 fRotationMatrix[3] = sincos[0];
2534 fRotationMatrix[4] = sincos[1];
2536}
2537
2538////////////////////////////////////////////////////////////////////////////////
2539/// Return a temporary inverse of this.
2540
2542{
2543 TGeoHMatrix h;
2544 h = *this;
2546 if (IsTranslation()) {
2547 Double_t tr[3];
2554 h.SetTranslation(tr);
2555 }
2556 if (IsRotation()) {
2557 Double_t newrot[9];
2558 newrot[0] = fRotationMatrix[0];
2559 newrot[1] = fRotationMatrix[3];
2560 newrot[2] = fRotationMatrix[6];
2561 newrot[3] = fRotationMatrix[1];
2562 newrot[4] = fRotationMatrix[4];
2563 newrot[5] = fRotationMatrix[7];
2564 newrot[6] = fRotationMatrix[2];
2565 newrot[7] = fRotationMatrix[5];
2566 newrot[8] = fRotationMatrix[8];
2567 h.SetRotation(newrot);
2568 }
2569 if (IsScale()) {
2570 Double_t sc[3];
2571 sc[0] = 1. / fScale[0];
2572 sc[1] = 1. / fScale[1];
2573 sc[2] = 1. / fScale[2];
2574 h.SetScale(sc);
2575 }
2576 return h;
2577}
2578
2579////////////////////////////////////////////////////////////////////////////////
2580/// computes determinant of the rotation matrix
2581
2592
2593////////////////////////////////////////////////////////////////////////////////
2594/// multiply to the right with an other transformation
2595/// if right is identity matrix, just return
2596
2598{
2599 if (right->IsIdentity())
2600 return;
2601 const Double_t *r_tra = right->GetTranslation();
2602 const Double_t *r_rot = right->GetRotationMatrix();
2603 const Double_t *r_scl = right->GetScale();
2604 if (IsIdentity()) {
2605 if (right->IsRotation()) {
2608 if (right->IsReflection())
2610 }
2611 if (right->IsScale()) {
2614 }
2615 if (right->IsTranslation()) {
2618 }
2619 return;
2620 }
2621 Int_t i, j;
2622 Double_t new_rot[9];
2623
2624 if (right->IsRotation()) {
2626 if (right->IsReflection())
2628 }
2629 if (right->IsScale())
2631 if (right->IsTranslation())
2633
2634 // new translation
2635 if (IsTranslation()) {
2636 for (i = 0; i < 3; i++) {
2637 fTranslation[i] += fRotationMatrix[3 * i] * r_tra[0] + fRotationMatrix[3 * i + 1] * r_tra[1] +
2638 fRotationMatrix[3 * i + 2] * r_tra[2];
2639 }
2640 }
2641 if (IsRotation()) {
2642 // new rotation
2643 for (i = 0; i < 3; i++) {
2644 for (j = 0; j < 3; j++) {
2645 new_rot[3 * i + j] = fRotationMatrix[3 * i] * r_rot[j] + fRotationMatrix[3 * i + 1] * r_rot[3 + j] +
2646 fRotationMatrix[3 * i + 2] * r_rot[6 + j];
2647 }
2648 }
2650 }
2651 // new scale
2652 if (IsScale()) {
2653 for (i = 0; i < 3; i++)
2654 fScale[i] *= r_scl[i];
2655 }
2656}
2657
2658////////////////////////////////////////////////////////////////////////////////
2659/// multiply to the left with an other transformation
2660/// if right is identity matrix, just return
2661
2663{
2664 if (left == gGeoIdentity)
2665 return;
2666 const Double_t *l_tra = left->GetTranslation();
2667 const Double_t *l_rot = left->GetRotationMatrix();
2668 const Double_t *l_scl = left->GetScale();
2669 if (IsIdentity()) {
2670 if (left->IsRotation()) {
2671 if (left->IsReflection())
2675 }
2676 if (left->IsScale()) {
2679 }
2680 if (left->IsTranslation()) {
2683 }
2684 return;
2685 }
2686 Int_t i, j;
2687 Double_t new_tra[3];
2688 Double_t new_rot[9];
2689
2690 if (left->IsRotation()) {
2692 if (left->IsReflection())
2694 }
2695 if (left->IsScale())
2697 if (left->IsTranslation())
2699
2700 // new translation
2701 if (IsTranslation()) {
2702 for (i = 0; i < 3; i++) {
2703 new_tra[i] = l_tra[i] + l_rot[3 * i] * fTranslation[0] + l_rot[3 * i + 1] * fTranslation[1] +
2704 l_rot[3 * i + 2] * fTranslation[2];
2705 }
2707 }
2708 if (IsRotation()) {
2709 // new rotation
2710 for (i = 0; i < 3; i++) {
2711 for (j = 0; j < 3; j++) {
2712 new_rot[3 * i + j] = l_rot[3 * i] * fRotationMatrix[j] + l_rot[3 * i + 1] * fRotationMatrix[3 + j] +
2713 l_rot[3 * i + 2] * fRotationMatrix[6 + j];
2714 }
2715 }
2717 }
2718 // new scale
2719 if (IsScale()) {
2720 for (i = 0; i < 3; i++)
2721 fScale[i] *= l_scl[i];
2722 }
2723}
2724
2725////////////////////////////////////////////////////////////////////////////////
2726/// Rotate about X axis with angle expressed in degrees.
2727
2729{
2731 Double_t phi = angle * TMath::DegToRad();
2732 Double_t c = TMath::Cos(phi);
2733 Double_t s = TMath::Sin(phi);
2734 Double_t v[9];
2735 v[0] = fRotationMatrix[0];
2736 v[1] = fRotationMatrix[1];
2737 v[2] = fRotationMatrix[2];
2738 v[3] = c * fRotationMatrix[3] - s * fRotationMatrix[6];
2739 v[4] = c * fRotationMatrix[4] - s * fRotationMatrix[7];
2740 v[5] = c * fRotationMatrix[5] - s * fRotationMatrix[8];
2741 v[6] = s * fRotationMatrix[3] + c * fRotationMatrix[6];
2742 v[7] = s * fRotationMatrix[4] + c * fRotationMatrix[7];
2743 v[8] = s * fRotationMatrix[5] + c * fRotationMatrix[8];
2745
2746 v[0] = fTranslation[0];
2747 v[1] = c * fTranslation[1] - s * fTranslation[2];
2748 v[2] = s * fTranslation[1] + c * fTranslation[2];
2750}
2751
2752////////////////////////////////////////////////////////////////////////////////
2753/// Rotate about Y axis with angle expressed in degrees.
2754
2756{
2758 Double_t phi = angle * TMath::DegToRad();
2759 Double_t c = TMath::Cos(phi);
2760 Double_t s = TMath::Sin(phi);
2761 Double_t v[9];
2762 v[0] = c * fRotationMatrix[0] + s * fRotationMatrix[6];
2763 v[1] = c * fRotationMatrix[1] + s * fRotationMatrix[7];
2764 v[2] = c * fRotationMatrix[2] + s * fRotationMatrix[8];
2765 v[3] = fRotationMatrix[3];
2766 v[4] = fRotationMatrix[4];
2767 v[5] = fRotationMatrix[5];
2768 v[6] = -s * fRotationMatrix[0] + c * fRotationMatrix[6];
2769 v[7] = -s * fRotationMatrix[1] + c * fRotationMatrix[7];
2770 v[8] = -s * fRotationMatrix[2] + c * fRotationMatrix[8];
2772
2773 v[0] = c * fTranslation[0] + s * fTranslation[2];
2774 v[1] = fTranslation[1];
2775 v[2] = -s * fTranslation[0] + c * fTranslation[2];
2777}
2778
2779////////////////////////////////////////////////////////////////////////////////
2780/// Rotate about Z axis with angle expressed in degrees.
2781
2783{
2785 Double_t phi = angle * TMath::DegToRad();
2786 Double_t c = TMath::Cos(phi);
2787 Double_t s = TMath::Sin(phi);
2788 Double_t v[9];
2789 v[0] = c * fRotationMatrix[0] - s * fRotationMatrix[3];
2790 v[1] = c * fRotationMatrix[1] - s * fRotationMatrix[4];
2791 v[2] = c * fRotationMatrix[2] - s * fRotationMatrix[5];
2792 v[3] = s * fRotationMatrix[0] + c * fRotationMatrix[3];
2793 v[4] = s * fRotationMatrix[1] + c * fRotationMatrix[4];
2794 v[5] = s * fRotationMatrix[2] + c * fRotationMatrix[5];
2795 v[6] = fRotationMatrix[6];
2796 v[7] = fRotationMatrix[7];
2797 v[8] = fRotationMatrix[8];
2798 memcpy(&fRotationMatrix[0], v, kN9);
2799
2800 v[0] = c * fTranslation[0] - s * fTranslation[1];
2801 v[1] = s * fTranslation[0] + c * fTranslation[1];
2802 v[2] = fTranslation[2];
2804}
2805
2806////////////////////////////////////////////////////////////////////////////////
2807/// Multiply by a reflection respect to YZ.
2808
2825
2826////////////////////////////////////////////////////////////////////////////////
2827/// Multiply by a reflection respect to ZX.
2828
2845
2846////////////////////////////////////////////////////////////////////////////////
2847/// Multiply by a reflection respect to XY.
2848
2865
2866////////////////////////////////////////////////////////////////////////////////
2867/// Save a primitive as a C++ statement(s) on output stream "out".
2868
2869void TGeoHMatrix::SavePrimitive(std::ostream &out, Option_t * /*option*/ /*= ""*/)
2870{
2872 return;
2873 const Double_t *tr = fTranslation;
2874 const Double_t *rot = fRotationMatrix;
2875 out << " // HMatrix: " << GetName() << std::endl;
2876 out << " tr[0] = " << tr[0] << "; "
2877 << "tr[1] = " << tr[1] << "; "
2878 << "tr[2] = " << tr[2] << ";" << std::endl;
2879 out << " rot[0] =" << rot[0] << "; "
2880 << "rot[1] = " << rot[1] << "; "
2881 << "rot[2] = " << rot[2] << ";" << std::endl;
2882 out << " rot[3] =" << rot[3] << "; "
2883 << "rot[4] = " << rot[4] << "; "
2884 << "rot[5] = " << rot[5] << ";" << std::endl;
2885 out << " rot[6] =" << rot[6] << "; "
2886 << "rot[7] = " << rot[7] << "; "
2887 << "rot[8] = " << rot[8] << ";" << std::endl;
2888 const char *name = GetPointerName();
2889 out << " auto " << name << " = new TGeoHMatrix(\"" << GetName() << "\");" << std::endl;
2890 out << " " << name << "->SetTranslation(tr);" << std::endl;
2891 out << " " << name << "->SetRotation(rot);" << std::endl;
2892 if (IsTranslation())
2893 out << " " << name << "->SetBit(TGeoMatrix::kGeoTranslation);" << std::endl;
2894 if (IsRotation())
2895 out << " " << name << "->SetBit(TGeoMatrix::kGeoRotation);" << std::endl;
2896 if (IsReflection())
2897 out << " " << name << "->SetBit(TGeoMatrix::kGeoReflection);" << std::endl;
2899}
#define c(i)
Definition RSha256.hxx:101
#define h(i)
Definition RSha256.hxx:106
int Int_t
Signed integer 4 bytes (int)
Definition RtypesCore.h:59
constexpr Bool_t kFALSE
Definition RtypesCore.h:108
double Double_t
Double 8 bytes.
Definition RtypesCore.h:73
constexpr Bool_t kTRUE
Definition RtypesCore.h:107
const char Option_t
Option string (const char)
Definition RtypesCore.h:80
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
Option_t Option_t option
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t r
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t index
Option_t Option_t TPoint TPoint angle
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t type
char name[80]
Definition TGX11.cxx:110
R__EXTERN TGeoManager * gGeoManager
const Int_t kN3
TGeoIdentity * gGeoIdentity
const Int_t kN9
const Double_t kUnitScale[3]
Definition TGeoMatrix.h:28
const Double_t kIdentityMatrix[3 *3]
Definition TGeoMatrix.h:26
R__EXTERN TGeoIdentity * gGeoIdentity
Definition TGeoMatrix.h:537
const Double_t kNullVector[3]
Definition TGeoMatrix.h:24
Class describing rotation + translation.
Definition TGeoMatrix.h:317
void Multiply(const TGeoMatrix *right)
multiply to the right with an other transformation if right is identity matrix, just return
TGeoCombiTrans & operator*=(const TGeoMatrix &other)
Composition.
void ReflectX(Bool_t leftside, Bool_t rotonly=kFALSE) override
Multiply by a reflection respect to YZ.
Bool_t operator==(const TGeoMatrix &other) const
Is-equal operator.
TGeoCombiTrans()
dummy ctor
void RegisterYourself() override
Register the matrix in the current manager, which will become the owner.
const Double_t * GetTranslation() const override
Definition TGeoMatrix.h:361
void SavePrimitive(std::ostream &out, Option_t *option="") override
Save a primitive as a C++ statement(s) on output stream "out".
TGeoMatrix * MakeClone() const override
Make a clone of this matrix.
TGeoHMatrix Inverse() const override
Return a temporary inverse of this.
void RotateY(Double_t angle) override
Rotate about Y axis with angle expressed in degrees.
Double_t fTranslation[3]
Definition TGeoMatrix.h:319
TGeoRotation * fRotation
Definition TGeoMatrix.h:320
void RotateX(Double_t angle) override
Rotate about X axis with angle expressed in degrees.
void SetTranslation(const TGeoTranslation &tr)
copy the translation component
void SetRotation(const TGeoRotation &other)
Copy the rotation from another one.
void Clear(Option_t *option="") override
Reset translation/rotation to identity.
TGeoCombiTrans & operator=(const TGeoCombiTrans &other)
Definition TGeoMatrix.h:330
void ReflectY(Bool_t leftside, Bool_t rotonly=kFALSE) override
Multiply by a reflection respect to ZX.
~TGeoCombiTrans() override
destructor
TGeoCombiTrans operator*(const TGeoMatrix &other) const
void RotateZ(Double_t angle) override
Rotate about Z axis with angle expressed in degrees.
const Double_t * GetRotationMatrix() const override
get the rotation array
void ReflectZ(Bool_t leftside, Bool_t rotonly=kFALSE) override
Multiply by a reflection respect to XY.
void Clear(Option_t *option="") override
clear the fields of this transformation
Double_t fScale[3]
Definition TGeoMatrix.h:377
~TGeoGenTrans() override
destructor
Bool_t Normalize()
A scale transformation should be normalized by sx*sy*sz factor.
TGeoGenTrans()
dummy ctor
void SetScale(Double_t sx, Double_t sy, Double_t sz)
set the scale
TGeoHMatrix Inverse() const override
Return a temporary inverse of this.
Matrix class used for computing global transformations Should NOT be used for node definition.
Definition TGeoMatrix.h:458
TGeoHMatrix & operator*=(const TGeoMatrix &other)
Composition.
TGeoHMatrix()
dummy ctor
void RotateX(Double_t angle) override
Rotate about X axis with angle expressed in degrees.
const Double_t * GetScale() const override
Definition TGeoMatrix.h:529
const Double_t * GetRotationMatrix() const override
Definition TGeoMatrix.h:528
void MultiplyLeft(const TGeoMatrix *left)
multiply to the left with an other transformation if right is identity matrix, just return
Double_t Determinant() const
computes determinant of the rotation matrix
TGeoMatrix * MakeClone() const override
Make a clone of this matrix.
TGeoHMatrix Inverse() const override
Return a temporary inverse of this.
void RotateZ(Double_t angle) override
Rotate about Z axis with angle expressed in degrees.
void ReflectX(Bool_t leftside, Bool_t rotonly=kFALSE) override
Multiply by a reflection respect to YZ.
void SavePrimitive(std::ostream &out, Option_t *option="") override
Save a primitive as a C++ statement(s) on output stream "out".
void CopyFrom(const TGeoMatrix *other)
Fast copy method.
void ReflectY(Bool_t leftside, Bool_t rotonly=kFALSE) override
Multiply by a reflection respect to ZX.
void FastRotZ(const Double_t *sincos)
Perform a rotation about Z having the sine/cosine of the rotation angle.
Double_t fTranslation[3]
Definition TGeoMatrix.h:460
Bool_t operator==(const TGeoMatrix &other) const
Is-equal operator.
Double_t fRotationMatrix[9]
Definition TGeoMatrix.h:461
~TGeoHMatrix() override
destructor
void RotateY(Double_t angle) override
Rotate about Y axis with angle expressed in degrees.
void Clear(Option_t *option="") override
clear the data for this matrix
const Double_t * GetTranslation() const override
Definition TGeoMatrix.h:527
TGeoHMatrix & operator=(const TGeoHMatrix &other)
Definition TGeoMatrix.h:471
void Multiply(const TGeoMatrix *right)
multiply to the right with an other transformation if right is identity matrix, just return
void ReflectZ(Bool_t leftside, Bool_t rotonly=kFALSE) override
Multiply by a reflection respect to XY.
TGeoHMatrix operator*(const TGeoMatrix &other) const
void SetTranslation(const Double_t *vect)
Definition TGeoMatrix.h:511
Double_t fScale[3]
Definition TGeoMatrix.h:462
An identity transformation.
Definition TGeoMatrix.h:406
TGeoHMatrix Inverse() const override
Return a temporary inverse of this.
TGeoIdentity()
dummy ctor
TObjArray * GetListOfMatrices() const
void RegisterMatrix(const TGeoMatrix *matrix)
Register a matrix to the list of matrices.
void BombTranslation(const Double_t *tr, Double_t *bombtr)
Get the new 'bombed' translation vector according current exploded view mode.
void UnbombTranslation(const Double_t *tr, Double_t *bombtr)
Get the new 'unbombed' translation vector according current exploded view mode.
Bool_t IsCleaning() const
Geometrical transformation package.
Definition TGeoMatrix.h:38
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
Bool_t IsScale() const
Definition TGeoMatrix.h:67
void SetDefaultName()
If no name was supplied in the ctor, the type of transformation is checked.
void Print(Option_t *option="") const override
print the matrix in 4x4 format
Bool_t IsGeneral() const
Definition TGeoMatrix.h:71
@ kGeoSavePrimitive
Definition TGeoMatrix.h:48
@ kGeoTranslation
Definition TGeoMatrix.h:43
@ kGeoMatrixOwned
Definition TGeoMatrix.h:49
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
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
virtual void ReflectZ(Bool_t leftside, Bool_t rotonly=kFALSE)
Multiply by a reflection respect to XY.
virtual const Double_t * GetTranslation() const =0
Bool_t IsTranslation() const
Definition TGeoMatrix.h:64
Bool_t IsReflection() const
Definition TGeoMatrix.h:66
Bool_t IsRotation() const
Definition TGeoMatrix.h:65
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
virtual void RegisterYourself()
Register the matrix in the current manager, which will become the owner.
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
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
Bool_t IsRotAboutZ() const
Returns true if no rotation or the rotation is about Z axis.
void GetHomogenousMatrix(Double_t *hmat) const
The homogenous matrix associated with the transformation is used for piling up's and visualization.
TGeoMatrix()
dummy constructor
Bool_t IsOwned() const
Definition TGeoMatrix.h:69
virtual const Double_t * GetScale() const =0
static void Normalize(Double_t *vect)
Normalize a vector.
Bool_t IsIdentity() const
Definition TGeoMatrix.h:63
const char * GetPointerName() const
Provide a pointer name containing uid.
Bool_t IsCombi() const
Definition TGeoMatrix.h:70
Bool_t IsRegistered() const
Definition TGeoMatrix.h:72
Bool_t IsShared() const
Definition TGeoMatrix.h:68
virtual const Double_t * GetRotationMatrix() const =0
virtual Int_t GetByteCount() const
Get total size in bytes of this.
~TGeoMatrix() override
Destructor.
virtual void ReflectY(Bool_t leftside, Bool_t rotonly=kFALSE)
Multiply by a reflection respect to ZX.
virtual void ReflectX(Bool_t leftside, Bool_t rotonly=kFALSE)
Multiply by a reflection respect to YZ.
Class describing rotations.
Definition TGeoMatrix.h:168
void RotateX(Double_t angle) override
Rotate about X axis of the master frame with angle expressed in degrees.
void ReflectZ(Bool_t leftside, Bool_t rotonly=kFALSE) override
Multiply by a reflection respect to XY.
TGeoRotation()
Default constructor.
void Clear(Option_t *option="") override
reset data members
const Double_t * GetRotationMatrix() const override
Definition TGeoMatrix.h:239
void SetAngles(Double_t phi, Double_t theta, Double_t psi)
Set matrix elements according to Euler angles.
void MultiplyBy(const TGeoRotation *rot, Bool_t after=kTRUE)
Multiply this rotation with the one specified by ROT.
void RotateY(Double_t angle) override
Rotate about Y axis of the master frame with angle expressed in degrees.
Bool_t operator==(const TGeoRotation &other) const
Is-equal operator.
void SetMatrix(const Double_t *rot)
Definition TGeoMatrix.h:230
void RotateZ(Double_t angle) override
Rotate about Z axis of the master frame with angle expressed in degrees.
void LocalToMaster(const Double_t *local, Double_t *master) const override
convert a point by multiplying its column vector (x, y, z, 1) to matrix inverse
TGeoRotation & operator*=(const TGeoRotation &other)
Composition.
void CheckMatrix()
performes an orthogonality check and finds if the matrix is a reflection Warning("CheckMatrix",...
void ReflectY(Bool_t leftside, Bool_t rotonly=kFALSE) override
Multiply by a reflection respect to ZX.
Double_t GetPhiRotation(Bool_t fixX=kFALSE) const
Returns rotation angle about Z axis in degrees.
void FastRotZ(const Double_t *sincos)
Perform a rotation about Z having the sine/cosine of the rotation angle.
void GetInverse(Double_t *invmat) const
Get the inverse rotation matrix (which is simply the transpose)
Double_t Determinant() const
computes determinant of the rotation matrix
void GetAngles(Double_t &theta1, Double_t &phi1, Double_t &theta2, Double_t &phi2, Double_t &theta3, Double_t &phi3) const
Retrieve rotation angles.
Bool_t IsValid() const
Perform orthogonality test for rotation.
void MasterToLocal(const Double_t *master, Double_t *local) const override
convert a point by multiplying its column vector (x, y, z, 1) to matrix
TGeoMatrix * MakeClone() const override
Make a clone of this matrix.
TGeoRotation operator*(const TGeoRotation &other) const
void SavePrimitive(std::ostream &out, Option_t *option="") override
Save a primitive as a C++ statement(s) on output stream "out".
void ReflectX(Bool_t leftside, Bool_t rotonly=kFALSE) override
Multiply by a reflection respect to YZ.
Double_t fRotationMatrix[3 *3]
Definition TGeoMatrix.h:170
void SetRotation(const TGeoMatrix &other)
Copy rotation elements from other rotation matrix.
TGeoRotation & operator=(const TGeoRotation &other)
Definition TGeoMatrix.h:185
TGeoHMatrix Inverse() const override
Return a temporary inverse of this.
Class describing scale transformations.
Definition TGeoMatrix.h:253
TGeoScale()
default constructor
const Double_t * GetScale() const override
Definition TGeoMatrix.h:305
TGeoScale & operator=(const TGeoScale &other)
Definition TGeoMatrix.h:264
TGeoMatrix * MakeClone() const override
Make a clone of this matrix.
Bool_t operator==(const TGeoScale &other) const
Is-equal operator.
~TGeoScale() override
destructor
void SetScale(Double_t sx, Double_t sy, Double_t sz)
scale setter
void LocalToMaster(const Double_t *local, Double_t *master) const override
Convert a local point to the master frame.
TGeoHMatrix Inverse() const override
Return a temporary inverse of this.
Double_t fScale[3]
Definition TGeoMatrix.h:255
TGeoScale operator*(const TGeoScale &other) const
TGeoScale & operator*=(const TGeoScale &other)
Scale composition.
void MasterToLocal(const Double_t *master, Double_t *local) const override
Convert a global point to local frame.
Class describing translations.
Definition TGeoMatrix.h:116
void RotateX(Double_t angle) override
Rotate about X axis of the master frame with angle expressed in degrees.
void RotateY(Double_t angle) override
Rotate about Y axis of the master frame with angle expressed in degrees.
Bool_t operator==(const TGeoTranslation &other) const
Is-equal operator.
TGeoTranslation & operator*=(const TGeoTranslation &other)
Translation composition.
TGeoTranslation operator*(const TGeoTranslation &right) const
void Add(const TGeoTranslation *other)
Adding a translation to this one.
void RotateZ(Double_t angle) override
Rotate about Z axis of the master frame with angle expressed in degrees.
void LocalToMasterVect(const Double_t *local, Double_t *master) const override
convert a vector to MARS
void LocalToMaster(const Double_t *local, Double_t *master) const override
convert a point by multiplying its column vector (x, y, z, 1) to matrix inverse
void MasterToLocalBomb(const Double_t *master, Double_t *local) const override
convert a point by multiplying its column vector (x, y, z, 1) to matrix
void SetTranslation(Double_t dx, Double_t dy, Double_t dz)
Set translation components.
TGeoTranslation & operator=(const TGeoTranslation &other)
Definition TGeoMatrix.h:127
Double_t fTranslation[3]
Definition TGeoMatrix.h:118
const Double_t * GetTranslation() const override
Definition TGeoMatrix.h:154
void MasterToLocal(const Double_t *master, Double_t *local) const override
convert a point by multiplying its column vector (x, y, z, 1) to matrix
void LocalToMasterBomb(const Double_t *local, Double_t *master) const override
convert a point by multiplying its column vector (x, y, z, 1) to matrix inverse
void SavePrimitive(std::ostream &out, Option_t *option="") override
Save a primitive as a C++ statement(s) on output stream "out".
TGeoTranslation()
Default constructor.
void Subtract(const TGeoTranslation *other)
Subtracting a translation from this one.
TGeoMatrix * MakeClone() const override
Make a clone of this matrix.
void MasterToLocalVect(const Double_t *master, Double_t *local) const override
convert a vector from MARS to local
TGeoHMatrix Inverse() const override
Return a temporary inverse of this.
The TNamed class is the base class for all named ROOT classes.
Definition TNamed.h:29
const char * GetName() const override
Returns name of object.
Definition TNamed.h:49
const char * GetTitle() const override
Returns title of object.
Definition TNamed.h:50
virtual void SetName(const char *name)
Set the name of the TNamed.
Definition TNamed.cxx:149
TNamed & operator=(const TNamed &rhs)
TNamed assignment operator.
Definition TNamed.cxx:50
An array of TObjects.
Definition TObjArray.h:31
TObject * Remove(TObject *obj) override
Remove object from array.
R__ALWAYS_INLINE Bool_t TestBit(UInt_t f) const
Definition TObject.h:202
virtual UInt_t GetUniqueID() const
Return the unique object id.
Definition TObject.cxx:475
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition TObject.cxx:1057
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
Definition TObject.cxx:864
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition TObject.cxx:1071
void ResetBit(UInt_t f)
Definition TObject.h:201
Basic string class.
Definition TString.h:138
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:2384
Double_t ACos(Double_t)
Returns the principal value of the arc cosine of x, expressed in radians.
Definition TMath.h:643
Double_t ASin(Double_t)
Returns the principal value of the arc sine of x, expressed in radians.
Definition TMath.h:635
Double_t ATan2(Double_t y, Double_t x)
Returns the principal value of the arc tangent of y/x, expressed in radians.
Definition TMath.h:657
constexpr Double_t DegToRad()
Conversion from degree to radian: .
Definition TMath.h:82
Double_t Sqrt(Double_t x)
Returns the square root of x.
Definition TMath.h:673
Double_t Cos(Double_t)
Returns the cosine of an angle of x radians.
Definition TMath.h:605
constexpr Double_t Pi()
Definition TMath.h:40
Double_t Sin(Double_t)
Returns the sine of an angle of x radians.
Definition TMath.h:599
constexpr Double_t RadToDeg()
Conversion from radian to degree: .
Definition TMath.h:75
Short_t Abs(Short_t d)
Returns the absolute value of parameter Short_t d.
Definition TMathBase.h:124
auto * th3
Definition textalign.C:22
auto * th2
Definition textalign.C:18
auto * th1
Definition textalign.C:14
TMarker m
Definition textangle.C:8