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