Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
TGeoMatrix.cxx
Go to the documentation of this file.
1// @(#)root/geom:$Id$
2// Author: Andrei Gheata 25/10/01
3
4/*************************************************************************
5 * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. *
6 * All rights reserved. *
7 * *
8 * For the licensing terms see $ROOTSYS/LICENSE. *
9 * For the list of contributors see $ROOTSYS/README/CREDITS. *
10 *************************************************************************/
11
12/** \class TGeoMatrix
13\ingroup Geometry_classes
14
15Geometrical transformation package.
16
17 All geometrical transformations handled by the modeller are provided as a
18built-in package. This was designed to minimize memory requirements and
19optimize performance of point/vector master-to-local and local-to-master
20computation. We need to have in mind that a transformation in TGeo has 2
21major use-cases. The first one is for defining the placement of a volume
22with respect to its container reference frame. This frame will be called
23'master' and the frame of the positioned volume - 'local'. If T is a
24transformation used for positioning volume daughters, then:
25
26~~~ {.cpp}
27 MASTER = T * LOCAL
28~~~
29
30 Therefore a local-to-master conversion will be performed by using T, while
31a master-to-local by using its inverse. The second use case is the computation
32of the global transformation of a given object in the geometry. Since the
33geometry is built as 'volumes-inside-volumes', this global transformation
34represent the pile-up of all local transformations in the corresponding
35branch. The conversion from the global reference frame and the given object
36is also called master-to-local, but it is handled by the manager class.
37 A general homogenous transformation is defined as a 4x4 matrix embedding
38a rotation, a translation and a scale. The advantage of this description
39is that each basic transformation can be represented as a homogenous matrix,
40composition being performed as simple matrix multiplication.
41
42 Rotation: Inverse rotation:
43
44~~~ {.cpp}
45 r11 r12 r13 0 r11 r21 r31 0
46 r21 r22 r23 0 r12 r22 r32 0
47 r31 r32 r33 0 r13 r23 r33 0
48 0 0 0 1 0 0 0 1
49~~~
50
51 Translation: Inverse translation:
52
53~~~ {.cpp}
54 1 0 0 tx 1 0 0 -tx
55 0 1 0 ty 0 1 0 -ty
56 0 0 1 tz 0 0 1 -tz
57 0 0 0 1 0 0 0 1
58~~~
59
60 Scale: Inverse scale:
61
62~~~ {.cpp}
63 sx 0 0 0 1/sx 0 0 0
64 0 sy 0 0 0 1/sy 0 0
65 0 0 sz 0 0 0 1/sz 0
66 0 0 0 1 0 0 0 1
67~~~
68
69 where:
70 - `rij` are the 3x3 rotation matrix components,
71 - `tx`, `ty`, `tz` are the translation components
72 - `sx`, `sy`, `sz` are arbitrary scale constants on each axis,
73
74 The disadvantage in using this approach is that computation for 4x4 matrices
75is expensive. Even combining two translation would become a multiplication
76of their corresponding matrices, which is quite an undesired effect. On the
77other hand, it is not a good idea to store a translation as a block of 16
78numbers. We have therefore chosen to implement each basic transformation type
79as a class deriving from the same basic abstract class and handling its specific
80data and point/vector transformation algorithms.
81
82\image html geom_transf.jpg
83
84### The base class TGeoMatrix defines abstract metods for:
85
86#### translation, rotation and scale getters. Every derived class stores only
87 its specific data, e.g. a translation stores an array of 3 doubles and a
88 rotation an array of 9. However, asking which is the rotation array of a
89 TGeoTranslation through the base TGeoMatrix interface is a legal operation.
90 The answer in this case is a pointer to a global constant array representing
91 an identity rotation.
92
93~~~ {.cpp}
94 Double_t *TGeoMatrix::GetTranslation()
95 Double_t *TGeoMatrix::GetRotation()
96 Double_t *TGeoMatrix::GetScale()
97~~~
98
99#### MasterToLocal() and LocalToMaster() point and vector transformations :
100
101~~~ {.cpp}
102 void TGeoMatrix::MasterToLocal(const Double_t *master, Double_t *local)
103 void TGeoMatrix::LocalToMaster(const Double_t *local, Double_t *master)
104 void TGeoMatrix::MasterToLocalVect(const Double_t *master, Double_t *local)
105 void TGeoMatrix::LocalToMasterVect(const Double_t *local, Double_t *master)
106~~~
107
108 These allow correct conversion also for reflections.
109
110#### Transformation type getters :
111
112~~~ {.cpp}
113 Bool_t TGeoMatrix::IsIdentity()
114 Bool_t TGeoMatrix::IsTranslation()
115 Bool_t TGeoMatrix::IsRotation()
116 Bool_t TGeoMatrix::IsScale()
117 Bool_t TGeoMatrix::IsCombi() (translation + rotation)
118 Bool_t TGeoMatrix::IsGeneral() (translation + rotation + scale)
119~~~
120
121 Combinations of basic transformations are represented by specific classes
122deriving from TGeoMatrix. In order to define a matrix as a combination of several
123others, a special class TGeoHMatrix is provided. Here is an example of matrix
124creation :
125
126### Matrix creation example:
127
128~~~ {.cpp}
129 root[0] TGeoRotation r1,r2;
130 r1.SetAngles(90,0,30); // rotation defined by Euler angles
131 r2.SetAngles(90,90,90,180,0,0); // rotation defined by GEANT3 angles
132 TGeoTranslation t1(-10,10,0);
133 TGeoTranslation t2(10,-10,5);
134 TGeoCombiTrans c1(t1,r1);
135 TGeoCombiTrans c2(t2,r2);
136 TGeoHMatrix h = c1 * c2; // composition is done via TGeoHMatrix class
137 root[7] TGeoHMatrix *ph = new TGeoHMatrix(hm); // this is the one we want to
138 // use for positioning a volume
139 root[8] ph->Print();
140 ...
141 pVolume->AddNode(pVolDaughter,id,ph) // now ph is owned by the manager
142~~~
143
144### Rule for matrix creation:
145 Unless explicitly used for positioning nodes (TGeoVolume::AddNode()) all
146matrices deletion have to be managed by users. Matrices passed to geometry
147have to be created by using new() operator and their deletion is done by
148TGeoManager class.
149
150### Available geometrical transformations
151
152#### TGeoTranslation
153Represent a (dx,dy,dz) translation. Data members:
154 Double_t fTranslation[3]. Translations can be added/subtracted.
155
156~~~ {.cpp}
157 TGeoTranslation t1;
158 t1->SetTranslation(-5,10,4);
159 TGeoTranslation *t2 = new TGeoTranslation(4,3,10);
160 t2->Subtract(&t1);
161~~~
162
163#### Rotations
164 Represent a pure rotation. Data members: Double_t fRotationMatrix[3*3].
165 Rotations can be defined either by Euler angles, either, by GEANT3 angles :
166
167~~~ {.cpp}
168 TGeoRotation *r1 = new TGeoRotation();
169 r1->SetAngles(phi, theta, psi); // all angles in degrees
170~~~
171
172 This represent the composition of : first a rotation about Z axis with
173 angle phi, then a rotation with theta about the rotated X axis, and
174 finally a rotation with psi about the new Z axis.
175
176~~~ {.cpp}
177 r1->SetAngles(th1,phi1, th2,phi2, th3,phi3)
178~~~
179
180 This is a rotation defined in GEANT3 style. Theta and phi are the spherical
181 angles of each axis of the rotated coordinate system with respect to the
182 initial one. This construction allows definition of malformed rotations,
183 e.g. not orthogonal. A check is performed and an error message is issued
184 in this case.
185
186 Specific utilities : determinant, inverse.
187
188#### Scale transformations
189 Represent a scale shrinking/enlargement. Data
190 members :Double_t fScale[3]. Not fully implemented yet.
191
192#### Combined transformations
193Represent a rotation followed by a translation.
194Data members: Double_t fTranslation[3], TGeoRotation *fRotation.
195
196~~~ {.cpp}
197 TGeoRotation *rot = new TGeoRotation("rot",10,20,30);
198 TGeoTranslation trans;
199 ...
200 TGeoCombiTrans *c1 = new TGeoCombiTrans(trans, rot);
201 TGeoCombiTrans *c2 = new TGeoCombiTrans("somename",10,20,30,rot)
202~~~
203
204
205#### TGeoGenTrans
206Combined transformations including a scale. Not implemented.
207
208#### TGeoIdentity
209A generic singleton matrix representing a identity transformation
210 NOTE: identified by the global variable gGeoIdentity.
211*/
212
213#include <iostream>
214#include "TObjArray.h"
215
216#include "TGeoManager.h"
217#include "TGeoMatrix.h"
218#include "TMath.h"
219
221const Int_t kN3 = 3 * sizeof(Double_t);
222const Int_t kN9 = 9 * sizeof(Double_t);
223
224// statics and globals
225
227
228////////////////////////////////////////////////////////////////////////////////
229/// dummy constructor
230
232{
234}
235
236////////////////////////////////////////////////////////////////////////////////
237/// copy constructor
238
240{
242}
243
244////////////////////////////////////////////////////////////////////////////////
245/// Constructor
246
248
249////////////////////////////////////////////////////////////////////////////////
250/// Destructor
251
253{
254 if (IsRegistered() && gGeoManager) {
255 if (!gGeoManager->IsCleaning()) {
257 Warning("dtor", "Registered matrix %s was removed", GetName());
258 }
259 }
260}
261
262////////////////////////////////////////////////////////////////////////////////
263/// Returns true if no rotation or the rotation is about Z axis
264
266{
267 if (IsIdentity())
268 return kTRUE;
269 const Double_t *rot = GetRotationMatrix();
270 if (TMath::Abs(rot[6]) > 1E-9)
271 return kFALSE;
272 if (TMath::Abs(rot[7]) > 1E-9)
273 return kFALSE;
274 if ((1. - TMath::Abs(rot[8])) > 1E-9)
275 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())
286 count += 12;
287 if (IsScale())
288 count += 12;
289 if (IsCombi() || IsGeneral())
290 count += 4 + 36;
291 return count;
292}
293
294////////////////////////////////////////////////////////////////////////////////
295/// Provide a pointer name containing uid.
296
297const char *TGeoMatrix::GetPointerName() const
298{
299 static TString name;
300 name.Form("pMatrix%d", GetUniqueID());
301 return name.Data();
302}
303
304////////////////////////////////////////////////////////////////////////////////
305/// The homogenous matrix associated with the transformation is used for
306/// piling up's and visualization. A homogenous matrix is a 4*4 array
307/// containing the translation, the rotation and the scale components
308/// ~~~ {.cpp}
309/// | R00*sx R01 R02 dx |
310/// | R10 R11*sy R12 dy |
311/// | R20 R21 R22*sz dz |
312/// | 0 0 0 1 |
313/// ~~~
314/// where Rij is the rotation matrix, (sx, sy, sz) is the scale
315/// transformation and (dx, dy, dz) is the translation.
316
318{
319 Double_t *hmatrix = hmat;
320 const Double_t *mat = GetRotationMatrix();
321 for (Int_t i = 0; i < 3; i++) {
322 memcpy(hmatrix, mat, kN3);
323 mat += 3;
324 hmatrix += 3;
325 *hmatrix = 0.0;
326 hmatrix++;
327 }
328 memcpy(hmatrix, GetTranslation(), kN3);
329 hmatrix = hmat;
330 if (IsScale()) {
331 for (Int_t i = 0; i < 3; i++) {
332 *hmatrix *= GetScale()[i];
333 hmatrix += 5;
334 }
335 }
336 hmatrix[15] = 1.;
337}
338
339////////////////////////////////////////////////////////////////////////////////
340/// convert a point by multiplying its column vector (x, y, z, 1) to matrix inverse
341
342void TGeoMatrix::LocalToMaster(const Double_t *local, Double_t *master) const
343{
344 if (IsIdentity()) {
345 memcpy(master, local, kN3);
346 return;
347 }
348 Int_t i;
349 const Double_t *tr = GetTranslation();
350 if (!IsRotation()) {
351 for (i = 0; i < 3; i++)
352 master[i] = tr[i] + local[i];
353 return;
354 }
355 const Double_t *rot = GetRotationMatrix();
356 for (i = 0; i < 3; i++) {
357 master[i] = tr[i] + local[0] * rot[3 * i] + local[1] * rot[3 * i + 1] + local[2] * rot[3 * i + 2];
358 }
359}
360
361////////////////////////////////////////////////////////////////////////////////
362/// convert a vector by multiplying its column vector (x, y, z, 1) to matrix inverse
363
364void TGeoMatrix::LocalToMasterVect(const Double_t *local, Double_t *master) const
365{
366 if (!IsRotation()) {
367 memcpy(master, local, kN3);
368 return;
369 }
370 const Double_t *rot = GetRotationMatrix();
371 for (Int_t i = 0; i < 3; i++) {
372 master[i] = local[0] * rot[3 * i] + local[1] * rot[3 * i + 1] + local[2] * rot[3 * i + 2];
373 }
374}
375
376////////////////////////////////////////////////////////////////////////////////
377/// convert a point by multiplying its column vector (x, y, z, 1) to matrix inverse
378
379void TGeoMatrix::LocalToMasterBomb(const Double_t *local, Double_t *master) const
380{
381 if (IsIdentity()) {
382 memcpy(master, local, kN3);
383 return;
384 }
385 Int_t i;
386 const Double_t *tr = GetTranslation();
387 Double_t bombtr[3] = {0., 0., 0.};
388 gGeoManager->BombTranslation(tr, &bombtr[0]);
389 if (!IsRotation()) {
390 for (i = 0; i < 3; i++)
391 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] + local[0] * rot[3 * i] + local[1] * rot[3 * i + 1] + local[2] * rot[3 * i + 2];
397 }
398}
399
400////////////////////////////////////////////////////////////////////////////////
401/// convert a point by multiplying its column vector (x, y, z, 1) to matrix
402
403void TGeoMatrix::MasterToLocal(const Double_t *master, Double_t *local) const
404{
405 if (IsIdentity()) {
406 memcpy(local, master, kN3);
407 return;
408 }
409 const Double_t *tr = GetTranslation();
410 Double_t mt0 = master[0] - tr[0];
411 Double_t mt1 = master[1] - tr[1];
412 Double_t mt2 = master[2] - tr[2];
413 if (!IsRotation()) {
414 local[0] = mt0;
415 local[1] = mt1;
416 local[2] = mt2;
417 return;
418 }
419 const Double_t *rot = GetRotationMatrix();
420 local[0] = mt0 * rot[0] + mt1 * rot[3] + mt2 * rot[6];
421 local[1] = mt0 * rot[1] + mt1 * rot[4] + mt2 * rot[7];
422 local[2] = mt0 * rot[2] + mt1 * rot[5] + mt2 * rot[8];
423}
424
425////////////////////////////////////////////////////////////////////////////////
426/// convert a point by multiplying its column vector (x, y, z, 1) to matrix
427
428void TGeoMatrix::MasterToLocalVect(const Double_t *master, Double_t *local) const
429{
430 if (!IsRotation()) {
431 memcpy(local, master, kN3);
432 return;
433 }
434 const Double_t *rot = GetRotationMatrix();
435 for (Int_t i = 0; i < 3; i++) {
436 local[i] = master[0] * rot[i] + master[1] * rot[i + 3] + master[2] * rot[i + 6];
437 }
438}
439
440////////////////////////////////////////////////////////////////////////////////
441/// convert a point by multiplying its column vector (x, y, z, 1) to matrix
442
443void TGeoMatrix::MasterToLocalBomb(const Double_t *master, Double_t *local) const
444{
445 if (IsIdentity()) {
446 memcpy(local, master, kN3);
447 return;
448 }
449 const Double_t *tr = GetTranslation();
450 Double_t bombtr[3] = {0., 0., 0.};
451 Int_t i;
452 gGeoManager->UnbombTranslation(tr, &bombtr[0]);
453 if (!IsRotation()) {
454 for (i = 0; i < 3; i++)
455 local[i] = master[i] - bombtr[i];
456 return;
457 }
458 const Double_t *rot = GetRotationMatrix();
459 for (i = 0; i < 3; i++) {
460 local[i] =
461 (master[0] - bombtr[0]) * rot[i] + (master[1] - bombtr[1]) * rot[i + 3] + (master[2] - bombtr[2]) * rot[i + 6];
462 }
463}
464
465////////////////////////////////////////////////////////////////////////////////
466/// Normalize a vector.
467
469{
470 Double_t normfactor = vect[0] * vect[0] + vect[1] * vect[1] + vect[2] * vect[2];
471 if (normfactor <= 1E-10)
472 return;
473 normfactor = 1. / TMath::Sqrt(normfactor);
474 vect[0] *= normfactor;
475 vect[1] *= normfactor;
476 vect[2] *= normfactor;
477}
478
479////////////////////////////////////////////////////////////////////////////////
480/// print the matrix in 4x4 format
481
483{
484 const Double_t *rot = GetRotationMatrix();
485 const Double_t *tr = GetTranslation();
486 printf("matrix %s - tr=%d rot=%d refl=%d scl=%d shr=%d reg=%d own=%d\n", GetName(), (Int_t)IsTranslation(),
488 (Int_t)IsOwned());
489 printf("%10.6f%12.6f%12.6f Tx = %10.6f\n", rot[0], rot[1], rot[2], tr[0]);
490 printf("%10.6f%12.6f%12.6f Ty = %10.6f\n", rot[3], rot[4], rot[5], tr[1]);
491 printf("%10.6f%12.6f%12.6f Tz = %10.6f\n", rot[6], rot[7], rot[8], tr[2]);
492 if (IsScale()) {
493 const Double_t *scl = GetScale();
494 printf("Sx=%10.6fSy=%12.6fSz=%12.6f\n", scl[0], scl[1], scl[2]);
495 }
496}
497
498////////////////////////////////////////////////////////////////////////////////
499/// Multiply by a reflection respect to YZ.
500
502
503////////////////////////////////////////////////////////////////////////////////
504/// Multiply by a reflection respect to ZX.
505
507
508////////////////////////////////////////////////////////////////////////////////
509/// Multiply by a reflection respect to XY.
510
512
513////////////////////////////////////////////////////////////////////////////////
514/// Register the matrix in the current manager, which will become the owner.
515
517{
518 if (!gGeoManager) {
519 Warning("RegisterYourself", "cannot register without geometry");
520 return;
521 }
522 if (!IsRegistered()) {
525 }
526}
527
528////////////////////////////////////////////////////////////////////////////////
529/// If no name was supplied in the ctor, the type of transformation is checked.
530/// A letter will be prepended to the name :
531/// - t - translation
532/// - r - rotation
533/// - s - scale
534/// - c - combi (translation + rotation)
535/// - g - general (tr+rot+scale)
536/// The index of the transformation in gGeoManager list of transformations will
537/// be appended.
538
540{
541 if (!gGeoManager)
542 return;
543 if (strlen(GetName()))
544 return;
545 char type = 'n';
546 if (IsTranslation())
547 type = 't';
548 if (IsRotation())
549 type = 'r';
550 if (IsScale())
551 type = 's';
552 if (IsCombi())
553 type = 'c';
554 if (IsGeneral())
555 type = 'g';
557 Int_t index = 0;
558 if (matrices)
559 index = matrices->GetEntriesFast() - 1;
561 SetName(name);
562}
563
564/** \class TGeoTranslation
565\ingroup Geometry_classes
566
567Class describing translations. A translation is
568basically an array of 3 doubles matching the positions 12, 13
569and 14 in the homogenous matrix description.
570*/
571
573
574////////////////////////////////////////////////////////////////////////////////
575/// Default constructor
576
578{
579 for (Int_t i = 0; i < 3; i++)
580 fTranslation[i] = 0;
581}
582
583////////////////////////////////////////////////////////////////////////////////
584/// Copy ctor.
585
587{
588 SetTranslation(other);
589}
590
591////////////////////////////////////////////////////////////////////////////////
592/// Ctor. based on a general matrix
593
595{
598 SetTranslation(other);
599}
600
601////////////////////////////////////////////////////////////////////////////////
602/// Default constructor defining the translation
603
605{
606 if (dx || dy || dz)
608 SetTranslation(dx, dy, dz);
609}
610
611////////////////////////////////////////////////////////////////////////////////
612/// Default constructor defining the translation
613
615{
616 if (dx || dy || dz)
618 SetTranslation(dx, dy, dz);
619}
620
621////////////////////////////////////////////////////////////////////////////////
622/// Assignment from a general matrix
623
625{
626 if (&matrix == this)
627 return *this;
628 Bool_t registered = TestBit(kGeoRegistered);
629 TNamed::operator=(matrix);
630 SetTranslation(matrix);
631 SetBit(kGeoRegistered, registered);
634 return *this;
635}
636
637////////////////////////////////////////////////////////////////////////////////
638/// Translation composition
639
641{
642 const Double_t *tr = right.GetTranslation();
643 fTranslation[0] += tr[0];
644 fTranslation[1] += tr[1];
645 fTranslation[2] += tr[2];
646 if (!IsTranslation())
648 return *this;
649}
650
652{
653 TGeoTranslation t = *this;
654 t *= right;
655 return t;
656}
657
659{
660 TGeoHMatrix t = *this;
661 t *= right;
662 return t;
663}
664
665////////////////////////////////////////////////////////////////////////////////
666/// Is-equal operator
667
669{
670 if (&other == this)
671 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)
676 return kFALSE;
677 return kTRUE;
678}
679
680////////////////////////////////////////////////////////////////////////////////
681/// Return a temporary inverse of this.
682
684{
686 h = *this;
688 Double_t tr[3];
689 tr[0] = -fTranslation[0];
690 tr[1] = -fTranslation[1];
691 tr[2] = -fTranslation[2];
692 h.SetTranslation(tr);
693 return h;
694}
695
696////////////////////////////////////////////////////////////////////////////////
697/// Adding a translation to this one
698
700{
701 const Double_t *trans = other->GetTranslation();
702 for (Int_t i = 0; i < 3; i++)
703 fTranslation[i] += trans[i];
704}
705
706////////////////////////////////////////////////////////////////////////////////
707/// Make a clone of this matrix.
708
710{
711 TGeoMatrix *matrix = new TGeoTranslation(*this);
712 return matrix;
713}
714
715////////////////////////////////////////////////////////////////////////////////
716/// Rotate about X axis of the master frame with angle expressed in degrees.
717
719{
720 Warning("RotateX", "Not implemented. Use TGeoCombiTrans instead");
721}
722
723////////////////////////////////////////////////////////////////////////////////
724/// Rotate about Y axis of the master frame with angle expressed in degrees.
725
727{
728 Warning("RotateY", "Not implemented. Use TGeoCombiTrans instead");
729}
730
731////////////////////////////////////////////////////////////////////////////////
732/// Rotate about Z axis of the master frame with angle expressed in degrees.
733
735{
736 Warning("RotateZ", "Not implemented. Use TGeoCombiTrans instead");
737}
738
739////////////////////////////////////////////////////////////////////////////////
740/// Subtracting a translation from this one
741
743{
744 const Double_t *trans = other->GetTranslation();
745 for (Int_t i = 0; i < 3; i++)
746 fTranslation[i] -= trans[i];
747}
748
749////////////////////////////////////////////////////////////////////////////////
750/// Set translation components
751
753{
754 fTranslation[0] = dx;
755 fTranslation[1] = dy;
756 fTranslation[2] = dz;
757 if (dx || dy || dz)
759 else
761}
762
763////////////////////////////////////////////////////////////////////////////////
764/// Set translation components
765
767{
769 const Double_t *transl = other.GetTranslation();
770 memcpy(fTranslation, transl, kN3);
771}
772
773////////////////////////////////////////////////////////////////////////////////
774/// convert a point by multiplying its column vector (x, y, z, 1) to matrix inverse
775
776void TGeoTranslation::LocalToMaster(const Double_t *local, Double_t *master) const
777{
778 const Double_t *tr = GetTranslation();
779 for (Int_t i = 0; i < 3; i++)
780 master[i] = tr[i] + local[i];
781}
782
783////////////////////////////////////////////////////////////////////////////////
784/// convert a vector to MARS
785
786void TGeoTranslation::LocalToMasterVect(const Double_t *local, Double_t *master) const
787{
788 memcpy(master, local, kN3);
789}
790
791////////////////////////////////////////////////////////////////////////////////
792/// convert a point by multiplying its column vector (x, y, z, 1) to matrix inverse
793
794void TGeoTranslation::LocalToMasterBomb(const Double_t *local, Double_t *master) const
795{
796 const Double_t *tr = GetTranslation();
797 Double_t bombtr[3] = {0., 0., 0.};
798 gGeoManager->BombTranslation(tr, &bombtr[0]);
799 for (Int_t i = 0; i < 3; i++)
800 master[i] = bombtr[i] + local[i];
801}
802
803////////////////////////////////////////////////////////////////////////////////
804/// convert a point by multiplying its column vector (x, y, z, 1) to matrix
805
806void TGeoTranslation::MasterToLocal(const Double_t *master, Double_t *local) const
807{
808 const Double_t *tr = GetTranslation();
809 for (Int_t i = 0; i < 3; i++)
810 local[i] = master[i] - tr[i];
811}
812
813////////////////////////////////////////////////////////////////////////////////
814/// convert a vector from MARS to local
815
816void TGeoTranslation::MasterToLocalVect(const Double_t *master, Double_t *local) const
817{
818 memcpy(local, master, kN3);
819}
820
821////////////////////////////////////////////////////////////////////////////////
822/// convert a point by multiplying its column vector (x, y, z, 1) to matrix
823
824void TGeoTranslation::MasterToLocalBomb(const Double_t *master, Double_t *local) const
825{
826 const Double_t *tr = GetTranslation();
827 Double_t bombtr[3] = {0., 0., 0.};
828 gGeoManager->UnbombTranslation(tr, &bombtr[0]);
829 for (Int_t i = 0; i < 3; i++)
830 local[i] = master[i] - bombtr[i];
831}
832
833////////////////////////////////////////////////////////////////////////////////
834/// Save a primitive as a C++ statement(s) on output stream "out".
835
836void TGeoTranslation::SavePrimitive(std::ostream &out, Option_t * /*option*/ /*= ""*/)
837{
839 return;
840 out << " // Translation: " << GetName() << std::endl;
841 out << " dx = " << fTranslation[0] << ";" << std::endl;
842 out << " dy = " << fTranslation[1] << ";" << std::endl;
843 out << " dz = " << fTranslation[2] << ";" << std::endl;
844 out << " TGeoTranslation *" << GetPointerName() << " = new TGeoTranslation(\"" << GetName() << "\",dx,dy,dz);"
845 << std::endl;
847}
848
849/** \class TGeoRotation
850\ingroup Geometry_classes
851Class describing rotations. A rotation is a 3*3 array
852Column vectors has to be orthogonal unit vectors.
853*/
854
856
857////////////////////////////////////////////////////////////////////////////////
858/// Default constructor.
859
861{
862 for (Int_t i = 0; i < 9; i++) {
863 if (i % 4)
864 fRotationMatrix[i] = 0;
865 else
866 fRotationMatrix[i] = 1.0;
867 }
868}
869
870////////////////////////////////////////////////////////////////////////////////
871/// Copy ctor.
872
874{
875 SetRotation(other);
876}
877
878////////////////////////////////////////////////////////////////////////////////
879/// Copy ctor.
880
882{
885 SetRotation(other);
886}
887
888////////////////////////////////////////////////////////////////////////////////
889/// Named rotation constructor
890
892{
893 for (Int_t i = 0; i < 9; i++) {
894 if (i % 4)
895 fRotationMatrix[i] = 0;
896 else
897 fRotationMatrix[i] = 1.0;
898 }
899}
900
901////////////////////////////////////////////////////////////////////////////////
902/// Default rotation constructor with Euler angles. Phi is the rotation angle about
903/// Z axis and is done first, theta is the rotation about new X and is done
904/// second, psi is the rotation angle about new Z and is done third. All angles are in
905/// degrees.
906
908{
909 SetAngles(phi, theta, psi);
910}
911
912////////////////////////////////////////////////////////////////////////////////
913/// Rotation constructor a la GEANT3. Angles theta(i), phi(i) are the polar and azimuthal
914/// angles of the (i) axis of the rotated system with respect to the initial non-rotated
915/// system.
916/// Example : the identity matrix (no rotation) is composed by
917/// theta1=90, phi1=0, theta2=90, phi2=90, theta3=0, phi3=0
918/// SetBit(kGeoRotation);
919
920TGeoRotation::TGeoRotation(const char *name, Double_t theta1, Double_t phi1, Double_t theta2, Double_t phi2,
921 Double_t theta3, Double_t phi3)
923{
924 SetAngles(theta1, phi1, theta2, phi2, theta3, phi3);
925}
926
927////////////////////////////////////////////////////////////////////////////////
928/// Assignment from a general matrix
929
931{
932 if (&other == this)
933 return *this;
934 Bool_t registered = TestBit(kGeoRegistered);
935 TNamed::operator=(other);
936 SetRotation(other);
937 SetBit(kGeoRegistered, registered);
940 return *this;
941}
942
943////////////////////////////////////////////////////////////////////////////////
944/// Composition
945
947{
948 if (!right.IsRotation())
949 return *this;
950 MultiplyBy(&right, true);
951 return *this;
952}
953
955{
956 TGeoRotation r = *this;
957 r *= right;
958 return r;
959}
960
962{
963 TGeoHMatrix t = *this;
964 t *= right;
965 return t;
966}
967
968////////////////////////////////////////////////////////////////////////////////
969/// Is-equal operator
970
972{
973 if (&other == this)
974 return kTRUE;
975 const Double_t *rot = GetRotationMatrix();
976 const Double_t *orot = other.GetRotationMatrix();
977 for (auto i = 0; i < 9; i++)
978 if (TMath::Abs(rot[i] - orot[i]) > 1.E-10)
979 return kFALSE;
980 return kTRUE;
981}
982
983////////////////////////////////////////////////////////////////////////////////
984/// Return a temporary inverse of this.
985
987{
989 h = *this;
991 Double_t newrot[9];
992 newrot[0] = fRotationMatrix[0];
993 newrot[1] = fRotationMatrix[3];
994 newrot[2] = fRotationMatrix[6];
995 newrot[3] = fRotationMatrix[1];
996 newrot[4] = fRotationMatrix[4];
997 newrot[5] = fRotationMatrix[7];
998 newrot[6] = fRotationMatrix[2];
999 newrot[7] = fRotationMatrix[5];
1000 newrot[8] = fRotationMatrix[8];
1001 h.SetRotation(newrot);
1002 return h;
1003}
1004
1005////////////////////////////////////////////////////////////////////////////////
1006/// Perform orthogonality test for rotation.
1007
1009{
1010 const Double_t *r = fRotationMatrix;
1011 Double_t cij;
1012 for (Int_t i = 0; i < 2; i++) {
1013 for (Int_t j = i + 1; j < 3; j++) {
1014 // check columns
1015 cij = TMath::Abs(r[i] * r[j] + r[i + 3] * r[j + 3] + r[i + 6] * r[j + 6]);
1016 if (cij > 1E-4)
1017 return kFALSE;
1018 // check rows
1019 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]);
1020 if (cij > 1E-4)
1021 return kFALSE;
1022 }
1023 }
1024 return kTRUE;
1025}
1026
1027////////////////////////////////////////////////////////////////////////////////
1028/// reset data members
1029
1031{
1034}
1035
1036////////////////////////////////////////////////////////////////////////////////
1037/// Perform a rotation about Z having the sine/cosine of the rotation angle.
1038
1040{
1041 fRotationMatrix[0] = sincos[1];
1042 fRotationMatrix[1] = -sincos[0];
1043 fRotationMatrix[3] = sincos[0];
1044 fRotationMatrix[4] = sincos[1];
1046}
1047
1048////////////////////////////////////////////////////////////////////////////////
1049/// Returns rotation angle about Z axis in degrees. If the rotation is a pure
1050/// rotation about Z, fixX parameter does not matter, otherwise its meaning is:
1051/// - fixX = true : result is the phi angle of the projection of the rotated X axis in the un-rotated XY
1052/// - fixX = false : result is the phi angle of the projection of the rotated Y axis - 90 degrees
1053
1055{
1056 Double_t phi;
1057 if (fixX)
1058 phi = 180. * TMath::ATan2(-fRotationMatrix[1], fRotationMatrix[4]) / TMath::Pi();
1059 else
1060 phi = 180. * TMath::ATan2(fRotationMatrix[3], fRotationMatrix[0]) / TMath::Pi();
1061 return phi;
1062}
1063
1064////////////////////////////////////////////////////////////////////////////////
1065/// convert a point by multiplying its column vector (x, y, z, 1) to matrix inverse
1066
1067void TGeoRotation::LocalToMaster(const Double_t *local, Double_t *master) const
1068{
1069 const Double_t *rot = GetRotationMatrix();
1070 for (Int_t i = 0; i < 3; i++) {
1071 master[i] = local[0] * rot[3 * i] + local[1] * rot[3 * i + 1] + local[2] * rot[3 * i + 2];
1072 }
1073}
1074
1075////////////////////////////////////////////////////////////////////////////////
1076/// convert a point by multiplying its column vector (x, y, z, 1) to matrix
1077
1078void TGeoRotation::MasterToLocal(const Double_t *master, Double_t *local) const
1079{
1080 const Double_t *rot = GetRotationMatrix();
1081 for (Int_t i = 0; i < 3; i++) {
1082 local[i] = master[0] * rot[i] + master[1] * rot[i + 3] + master[2] * rot[i + 6];
1083 }
1084}
1085
1086////////////////////////////////////////////////////////////////////////////////
1087/// Make a clone of this matrix.
1088
1090{
1091 TGeoMatrix *matrix = new TGeoRotation(*this);
1092 return matrix;
1093}
1094
1095////////////////////////////////////////////////////////////////////////////////
1096/// Rotate about X axis of the master frame with angle expressed in degrees.
1097
1099{
1101 Double_t phi = angle * TMath::DegToRad();
1102 Double_t c = TMath::Cos(phi);
1103 Double_t s = TMath::Sin(phi);
1104 Double_t v[9];
1105 v[0] = fRotationMatrix[0];
1106 v[1] = fRotationMatrix[1];
1107 v[2] = fRotationMatrix[2];
1108 v[3] = c * fRotationMatrix[3] - s * fRotationMatrix[6];
1109 v[4] = c * fRotationMatrix[4] - s * fRotationMatrix[7];
1110 v[5] = c * fRotationMatrix[5] - s * fRotationMatrix[8];
1111 v[6] = s * fRotationMatrix[3] + c * fRotationMatrix[6];
1112 v[7] = s * fRotationMatrix[4] + c * fRotationMatrix[7];
1113 v[8] = s * fRotationMatrix[5] + c * fRotationMatrix[8];
1114
1115 memcpy(fRotationMatrix, v, kN9);
1116}
1117
1118////////////////////////////////////////////////////////////////////////////////
1119/// Rotate about Y axis of the master frame with angle expressed in degrees.
1120
1122{
1124 Double_t phi = angle * TMath::DegToRad();
1125 Double_t c = TMath::Cos(phi);
1126 Double_t s = TMath::Sin(phi);
1127 Double_t v[9];
1128 v[0] = c * fRotationMatrix[0] + s * fRotationMatrix[6];
1129 v[1] = c * fRotationMatrix[1] + s * fRotationMatrix[7];
1130 v[2] = c * fRotationMatrix[2] + s * fRotationMatrix[8];
1131 v[3] = fRotationMatrix[3];
1132 v[4] = fRotationMatrix[4];
1133 v[5] = fRotationMatrix[5];
1134 v[6] = -s * fRotationMatrix[0] + c * fRotationMatrix[6];
1135 v[7] = -s * fRotationMatrix[1] + c * fRotationMatrix[7];
1136 v[8] = -s * fRotationMatrix[2] + c * fRotationMatrix[8];
1137
1138 memcpy(fRotationMatrix, v, kN9);
1139}
1140
1141////////////////////////////////////////////////////////////////////////////////
1142/// Rotate about Z axis of the master frame with angle expressed in degrees.
1143
1145{
1147 Double_t phi = angle * TMath::DegToRad();
1148 Double_t c = TMath::Cos(phi);
1149 Double_t s = TMath::Sin(phi);
1150 Double_t v[9];
1151 v[0] = c * fRotationMatrix[0] - s * fRotationMatrix[3];
1152 v[1] = c * fRotationMatrix[1] - s * fRotationMatrix[4];
1153 v[2] = c * fRotationMatrix[2] - s * fRotationMatrix[5];
1154 v[3] = s * fRotationMatrix[0] + c * fRotationMatrix[3];
1155 v[4] = s * fRotationMatrix[1] + c * fRotationMatrix[4];
1156 v[5] = s * fRotationMatrix[2] + c * fRotationMatrix[5];
1157 v[6] = fRotationMatrix[6];
1158 v[7] = fRotationMatrix[7];
1159 v[8] = fRotationMatrix[8];
1160
1161 memcpy(&fRotationMatrix[0], v, kN9);
1162}
1163
1164////////////////////////////////////////////////////////////////////////////////
1165/// Multiply by a reflection respect to YZ.
1166
1168{
1169 if (leftside) {
1173 } else {
1177 }
1180}
1181
1182////////////////////////////////////////////////////////////////////////////////
1183/// Multiply by a reflection respect to ZX.
1184
1186{
1187 if (leftside) {
1191 } else {
1195 }
1198}
1199
1200////////////////////////////////////////////////////////////////////////////////
1201/// Multiply by a reflection respect to XY.
1202
1204{
1205 if (leftside) {
1209 } else {
1213 }
1216}
1217
1218////////////////////////////////////////////////////////////////////////////////
1219/// Save a primitive as a C++ statement(s) on output stream "out".
1220
1221void TGeoRotation::SavePrimitive(std::ostream &out, Option_t * /*option*/ /*= ""*/)
1222{
1224 return;
1225 out << " // Rotation: " << GetName() << std::endl;
1226 Double_t th1, ph1, th2, ph2, th3, ph3;
1227 GetAngles(th1, ph1, th2, ph2, th3, ph3);
1228 out << " thx = " << th1 << "; phx = " << ph1 << ";" << std::endl;
1229 out << " thy = " << th2 << "; phy = " << ph2 << ";" << std::endl;
1230 out << " thz = " << th3 << "; phz = " << ph3 << ";" << std::endl;
1231 out << " TGeoRotation *" << GetPointerName() << " = new TGeoRotation(\"" << GetName()
1232 << "\",thx,phx,thy,phy,thz,phz);" << std::endl;
1234}
1235
1236////////////////////////////////////////////////////////////////////////////////
1237/// Copy rotation elements from other rotation matrix.
1238
1240{
1241 SetBit(kGeoRotation, other.IsRotation());
1243}
1244
1245////////////////////////////////////////////////////////////////////////////////
1246/// Set matrix elements according to Euler angles. Phi is the rotation angle about
1247/// Z axis and is done first, theta is the rotation about new X and is done
1248/// second, psi is the rotation angle about new Z and is done third. All angles are in
1249/// degrees.
1250
1252{
1253 Double_t degrad = TMath::Pi() / 180.;
1254 Double_t sinphi = TMath::Sin(degrad * phi);
1255 Double_t cosphi = TMath::Cos(degrad * phi);
1256 Double_t sinthe = TMath::Sin(degrad * theta);
1257 Double_t costhe = TMath::Cos(degrad * theta);
1258 Double_t sinpsi = TMath::Sin(degrad * psi);
1259 Double_t cospsi = TMath::Cos(degrad * psi);
1260
1261 fRotationMatrix[0] = cospsi * cosphi - costhe * sinphi * sinpsi;
1262 fRotationMatrix[1] = -sinpsi * cosphi - costhe * sinphi * cospsi;
1263 fRotationMatrix[2] = sinthe * sinphi;
1264 fRotationMatrix[3] = cospsi * sinphi + costhe * cosphi * sinpsi;
1265 fRotationMatrix[4] = -sinpsi * sinphi + costhe * cosphi * cospsi;
1266 fRotationMatrix[5] = -sinthe * cosphi;
1267 fRotationMatrix[6] = sinpsi * sinthe;
1268 fRotationMatrix[7] = cospsi * sinthe;
1269 fRotationMatrix[8] = costhe;
1270
1271 if (!IsValid())
1272 Error("SetAngles", "invalid rotation (Euler angles : phi=%f theta=%f psi=%f)", phi, theta, psi);
1273 CheckMatrix();
1274}
1275
1276////////////////////////////////////////////////////////////////////////////////
1277/// Set matrix elements in the GEANT3 way
1278
1279void TGeoRotation::SetAngles(Double_t theta1, Double_t phi1, Double_t theta2, Double_t phi2, Double_t theta3,
1280 Double_t phi3)
1281{
1282 Double_t degrad = TMath::Pi() / 180.;
1283 fRotationMatrix[0] = TMath::Cos(degrad * phi1) * TMath::Sin(degrad * theta1);
1284 fRotationMatrix[3] = TMath::Sin(degrad * phi1) * TMath::Sin(degrad * theta1);
1285 fRotationMatrix[6] = TMath::Cos(degrad * theta1);
1286 fRotationMatrix[1] = TMath::Cos(degrad * phi2) * TMath::Sin(degrad * theta2);
1287 fRotationMatrix[4] = TMath::Sin(degrad * phi2) * TMath::Sin(degrad * theta2);
1288 fRotationMatrix[7] = TMath::Cos(degrad * theta2);
1289 fRotationMatrix[2] = TMath::Cos(degrad * phi3) * TMath::Sin(degrad * theta3);
1290 fRotationMatrix[5] = TMath::Sin(degrad * phi3) * TMath::Sin(degrad * theta3);
1291 fRotationMatrix[8] = TMath::Cos(degrad * theta3);
1292 // do the trick to eliminate most of the floating point errors
1293 for (Int_t i = 0; i < 9; i++) {
1294 if (TMath::Abs(fRotationMatrix[i]) < 1E-15)
1295 fRotationMatrix[i] = 0;
1296 if (TMath::Abs(fRotationMatrix[i] - 1) < 1E-15)
1297 fRotationMatrix[i] = 1;
1298 if (TMath::Abs(fRotationMatrix[i] + 1) < 1E-15)
1299 fRotationMatrix[i] = -1;
1300 }
1301 if (!IsValid())
1302 Error("SetAngles", "invalid rotation (G3 angles, th1=%f phi1=%f, th2=%f ph2=%f, th3=%f phi3=%f)", theta1, phi1,
1303 theta2, phi2, theta3, phi3);
1304 CheckMatrix();
1305}
1306
1307////////////////////////////////////////////////////////////////////////////////
1308/// Retrieve rotation angles
1309
1310void TGeoRotation::GetAngles(Double_t &theta1, Double_t &phi1, Double_t &theta2, Double_t &phi2, Double_t &theta3,
1311 Double_t &phi3) const
1312{
1313 Double_t raddeg = 180. / TMath::Pi();
1314 theta1 = raddeg * TMath::ACos(fRotationMatrix[6]);
1315 theta2 = raddeg * TMath::ACos(fRotationMatrix[7]);
1316 theta3 = raddeg * TMath::ACos(fRotationMatrix[8]);
1317 if (TMath::Abs(fRotationMatrix[0]) < 1E-6 && TMath::Abs(fRotationMatrix[3]) < 1E-6)
1318 phi1 = 0.;
1319 else
1320 phi1 = raddeg * TMath::ATan2(fRotationMatrix[3], fRotationMatrix[0]);
1321 if (phi1 < 0)
1322 phi1 += 360.;
1323 if (TMath::Abs(fRotationMatrix[1]) < 1E-6 && TMath::Abs(fRotationMatrix[4]) < 1E-6)
1324 phi2 = 0.;
1325 else
1326 phi2 = raddeg * TMath::ATan2(fRotationMatrix[4], fRotationMatrix[1]);
1327 if (phi2 < 0)
1328 phi2 += 360.;
1329 if (TMath::Abs(fRotationMatrix[2]) < 1E-6 && TMath::Abs(fRotationMatrix[5]) < 1E-6)
1330 phi3 = 0.;
1331 else
1332 phi3 = raddeg * TMath::ATan2(fRotationMatrix[5], fRotationMatrix[2]);
1333 if (phi3 < 0)
1334 phi3 += 360.;
1335}
1336
1337////////////////////////////////////////////////////////////////////////////////
1338/// Retrieve Euler angles.
1339
1341{
1342 const Double_t *m = fRotationMatrix;
1343 // Check if theta is 0 or 180.
1344 if (TMath::Abs(1. - TMath::Abs(m[8])) < 1.e-9) {
1345 theta = TMath::ACos(m[8]) * TMath::RadToDeg();
1346 phi = TMath::ATan2(-m[8] * m[1], m[0]) * TMath::RadToDeg();
1347 psi = 0.; // convention, phi+psi matters
1348 return;
1349 }
1350 // sin(theta) != 0
1351 phi = TMath::ATan2(m[2], -m[5]);
1352 Double_t sphi = TMath::Sin(phi);
1353 if (TMath::Abs(sphi) < 1.e-9)
1354 theta = -TMath::ASin(m[5] / TMath::Cos(phi)) * TMath::RadToDeg();
1355 else
1356 theta = TMath::ASin(m[2] / sphi) * TMath::RadToDeg();
1357 phi *= TMath::RadToDeg();
1358 psi = TMath::ATan2(m[6], m[7]) * TMath::RadToDeg();
1359}
1360
1361////////////////////////////////////////////////////////////////////////////////
1362/// computes determinant of the rotation matrix
1363
1365{
1372 return det;
1373}
1374
1375////////////////////////////////////////////////////////////////////////////////
1376/// performes an orthogonality check and finds if the matrix is a reflection
1377/// Warning("CheckMatrix", "orthogonality check not performed yet");
1378
1380{
1381 if (Determinant() < 0)
1384 if (TMath::Abs(dd) < 1.E-12)
1386 else
1388}
1389
1390////////////////////////////////////////////////////////////////////////////////
1391/// Get the inverse rotation matrix (which is simply the transpose)
1392
1394{
1395 if (!invmat) {
1396 Error("GetInverse", "no place to store the inverse matrix");
1397 return;
1398 }
1399 for (Int_t i = 0; i < 3; i++) {
1400 for (Int_t j = 0; j < 3; j++) {
1401 invmat[3 * i + j] = fRotationMatrix[3 * j + i];
1402 }
1403 }
1404}
1405
1406////////////////////////////////////////////////////////////////////////////////
1407/// Multiply this rotation with the one specified by ROT.
1408/// - after=TRUE (default): THIS*ROT
1409/// - after=FALSE : ROT*THIS
1410
1412{
1413 const Double_t *matleft, *matright;
1415 Double_t newmat[9] = {0};
1416 if (after) {
1417 matleft = &fRotationMatrix[0];
1418 matright = rot->GetRotationMatrix();
1419 } else {
1420 matleft = rot->GetRotationMatrix();
1421 matright = &fRotationMatrix[0];
1422 }
1423 for (Int_t i = 0; i < 3; i++) {
1424 for (Int_t j = 0; j < 3; j++) {
1425 for (Int_t k = 0; k < 3; k++) {
1426 newmat[3 * i + j] += matleft[3 * i + k] * matright[3 * k + j];
1427 }
1428 }
1429 }
1430 memcpy(&fRotationMatrix[0], &newmat[0], kN9);
1431}
1432
1433/** \class TGeoScale
1434\ingroup Geometry_classes
1435Class describing scale transformations. A scale is an
1436array of 3 doubles (sx, sy, sz) multiplying elements 0, 5 and 10
1437of the homogenous matrix. A scale is normalized : sx*sy*sz = 1
1438*/
1439
1441
1442////////////////////////////////////////////////////////////////////////////////
1443/// default constructor
1444
1446{
1448 for (Int_t i = 0; i < 3; i++)
1449 fScale[i] = 1.;
1450}
1451
1452////////////////////////////////////////////////////////////////////////////////
1453/// Copy constructor
1454
1456{
1457 SetScale(other);
1458}
1459
1460////////////////////////////////////////////////////////////////////////////////
1461/// Ctor. based on a general matrix
1462
1464{
1467 SetScale(other);
1468}
1469
1470////////////////////////////////////////////////////////////////////////////////
1471/// default constructor
1472
1474{
1476 SetScale(sx, sy, sz);
1477}
1478
1479////////////////////////////////////////////////////////////////////////////////
1480/// default constructor
1481
1483{
1485 SetScale(sx, sy, sz);
1486}
1487
1488////////////////////////////////////////////////////////////////////////////////
1489/// destructor
1490
1492
1493////////////////////////////////////////////////////////////////////////////////
1494/// Assignment from a general matrix
1495
1497{
1498 if (&matrix == this)
1499 return *this;
1500 Bool_t registered = TestBit(kGeoRegistered);
1501 TNamed::operator=(matrix);
1502 SetScale(matrix);
1503 SetBit(kGeoRegistered, registered);
1506 return *this;
1507}
1508
1509////////////////////////////////////////////////////////////////////////////////
1510/// Scale composition
1511
1513{
1514 const Double_t *scl = right.GetScale();
1515 fScale[0] *= scl[0];
1516 fScale[1] *= scl[1];
1517 fScale[2] *= scl[2];
1518 SetBit(kGeoReflection, fScale[0] * fScale[1] * fScale[2] < 0);
1519 if (!IsScale())
1520 SetBit(kGeoScale, right.IsScale());
1521 return *this;
1522}
1523
1525{
1526 TGeoScale s = *this;
1527 s *= right;
1528 return s;
1529}
1530
1532{
1533 TGeoHMatrix t = *this;
1534 t *= right;
1535 return t;
1536}
1537
1538////////////////////////////////////////////////////////////////////////////////
1539/// Is-equal operator
1540
1542{
1543 if (&other == this)
1544 return kTRUE;
1545 const Double_t *scl = GetScale();
1546 const Double_t *oscl = other.GetScale();
1547 for (auto i = 0; i < 3; i++)
1548 if (TMath::Abs(scl[i] - oscl[i]) > 1.E-10)
1549 return kFALSE;
1550 return kTRUE;
1551}
1552
1553////////////////////////////////////////////////////////////////////////////////
1554/// Return a temporary inverse of this.
1555
1557{
1558 TGeoHMatrix h;
1559 h = *this;
1561 Double_t scale[3];
1562 scale[0] = 1. / fScale[0];
1563 scale[1] = 1. / fScale[1];
1564 scale[2] = 1. / fScale[2];
1565 h.SetScale(scale);
1566 return h;
1567}
1568
1569////////////////////////////////////////////////////////////////////////////////
1570/// scale setter
1571
1573{
1574 if (TMath::Abs(sx * sy * sz) < 1.E-10) {
1575 Error("SetScale", "Invalid scale %f, %f, %f for transformation %s", sx, sy, sx, GetName());
1576 return;
1577 }
1578 fScale[0] = sx;
1579 fScale[1] = sy;
1580 fScale[2] = sz;
1581 if (sx * sy * sz < 0)
1583 else
1585}
1586
1587////////////////////////////////////////////////////////////////////////////////
1588/// Set scale from other transformation
1589
1591{
1592 SetBit(kGeoScale, other.IsScale());
1594 memcpy(fScale, other.GetScale(), kN3);
1595}
1596
1597////////////////////////////////////////////////////////////////////////////////
1598/// Convert a local point to the master frame.
1599
1600void TGeoScale::LocalToMaster(const Double_t *local, Double_t *master) const
1601{
1602 master[0] = local[0] * fScale[0];
1603 master[1] = local[1] * fScale[1];
1604 master[2] = local[2] * fScale[2];
1605}
1606
1607////////////////////////////////////////////////////////////////////////////////
1608/// Convert the local distance along unit vector DIR to master frame. If DIR
1609/// is not specified perform a conversion such as the returned distance is the
1610/// the minimum for all possible directions.
1611
1613{
1614 Double_t scale;
1615 if (!dir) {
1616 scale = TMath::Abs(fScale[0]);
1617 if (TMath::Abs(fScale[1]) < scale)
1618 scale = TMath::Abs(fScale[1]);
1619 if (TMath::Abs(fScale[2]) < scale)
1620 scale = TMath::Abs(fScale[2]);
1621 } else {
1622 scale = fScale[0] * fScale[0] * dir[0] * dir[0] + fScale[1] * fScale[1] * dir[1] * dir[1] +
1623 fScale[2] * fScale[2] * dir[2] * dir[2];
1624 scale = TMath::Sqrt(scale);
1625 }
1626 return scale * dist;
1627}
1628
1629////////////////////////////////////////////////////////////////////////////////
1630/// Make a clone of this matrix.
1631
1633{
1634 TGeoMatrix *matrix = new TGeoScale(*this);
1635 return matrix;
1636}
1637
1638////////////////////////////////////////////////////////////////////////////////
1639/// Convert a global point to local frame.
1640
1641void TGeoScale::MasterToLocal(const Double_t *master, Double_t *local) const
1642{
1643 local[0] = master[0] / fScale[0];
1644 local[1] = master[1] / fScale[1];
1645 local[2] = master[2] / fScale[2];
1646}
1647
1648////////////////////////////////////////////////////////////////////////////////
1649/// Convert the distance along unit vector DIR to local frame. If DIR
1650/// is not specified perform a conversion such as the returned distance is the
1651/// the minimum for all possible directions.
1652
1654{
1655 Double_t scale;
1656 if (!dir) {
1657 scale = TMath::Abs(fScale[0]);
1658 if (TMath::Abs(fScale[1]) > scale)
1659 scale = TMath::Abs(fScale[1]);
1660 if (TMath::Abs(fScale[2]) > scale)
1661 scale = TMath::Abs(fScale[2]);
1662 scale = 1. / scale;
1663 } else {
1664 scale = (dir[0] * dir[0]) / (fScale[0] * fScale[0]) + (dir[1] * dir[1]) / (fScale[1] * fScale[1]) +
1665 (dir[2] * dir[2]) / (fScale[2] * fScale[2]);
1666 scale = TMath::Sqrt(scale);
1667 }
1668 return scale * dist;
1669}
1670
1671/** \class TGeoCombiTrans
1672\ingroup Geometry_classes
1673Class describing rotation + translation. Most frequently used in the description
1674of TGeoNode 's
1675*/
1676
1678
1679////////////////////////////////////////////////////////////////////////////////
1680/// dummy ctor
1681
1683{
1684 for (Int_t i = 0; i < 3; i++)
1685 fTranslation[i] = 0.0;
1686 fRotation = nullptr;
1687}
1688
1689////////////////////////////////////////////////////////////////////////////////
1690/// Copy ctor from generic matrix.
1691
1693{
1695 if (other.IsTranslation()) {
1697 memcpy(fTranslation, other.GetTranslation(), kN3);
1698 } else {
1699 for (Int_t i = 0; i < 3; i++)
1700 fTranslation[i] = 0.0;
1701 }
1702 if (other.IsRotation()) {
1705 fRotation = new TGeoRotation(other);
1706 } else
1707 fRotation = nullptr;
1708}
1709
1710////////////////////////////////////////////////////////////////////////////////
1711/// Constructor from a translation and a rotation.
1712
1714{
1715 if (tr.IsTranslation()) {
1717 const Double_t *trans = tr.GetTranslation();
1718 memcpy(fTranslation, trans, kN3);
1719 } else {
1720 for (Int_t i = 0; i < 3; i++)
1721 fTranslation[i] = 0.0;
1722 }
1723 if (rot.IsRotation()) {
1726 fRotation = new TGeoRotation(rot);
1728 } else
1729 fRotation = nullptr;
1730}
1731
1732////////////////////////////////////////////////////////////////////////////////
1733/// Named ctor.
1734
1736{
1737 for (Int_t i = 0; i < 3; i++)
1738 fTranslation[i] = 0.0;
1739 fRotation = nullptr;
1740}
1741
1742////////////////////////////////////////////////////////////////////////////////
1743/// Constructor from a translation specified by X,Y,Z and a pointer to a rotation. The rotation will not be owned by
1744/// this.
1745
1747{
1748 SetTranslation(dx, dy, dz);
1749 fRotation = nullptr;
1750 SetRotation(rot);
1751}
1752
1753////////////////////////////////////////////////////////////////////////////////
1754/// Named ctor
1755
1757 : TGeoMatrix(name)
1758{
1759 SetTranslation(dx, dy, dz);
1760 fRotation = nullptr;
1761 SetRotation(rot);
1762}
1763
1764////////////////////////////////////////////////////////////////////////////////
1765/// Assignment operator with generic matrix.
1766
1768{
1769 if (&matrix == this)
1770 return *this;
1771 Bool_t registered = TestBit(kGeoRegistered);
1772 Clear();
1773 TNamed::operator=(matrix);
1774
1775 if (matrix.IsTranslation()) {
1776 memcpy(fTranslation, matrix.GetTranslation(), kN3);
1777 }
1778 if (matrix.IsRotation()) {
1779 if (!fRotation) {
1780 fRotation = new TGeoRotation();
1782 } else {
1783 if (!TestBit(kGeoMatrixOwned)) {
1784 fRotation = new TGeoRotation();
1786 }
1787 }
1791 } else {
1793 delete fRotation;
1795 fRotation = nullptr;
1796 }
1797 SetBit(kGeoRegistered, registered);
1799 return *this;
1800}
1801
1802////////////////////////////////////////////////////////////////////////////////
1803/// Is-equal operator
1804
1806{
1807 if (&other == this)
1808 return kTRUE;
1809 const Double_t *tr = GetTranslation();
1810 const Double_t *otr = other.GetTranslation();
1811 for (auto i = 0; i < 3; i++)
1812 if (TMath::Abs(tr[i] - otr[i]) > 1.E-10)
1813 return kFALSE;
1814 const Double_t *rot = GetRotationMatrix();
1815 const Double_t *orot = other.GetRotationMatrix();
1816 for (auto i = 0; i < 9; i++)
1817 if (TMath::Abs(rot[i] - orot[i]) > 1.E-10)
1818 return kFALSE;
1819 return kTRUE;
1820}
1821
1822////////////////////////////////////////////////////////////////////////////////
1823/// Composition
1824
1826{
1827 Multiply(&right);
1828 return *this;
1829}
1830
1832{
1833 TGeoHMatrix h = *this;
1834 h *= right;
1835 return h;
1836}
1837
1838////////////////////////////////////////////////////////////////////////////////
1839/// destructor
1840
1842{
1843 if (fRotation) {
1845 delete fRotation;
1846 }
1847}
1848
1849////////////////////////////////////////////////////////////////////////////////
1850/// Reset translation/rotation to identity
1851
1853{
1854 if (IsTranslation()) {
1856 memset(fTranslation, 0, kN3);
1857 }
1858 if (fRotation) {
1860 delete fRotation;
1861 fRotation = nullptr;
1862 }
1866}
1867
1868////////////////////////////////////////////////////////////////////////////////
1869/// Return a temporary inverse of this.
1870
1872{
1873 TGeoHMatrix h;
1874 h = *this;
1876 Bool_t is_tr = IsTranslation();
1877 Bool_t is_rot = IsRotation();
1878 Double_t tr[3];
1879 Double_t newrot[9];
1880 const Double_t *rot = GetRotationMatrix();
1881 tr[0] = -fTranslation[0] * rot[0] - fTranslation[1] * rot[3] - fTranslation[2] * rot[6];
1882 tr[1] = -fTranslation[0] * rot[1] - fTranslation[1] * rot[4] - fTranslation[2] * rot[7];
1883 tr[2] = -fTranslation[0] * rot[2] - fTranslation[1] * rot[5] - fTranslation[2] * rot[8];
1884 h.SetTranslation(tr);
1885 newrot[0] = rot[0];
1886 newrot[1] = rot[3];
1887 newrot[2] = rot[6];
1888 newrot[3] = rot[1];
1889 newrot[4] = rot[4];
1890 newrot[5] = rot[7];
1891 newrot[6] = rot[2];
1892 newrot[7] = rot[5];
1893 newrot[8] = rot[8];
1894 h.SetRotation(newrot);
1895 h.SetBit(kGeoTranslation, is_tr);
1896 h.SetBit(kGeoRotation, is_rot);
1897 return h;
1898}
1899
1900////////////////////////////////////////////////////////////////////////////////
1901/// Make a clone of this matrix.
1902
1904{
1905 TGeoMatrix *matrix = new TGeoCombiTrans(*this);
1906 return matrix;
1907}
1908
1909////////////////////////////////////////////////////////////////////////////////
1910/// multiply to the right with an other transformation
1911/// if right is identity matrix, just return
1912
1914{
1915 if (right->IsIdentity())
1916 return;
1917 TGeoHMatrix h = *this;
1918 h.Multiply(right);
1919 operator=(h);
1920}
1921
1922////////////////////////////////////////////////////////////////////////////////
1923/// Register the matrix in the current manager, which will become the owner.
1924
1926{
1928 if (fRotation && fRotation->IsRotation())
1930}
1931
1932////////////////////////////////////////////////////////////////////////////////
1933/// Rotate about X axis with angle expressed in degrees.
1934
1936{
1937 if (!fRotation || !TestBit(kGeoMatrixOwned)) {
1938 if (fRotation)
1940 else
1941 fRotation = new TGeoRotation();
1943 }
1945 const Double_t *rot = fRotation->GetRotationMatrix();
1946 Double_t phi = angle * TMath::DegToRad();
1947 Double_t c = TMath::Cos(phi);
1948 Double_t s = TMath::Sin(phi);
1949 Double_t v[9];
1950 v[0] = rot[0];
1951 v[1] = rot[1];
1952 v[2] = rot[2];
1953 v[3] = c * rot[3] - s * rot[6];
1954 v[4] = c * rot[4] - s * rot[7];
1955 v[5] = c * rot[5] - s * rot[8];
1956 v[6] = s * rot[3] + c * rot[6];
1957 v[7] = s * rot[4] + c * rot[7];
1958 v[8] = s * rot[5] + c * rot[8];
1961 if (!IsTranslation())
1962 return;
1963 v[0] = fTranslation[0];
1964 v[1] = c * fTranslation[1] - s * fTranslation[2];
1965 v[2] = s * fTranslation[1] + c * fTranslation[2];
1966 memcpy(fTranslation, v, kN3);
1967}
1968
1969////////////////////////////////////////////////////////////////////////////////
1970/// Rotate about Y axis with angle expressed in degrees.
1971
1973{
1974 if (!fRotation || !TestBit(kGeoMatrixOwned)) {
1975 if (fRotation)
1977 else
1978 fRotation = new TGeoRotation();
1980 }
1982 const Double_t *rot = fRotation->GetRotationMatrix();
1983 Double_t phi = angle * TMath::DegToRad();
1984 Double_t c = TMath::Cos(phi);
1985 Double_t s = TMath::Sin(phi);
1986 Double_t v[9];
1987 v[0] = c * rot[0] + s * rot[6];
1988 v[1] = c * rot[1] + s * rot[7];
1989 v[2] = c * rot[2] + s * rot[8];
1990 v[3] = rot[3];
1991 v[4] = rot[4];
1992 v[5] = rot[5];
1993 v[6] = -s * rot[0] + c * rot[6];
1994 v[7] = -s * rot[1] + c * rot[7];
1995 v[8] = -s * rot[2] + c * rot[8];
1998 if (!IsTranslation())
1999 return;
2000 v[0] = c * fTranslation[0] + s * fTranslation[2];
2001 v[1] = fTranslation[1];
2002 v[2] = -s * fTranslation[0] + c * fTranslation[2];
2003 memcpy(fTranslation, v, kN3);
2004}
2005
2006////////////////////////////////////////////////////////////////////////////////
2007/// Rotate about Z axis with angle expressed in degrees.
2008
2010{
2011 if (!fRotation || !TestBit(kGeoMatrixOwned)) {
2012 if (fRotation)
2014 else
2015 fRotation = new TGeoRotation();
2017 }
2019 const Double_t *rot = fRotation->GetRotationMatrix();
2020 Double_t phi = angle * TMath::DegToRad();
2021 Double_t c = TMath::Cos(phi);
2022 Double_t s = TMath::Sin(phi);
2023 Double_t v[9];
2024 v[0] = c * rot[0] - s * rot[3];
2025 v[1] = c * rot[1] - s * rot[4];
2026 v[2] = c * rot[2] - s * rot[5];
2027 v[3] = s * rot[0] + c * rot[3];
2028 v[4] = s * rot[1] + c * rot[4];
2029 v[5] = s * rot[2] + c * rot[5];
2030 v[6] = rot[6];
2031 v[7] = rot[7];
2032 v[8] = rot[8];
2035 if (!IsTranslation())
2036 return;
2037 v[0] = c * fTranslation[0] - s * fTranslation[1];
2038 v[1] = s * fTranslation[0] + c * fTranslation[1];
2039 v[2] = fTranslation[2];
2040 memcpy(fTranslation, v, kN3);
2041}
2042
2043////////////////////////////////////////////////////////////////////////////////
2044/// Multiply by a reflection respect to YZ.
2045
2047{
2048 if (leftside && !rotonly)
2049 fTranslation[0] = -fTranslation[0];
2050 if (!fRotation || !TestBit(kGeoMatrixOwned)) {
2051 if (fRotation)
2053 else
2054 fRotation = new TGeoRotation();
2056 }
2058 fRotation->ReflectX(leftside);
2060}
2061
2062////////////////////////////////////////////////////////////////////////////////
2063/// Multiply by a reflection respect to ZX.
2064
2066{
2067 if (leftside && !rotonly)
2068 fTranslation[1] = -fTranslation[1];
2069 if (!fRotation || !TestBit(kGeoMatrixOwned)) {
2070 if (fRotation)
2072 else
2073 fRotation = new TGeoRotation();
2075 }
2077 fRotation->ReflectY(leftside);
2079}
2080
2081////////////////////////////////////////////////////////////////////////////////
2082/// Multiply by a reflection respect to XY.
2083
2085{
2086 if (leftside && !rotonly)
2087 fTranslation[2] = -fTranslation[2];
2088 if (!fRotation || !TestBit(kGeoMatrixOwned)) {
2089 if (fRotation)
2091 else
2092 fRotation = new TGeoRotation();
2094 }
2096 fRotation->ReflectZ(leftside);
2098}
2099
2100////////////////////////////////////////////////////////////////////////////////
2101/// Save a primitive as a C++ statement(s) on output stream "out".
2102
2103void TGeoCombiTrans::SavePrimitive(std::ostream &out, Option_t *option /*= ""*/)
2104{
2106 return;
2107 out << " // Combi transformation: " << GetName() << std::endl;
2108 out << " dx = " << fTranslation[0] << ";" << std::endl;
2109 out << " dy = " << fTranslation[1] << ";" << std::endl;
2110 out << " dz = " << fTranslation[2] << ";" << std::endl;
2111 if (fRotation && fRotation->IsRotation()) {
2113 out << " auto " << GetPointerName() << " = new TGeoCombiTrans(\"" << GetName() << "\", dx, dy, dz, "
2114 << fRotation->GetPointerName() << ");" << std::endl;
2115 } else {
2116 out << " auto " << GetPointerName() << " = new TGeoCombiTrans(\"" << GetName() << "\");" << std::endl;
2117 out << " " << GetPointerName() << "->SetTranslation(dx, dy, dz);" << std::endl;
2118 }
2120}
2121
2122////////////////////////////////////////////////////////////////////////////////
2123/// Assign a foreign rotation to the combi. The rotation is NOT owned by this.
2124
2126{
2128 delete fRotation;
2129 fRotation = nullptr;
2133 if (!rot)
2134 return;
2135 if (!rot->IsRotation())
2136 return;
2137
2140 TGeoRotation *rr = (TGeoRotation *)rot;
2141 fRotation = rr;
2142}
2143
2144////////////////////////////////////////////////////////////////////////////////
2145/// Copy the rotation from another one.
2146
2148{
2150 delete fRotation;
2151 fRotation = nullptr;
2152 if (!rot.IsRotation()) {
2156 return;
2157 }
2158
2161 fRotation = new TGeoRotation(rot);
2163}
2164
2165////////////////////////////////////////////////////////////////////////////////
2166/// copy the translation component
2167
2169{
2170 if (tr.IsTranslation()) {
2172 const Double_t *trans = tr.GetTranslation();
2173 memcpy(fTranslation, trans, kN3);
2174 } else {
2175 if (!IsTranslation())
2176 return;
2177 memset(fTranslation, 0, kN3);
2179 }
2180}
2181
2182////////////////////////////////////////////////////////////////////////////////
2183/// set the translation component
2184
2186{
2187 fTranslation[0] = dx;
2188 fTranslation[1] = dy;
2189 fTranslation[2] = dz;
2190 if (fTranslation[0] || fTranslation[1] || fTranslation[2])
2192 else
2194}
2195
2196////////////////////////////////////////////////////////////////////////////////
2197/// set the translation component
2198
2200{
2201 fTranslation[0] = vect[0];
2202 fTranslation[1] = vect[1];
2203 fTranslation[2] = vect[2];
2204 if (fTranslation[0] || fTranslation[1] || fTranslation[2])
2206 else
2208}
2209
2210////////////////////////////////////////////////////////////////////////////////
2211/// get the rotation array
2212
2214{
2215 if (!fRotation)
2216 return kIdentityMatrix;
2217 return fRotation->GetRotationMatrix();
2218}
2219
2220/** \class TGeoGenTrans
2221\ingroup Geometry_classes
2222Most general transformation, holding a translation, a rotation and a scale
2223*/
2224
2226
2227////////////////////////////////////////////////////////////////////////////////
2228/// dummy ctor
2229
2231{
2233 for (Int_t i = 0; i < 3; i++)
2234 fTranslation[i] = 0.0;
2235 for (Int_t j = 0; j < 3; j++)
2236 fScale[j] = 1.0;
2237 fRotation = nullptr;
2238}
2239
2240////////////////////////////////////////////////////////////////////////////////
2241/// constructor
2242
2244{
2246 for (Int_t i = 0; i < 3; i++)
2247 fTranslation[i] = 0.0;
2248 for (Int_t j = 0; j < 3; j++)
2249 fScale[j] = 1.0;
2250 fRotation = nullptr;
2251}
2252
2253////////////////////////////////////////////////////////////////////////////////
2254/// constructor
2255
2257 TGeoRotation *rot)
2258 : TGeoCombiTrans("")
2259{
2261 SetTranslation(dx, dy, dz);
2262 SetScale(sx, sy, sz);
2263 SetRotation(rot);
2264}
2265
2266////////////////////////////////////////////////////////////////////////////////
2267/// constructor
2268
2270 Double_t sz, TGeoRotation *rot)
2272{
2274 SetTranslation(dx, dy, dz);
2275 SetScale(sx, sy, sz);
2276 SetRotation(rot);
2277}
2278
2279////////////////////////////////////////////////////////////////////////////////
2280/// destructor
2281
2283
2284////////////////////////////////////////////////////////////////////////////////
2285/// clear the fields of this transformation
2286
2288{
2289 memset(&fTranslation[0], 0, kN3);
2290 memset(&fScale[0], 0, kN3);
2291 if (fRotation)
2292 fRotation->Clear();
2293}
2294
2295////////////////////////////////////////////////////////////////////////////////
2296/// set the scale
2297
2299{
2300 if (sx < 1.E-5 || sy < 1.E-5 || sz < 1.E-5) {
2301 Error("ctor", "Invalid scale");
2302 return;
2303 }
2304 fScale[0] = sx;
2305 fScale[1] = sy;
2306 fScale[2] = sz;
2307}
2308
2309////////////////////////////////////////////////////////////////////////////////
2310/// Return a temporary inverse of this.
2311
2313{
2314 TGeoHMatrix h = *this;
2316 return h;
2317}
2318
2319////////////////////////////////////////////////////////////////////////////////
2320/// A scale transformation should be normalized by sx*sy*sz factor
2321
2323{
2324 Double_t normfactor = fScale[0] * fScale[1] * fScale[2];
2325 if (normfactor <= 1E-5)
2326 return kFALSE;
2327 for (Int_t i = 0; i < 3; i++)
2328 fScale[i] /= normfactor;
2329 return kTRUE;
2330}
2331
2332/** \class TGeoIdentity
2333\ingroup Geometry_classes
2334An identity transformation. It holds no data member
2335and returns pointers to static null translation and identity
2336transformations for rotation and scale
2337*/
2338
2340
2341////////////////////////////////////////////////////////////////////////////////
2342/// dummy ctor
2343
2345{
2346 if (!gGeoIdentity)
2347 gGeoIdentity = this;
2349}
2350
2351////////////////////////////////////////////////////////////////////////////////
2352/// constructor
2353
2355{
2356 if (!gGeoIdentity)
2357 gGeoIdentity = this;
2359}
2360
2361////////////////////////////////////////////////////////////////////////////////
2362/// Return a temporary inverse of this.
2363
2365{
2367 return h;
2368}
2369
2370/** \class TGeoHMatrix
2371\ingroup Geometry_classes
2372
2373Matrix class used for computing global transformations
2374Should NOT be used for node definition. An instance of this class
2375is generally used to pile-up local transformations starting from
2376the top level physical node, down to the current node.
2377*/
2378
2380
2381////////////////////////////////////////////////////////////////////////////////
2382/// dummy ctor
2383
2385{
2386 memset(&fTranslation[0], 0, kN3);
2388 memcpy(fScale, kUnitScale, kN3);
2389}
2390
2391////////////////////////////////////////////////////////////////////////////////
2392/// constructor
2393
2395{
2396 memset(&fTranslation[0], 0, kN3);
2398 memcpy(fScale, kUnitScale, kN3);
2399}
2400
2401////////////////////////////////////////////////////////////////////////////////
2402/// assignment
2403
2405{
2406 memset(&fTranslation[0], 0, kN3);
2408 memcpy(fScale, kUnitScale, kN3);
2409 if (matrix.IsIdentity())
2410 return;
2411 if (matrix.IsTranslation())
2413 if (matrix.IsRotation())
2414 memcpy(fRotationMatrix, matrix.GetRotationMatrix(), kN9);
2415 if (matrix.IsScale())
2416 memcpy(fScale, matrix.GetScale(), kN3);
2417}
2418
2419////////////////////////////////////////////////////////////////////////////////
2420/// destructor
2421
2423
2424////////////////////////////////////////////////////////////////////////////////
2425/// assignment
2426
2428{
2429 return TGeoHMatrix::operator=(*matrix);
2430}
2431
2432////////////////////////////////////////////////////////////////////////////////
2433/// assignment
2434
2436{
2437 if (&matrix == this)
2438 return *this;
2439 Clear();
2440 Bool_t registered = TestBit(kGeoRegistered);
2441 TNamed::operator=(matrix);
2442 if (matrix.IsIdentity())
2443 return *this;
2444 if (matrix.IsTranslation())
2445 memcpy(fTranslation, matrix.GetTranslation(), kN3);
2446 if (matrix.IsRotation())
2447 memcpy(fRotationMatrix, matrix.GetRotationMatrix(), kN9);
2448 if (matrix.IsScale())
2449 memcpy(fScale, matrix.GetScale(), kN3);
2450 SetBit(kGeoRegistered, registered);
2451 return *this;
2452}
2453
2454////////////////////////////////////////////////////////////////////////////////
2455/// Composition
2456
2458{
2459 Multiply(&right);
2460 return *this;
2461}
2462
2464{
2465 TGeoHMatrix h = *this;
2466 h *= right;
2467 return h;
2468}
2469
2470////////////////////////////////////////////////////////////////////////////////
2471/// Is-equal operator
2472
2474{
2475 if (&other == this)
2476 return kTRUE;
2477 const Double_t *tr = GetTranslation();
2478 const Double_t *otr = other.GetTranslation();
2479 for (auto i = 0; i < 3; i++)
2480 if (TMath::Abs(tr[i] - otr[i]) > 1.E-10)
2481 return kFALSE;
2482 const Double_t *rot = GetRotationMatrix();
2483 const Double_t *orot = other.GetRotationMatrix();
2484 for (auto i = 0; i < 9; i++)
2485 if (TMath::Abs(rot[i] - orot[i]) > 1.E-10)
2486 return kFALSE;
2487 const Double_t *scl = GetScale();
2488 const Double_t *oscl = other.GetScale();
2489 for (auto i = 0; i < 3; i++)
2490 if (TMath::Abs(scl[i] - oscl[i]) > 1.E-10)
2491 return kFALSE;
2492 return kTRUE;
2493}
2494
2495////////////////////////////////////////////////////////////////////////////////
2496/// Fast copy method.
2497
2499{
2501 SetBit(kGeoRotation, other->IsRotation());
2503 memcpy(fTranslation, other->GetTranslation(), kN3);
2504 memcpy(fRotationMatrix, other->GetRotationMatrix(), kN9);
2505}
2506
2507////////////////////////////////////////////////////////////////////////////////
2508/// clear the data for this matrix
2509
2511{
2513 if (IsIdentity())
2514 return;
2518 memcpy(fTranslation, kNullVector, kN3);
2520 memcpy(fScale, kUnitScale, kN3);
2521}
2522
2523////////////////////////////////////////////////////////////////////////////////
2524/// Make a clone of this matrix.
2525
2527{
2528 TGeoMatrix *matrix = new TGeoHMatrix(*this);
2529 return matrix;
2530}
2531
2532////////////////////////////////////////////////////////////////////////////////
2533/// Perform a rotation about Z having the sine/cosine of the rotation angle.
2534
2536{
2537 fRotationMatrix[0] = sincos[1];
2538 fRotationMatrix[1] = -sincos[0];
2539 fRotationMatrix[3] = sincos[0];
2540 fRotationMatrix[4] = sincos[1];
2542}
2543
2544////////////////////////////////////////////////////////////////////////////////
2545/// Return a temporary inverse of this.
2546
2548{
2549 TGeoHMatrix h;
2550 h = *this;
2552 if (IsTranslation()) {
2553 Double_t tr[3];
2554 tr[0] = -fTranslation[0] * fRotationMatrix[0] - fTranslation[1] * fRotationMatrix[3] -
2556 tr[1] = -fTranslation[0] * fRotationMatrix[1] - fTranslation[1] * fRotationMatrix[4] -
2558 tr[2] = -fTranslation[0] * fRotationMatrix[2] - fTranslation[1] * fRotationMatrix[5] -
2560 h.SetTranslation(tr);
2561 }
2562 if (IsRotation()) {
2563 Double_t newrot[9];
2564 newrot[0] = fRotationMatrix[0];
2565 newrot[1] = fRotationMatrix[3];
2566 newrot[2] = fRotationMatrix[6];
2567 newrot[3] = fRotationMatrix[1];
2568 newrot[4] = fRotationMatrix[4];
2569 newrot[5] = fRotationMatrix[7];
2570 newrot[6] = fRotationMatrix[2];
2571 newrot[7] = fRotationMatrix[5];
2572 newrot[8] = fRotationMatrix[8];
2573 h.SetRotation(newrot);
2574 }
2575 if (IsScale()) {
2576 Double_t sc[3];
2577 sc[0] = 1. / fScale[0];
2578 sc[1] = 1. / fScale[1];
2579 sc[2] = 1. / fScale[2];
2580 h.SetScale(sc);
2581 }
2582 return h;
2583}
2584
2585////////////////////////////////////////////////////////////////////////////////
2586/// computes determinant of the rotation matrix
2587
2589{
2596 return det;
2597}
2598
2599////////////////////////////////////////////////////////////////////////////////
2600/// multiply to the right with an other transformation
2601/// if right is identity matrix, just return
2602
2604{
2605 if (right->IsIdentity())
2606 return;
2607 const Double_t *r_tra = right->GetTranslation();
2608 const Double_t *r_rot = right->GetRotationMatrix();
2609 const Double_t *r_scl = right->GetScale();
2610 if (IsIdentity()) {
2611 if (right->IsRotation()) {
2613 memcpy(fRotationMatrix, r_rot, kN9);
2614 if (right->IsReflection())
2616 }
2617 if (right->IsScale()) {
2619 memcpy(fScale, r_scl, kN3);
2620 }
2621 if (right->IsTranslation()) {
2623 memcpy(fTranslation, r_tra, kN3);
2624 }
2625 return;
2626 }
2627 Int_t i, j;
2628 Double_t new_rot[9];
2629
2630 if (right->IsRotation()) {
2632 if (right->IsReflection())
2634 }
2635 if (right->IsScale())
2637 if (right->IsTranslation())
2639
2640 // new translation
2641 if (IsTranslation()) {
2642 for (i = 0; i < 3; i++) {
2643 fTranslation[i] += fRotationMatrix[3 * i] * r_tra[0] + fRotationMatrix[3 * i + 1] * r_tra[1] +
2644 fRotationMatrix[3 * i + 2] * r_tra[2];
2645 }
2646 }
2647 if (IsRotation()) {
2648 // new rotation
2649 for (i = 0; i < 3; i++) {
2650 for (j = 0; j < 3; j++) {
2651 new_rot[3 * i + j] = fRotationMatrix[3 * i] * r_rot[j] + fRotationMatrix[3 * i + 1] * r_rot[3 + j] +
2652 fRotationMatrix[3 * i + 2] * r_rot[6 + j];
2653 }
2654 }
2655 memcpy(fRotationMatrix, new_rot, kN9);
2656 }
2657 // new scale
2658 if (IsScale()) {
2659 for (i = 0; i < 3; i++)
2660 fScale[i] *= r_scl[i];
2661 }
2662}
2663
2664////////////////////////////////////////////////////////////////////////////////
2665/// multiply to the left with an other transformation
2666/// if right is identity matrix, just return
2667
2669{
2670 if (left == gGeoIdentity)
2671 return;
2672 const Double_t *l_tra = left->GetTranslation();
2673 const Double_t *l_rot = left->GetRotationMatrix();
2674 const Double_t *l_scl = left->GetScale();
2675 if (IsIdentity()) {
2676 if (left->IsRotation()) {
2677 if (left->IsReflection())
2680 memcpy(fRotationMatrix, l_rot, kN9);
2681 }
2682 if (left->IsScale()) {
2684 memcpy(fScale, l_scl, kN3);
2685 }
2686 if (left->IsTranslation()) {
2688 memcpy(fTranslation, l_tra, kN3);
2689 }
2690 return;
2691 }
2692 Int_t i, j;
2693 Double_t new_tra[3];
2694 Double_t new_rot[9];
2695
2696 if (left->IsRotation()) {
2698 if (left->IsReflection())
2700 }
2701 if (left->IsScale())
2703 if (left->IsTranslation())
2705
2706 // new translation
2707 if (IsTranslation()) {
2708 for (i = 0; i < 3; i++) {
2709 new_tra[i] = l_tra[i] + l_rot[3 * i] * fTranslation[0] + l_rot[3 * i + 1] * fTranslation[1] +
2710 l_rot[3 * i + 2] * fTranslation[2];
2711 }
2712 memcpy(fTranslation, new_tra, kN3);
2713 }
2714 if (IsRotation()) {
2715 // new rotation
2716 for (i = 0; i < 3; i++) {
2717 for (j = 0; j < 3; j++) {
2718 new_rot[3 * i + j] = l_rot[3 * i] * fRotationMatrix[j] + l_rot[3 * i + 1] * fRotationMatrix[3 + j] +
2719 l_rot[3 * i + 2] * fRotationMatrix[6 + j];
2720 }
2721 }
2722 memcpy(fRotationMatrix, new_rot, kN9);
2723 }
2724 // new scale
2725 if (IsScale()) {
2726 for (i = 0; i < 3; i++)
2727 fScale[i] *= l_scl[i];
2728 }
2729}
2730
2731////////////////////////////////////////////////////////////////////////////////
2732/// Rotate about X axis with angle expressed in degrees.
2733
2735{
2737 Double_t phi = angle * TMath::DegToRad();
2738 Double_t c = TMath::Cos(phi);
2739 Double_t s = TMath::Sin(phi);
2740 Double_t v[9];
2741 v[0] = fRotationMatrix[0];
2742 v[1] = fRotationMatrix[1];
2743 v[2] = fRotationMatrix[2];
2744 v[3] = c * fRotationMatrix[3] - s * fRotationMatrix[6];
2745 v[4] = c * fRotationMatrix[4] - s * fRotationMatrix[7];
2746 v[5] = c * fRotationMatrix[5] - s * fRotationMatrix[8];
2747 v[6] = s * fRotationMatrix[3] + c * fRotationMatrix[6];
2748 v[7] = s * fRotationMatrix[4] + c * fRotationMatrix[7];
2749 v[8] = s * fRotationMatrix[5] + c * fRotationMatrix[8];
2750 memcpy(fRotationMatrix, v, kN9);
2751
2752 v[0] = fTranslation[0];
2753 v[1] = c * fTranslation[1] - s * fTranslation[2];
2754 v[2] = s * fTranslation[1] + c * fTranslation[2];
2755 memcpy(fTranslation, v, kN3);
2756}
2757
2758////////////////////////////////////////////////////////////////////////////////
2759/// Rotate about Y axis with angle expressed in degrees.
2760
2762{
2764 Double_t phi = angle * TMath::DegToRad();
2765 Double_t c = TMath::Cos(phi);
2766 Double_t s = TMath::Sin(phi);
2767 Double_t v[9];
2768 v[0] = c * fRotationMatrix[0] + s * fRotationMatrix[6];
2769 v[1] = c * fRotationMatrix[1] + s * fRotationMatrix[7];
2770 v[2] = c * fRotationMatrix[2] + s * fRotationMatrix[8];
2771 v[3] = fRotationMatrix[3];
2772 v[4] = fRotationMatrix[4];
2773 v[5] = fRotationMatrix[5];
2774 v[6] = -s * fRotationMatrix[0] + c * fRotationMatrix[6];
2775 v[7] = -s * fRotationMatrix[1] + c * fRotationMatrix[7];
2776 v[8] = -s * fRotationMatrix[2] + c * fRotationMatrix[8];
2777 memcpy(fRotationMatrix, v, kN9);
2778
2779 v[0] = c * fTranslation[0] + s * fTranslation[2];
2780 v[1] = fTranslation[1];
2781 v[2] = -s * fTranslation[0] + c * fTranslation[2];
2782 memcpy(fTranslation, v, kN3);
2783}
2784
2785////////////////////////////////////////////////////////////////////////////////
2786/// Rotate about Z axis with angle expressed in degrees.
2787
2789{
2791 Double_t phi = angle * TMath::DegToRad();
2792 Double_t c = TMath::Cos(phi);
2793 Double_t s = TMath::Sin(phi);
2794 Double_t v[9];
2795 v[0] = c * fRotationMatrix[0] - s * fRotationMatrix[3];
2796 v[1] = c * fRotationMatrix[1] - s * fRotationMatrix[4];
2797 v[2] = c * fRotationMatrix[2] - s * fRotationMatrix[5];
2798 v[3] = s * fRotationMatrix[0] + c * fRotationMatrix[3];
2799 v[4] = s * fRotationMatrix[1] + c * fRotationMatrix[4];
2800 v[5] = s * fRotationMatrix[2] + c * fRotationMatrix[5];
2801 v[6] = fRotationMatrix[6];
2802 v[7] = fRotationMatrix[7];
2803 v[8] = fRotationMatrix[8];
2804 memcpy(&fRotationMatrix[0], v, kN9);
2805
2806 v[0] = c * fTranslation[0] - s * fTranslation[1];
2807 v[1] = s * fTranslation[0] + c * fTranslation[1];
2808 v[2] = fTranslation[2];
2809 memcpy(fTranslation, v, kN3);
2810}
2811
2812////////////////////////////////////////////////////////////////////////////////
2813/// Multiply by a reflection respect to YZ.
2814
2815void TGeoHMatrix::ReflectX(Bool_t leftside, Bool_t rotonly)
2816{
2817 if (leftside && !rotonly)
2818 fTranslation[0] = -fTranslation[0];
2819 if (leftside) {
2823 } else {
2827 }
2830}
2831
2832////////////////////////////////////////////////////////////////////////////////
2833/// Multiply by a reflection respect to ZX.
2834
2835void TGeoHMatrix::ReflectY(Bool_t leftside, Bool_t rotonly)
2836{
2837 if (leftside && !rotonly)
2838 fTranslation[1] = -fTranslation[1];
2839 if (leftside) {
2843 } else {
2847 }
2850}
2851
2852////////////////////////////////////////////////////////////////////////////////
2853/// Multiply by a reflection respect to XY.
2854
2855void TGeoHMatrix::ReflectZ(Bool_t leftside, Bool_t rotonly)
2856{
2857 if (leftside && !rotonly)
2858 fTranslation[2] = -fTranslation[2];
2859 if (leftside) {
2863 } else {
2867 }
2870}
2871
2872////////////////////////////////////////////////////////////////////////////////
2873/// Save a primitive as a C++ statement(s) on output stream "out".
2874
2875void TGeoHMatrix::SavePrimitive(std::ostream &out, Option_t * /*option*/ /*= ""*/)
2876{
2878 return;
2879 const Double_t *tr = fTranslation;
2880 const Double_t *rot = fRotationMatrix;
2881 out << " // HMatrix: " << GetName() << std::endl;
2882 out << " tr[0] = " << tr[0] << "; "
2883 << "tr[1] = " << tr[1] << "; "
2884 << "tr[2] = " << tr[2] << ";" << std::endl;
2885 out << " rot[0] =" << rot[0] << "; "
2886 << "rot[1] = " << rot[1] << "; "
2887 << "rot[2] = " << rot[2] << ";" << std::endl;
2888 out << " rot[3] =" << rot[3] << "; "
2889 << "rot[4] = " << rot[4] << "; "
2890 << "rot[5] = " << rot[5] << ";" << std::endl;
2891 out << " rot[6] =" << rot[6] << "; "
2892 << "rot[7] = " << rot[7] << "; "
2893 << "rot[8] = " << rot[8] << ";" << std::endl;
2894 const char *name = GetPointerName();
2895 out << " auto " << name << " = new TGeoHMatrix(\"" << GetName() << "\");" << std::endl;
2896 out << " " << name << "->SetTranslation(tr);" << std::endl;
2897 out << " " << name << "->SetRotation(rot);" << std::endl;
2898 if (IsTranslation())
2899 out << " " << name << "->SetBit(TGeoMatrix::kGeoTranslation);" << std::endl;
2900 if (IsRotation())
2901 out << " " << name << "->SetBit(TGeoMatrix::kGeoRotation);" << std::endl;
2902 if (IsReflection())
2903 out << " " << name << "->SetBit(TGeoMatrix::kGeoReflection);" << std::endl;
2905}
#define c(i)
Definition RSha256.hxx:101
#define h(i)
Definition RSha256.hxx:106
int Int_t
Definition RtypesCore.h:45
constexpr Bool_t kFALSE
Definition RtypesCore.h:101
double Double_t
Definition RtypesCore.h:59
constexpr Bool_t kTRUE
Definition RtypesCore.h:100
const char Option_t
Definition RtypesCore.h:66
#define ClassImp(name)
Definition Rtypes.h:377
Option_t Option_t option
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t r
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t index
Option_t Option_t TPoint TPoint angle
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t type
char name[80]
Definition TGX11.cxx:110
R__EXTERN TGeoManager * gGeoManager
const Int_t kN3
TGeoIdentity * gGeoIdentity
const Int_t kN9
const Double_t kUnitScale[3]
Definition TGeoMatrix.h:28
const Double_t kIdentityMatrix[3 *3]
Definition TGeoMatrix.h:26
R__EXTERN TGeoIdentity * gGeoIdentity
Definition TGeoMatrix.h:537
const Double_t kNullVector[3]
Definition TGeoMatrix.h:24
Class describing rotation + translation.
Definition TGeoMatrix.h:317
void Multiply(const TGeoMatrix *right)
multiply to the right with an other transformation if right is identity matrix, just return
TGeoCombiTrans & operator*=(const TGeoMatrix &other)
Composition.
void ReflectX(Bool_t leftside, Bool_t rotonly=kFALSE) override
Multiply by a reflection respect to YZ.
Bool_t operator==(const TGeoMatrix &other) const
Is-equal operator.
TGeoCombiTrans()
dummy ctor
void RegisterYourself() override
Register the matrix in the current manager, which will become the owner.
const Double_t * GetTranslation() const override
Definition TGeoMatrix.h:361
void SavePrimitive(std::ostream &out, Option_t *option="") override
Save a primitive as a C++ statement(s) on output stream "out".
TGeoMatrix * MakeClone() const override
Make a clone of this matrix.
TGeoHMatrix Inverse() const override
Return a temporary inverse of this.
void RotateY(Double_t angle) override
Rotate about Y axis with angle expressed in degrees.
Double_t fTranslation[3]
Definition TGeoMatrix.h:319
TGeoRotation * fRotation
Definition TGeoMatrix.h:320
void RotateX(Double_t angle) override
Rotate about X axis with angle expressed in degrees.
void SetTranslation(const TGeoTranslation &tr)
copy the translation component
void SetRotation(const TGeoRotation &other)
Copy the rotation from another one.
void Clear(Option_t *option="") override
Reset translation/rotation to identity.
TGeoCombiTrans & operator=(const TGeoCombiTrans &other)
Definition TGeoMatrix.h:330
void ReflectY(Bool_t leftside, Bool_t rotonly=kFALSE) override
Multiply by a reflection respect to ZX.
~TGeoCombiTrans() override
destructor
TGeoCombiTrans operator*(const TGeoMatrix &other) const
void RotateZ(Double_t angle) override
Rotate about Z axis with angle expressed in degrees.
const Double_t * GetRotationMatrix() const override
get the rotation array
void ReflectZ(Bool_t leftside, Bool_t rotonly=kFALSE) override
Multiply by a reflection respect to XY.
Most general transformation, holding a translation, a rotation and a scale.
Definition TGeoMatrix.h:375
void Clear(Option_t *option="") override
clear the fields of this transformation
Double_t fScale[3]
Definition TGeoMatrix.h:377
~TGeoGenTrans() override
destructor
Bool_t Normalize()
A scale transformation should be normalized by sx*sy*sz factor.
TGeoGenTrans()
dummy ctor
void SetScale(Double_t sx, Double_t sy, Double_t sz)
set the scale
TGeoHMatrix Inverse() const override
Return a temporary inverse of this.
Matrix class used for computing global transformations Should NOT be used for node definition.
Definition TGeoMatrix.h:458
TGeoHMatrix & operator*=(const TGeoMatrix &other)
Composition.
TGeoHMatrix()
dummy ctor
void RotateX(Double_t angle) override
Rotate about X axis with angle expressed in degrees.
const Double_t * GetScale() const override
Definition TGeoMatrix.h:529
const Double_t * GetRotationMatrix() const override
Definition TGeoMatrix.h:528
void MultiplyLeft(const TGeoMatrix *left)
multiply to the left with an other transformation if right is identity matrix, just return
Double_t Determinant() const
computes determinant of the rotation matrix
TGeoMatrix * MakeClone() const override
Make a clone of this matrix.
TGeoHMatrix Inverse() const override
Return a temporary inverse of this.
void RotateZ(Double_t angle) override
Rotate about Z axis with angle expressed in degrees.
void ReflectX(Bool_t leftside, Bool_t rotonly=kFALSE) override
Multiply by a reflection respect to YZ.
void SavePrimitive(std::ostream &out, Option_t *option="") override
Save a primitive as a C++ statement(s) on output stream "out".
void CopyFrom(const TGeoMatrix *other)
Fast copy method.
void ReflectY(Bool_t leftside, Bool_t rotonly=kFALSE) override
Multiply by a reflection respect to ZX.
void FastRotZ(const Double_t *sincos)
Perform a rotation about Z having the sine/cosine of the rotation angle.
Double_t fTranslation[3]
Definition TGeoMatrix.h:460
Bool_t operator==(const TGeoMatrix &other) const
Is-equal operator.
Double_t fRotationMatrix[9]
Definition TGeoMatrix.h:461
~TGeoHMatrix() override
destructor
void RotateY(Double_t angle) override
Rotate about Y axis with angle expressed in degrees.
void Clear(Option_t *option="") override
clear the data for this matrix
const Double_t * GetTranslation() const override
Definition TGeoMatrix.h:527
TGeoHMatrix & operator=(const TGeoHMatrix &other)
Definition TGeoMatrix.h:471
void Multiply(const TGeoMatrix *right)
multiply to the right with an other transformation if right is identity matrix, just return
void ReflectZ(Bool_t leftside, Bool_t rotonly=kFALSE) override
Multiply by a reflection respect to XY.
TGeoHMatrix operator*(const TGeoMatrix &other) const
void SetTranslation(const Double_t *vect)
Definition TGeoMatrix.h:511
Double_t fScale[3]
Definition TGeoMatrix.h:462
An identity transformation.
Definition TGeoMatrix.h:406
TGeoHMatrix Inverse() const override
Return a temporary inverse of this.
TGeoIdentity()
dummy ctor
TObjArray * GetListOfMatrices() const
void RegisterMatrix(const TGeoMatrix *matrix)
Register a matrix to the list of matrices.
void BombTranslation(const Double_t *tr, Double_t *bombtr)
Get the new 'bombed' translation vector according current exploded view mode.
void UnbombTranslation(const Double_t *tr, Double_t *bombtr)
Get the new 'unbombed' translation vector according current exploded view mode.
Bool_t IsCleaning() const
Geometrical transformation package.
Definition TGeoMatrix.h:38
virtual void LocalToMasterVect(const Double_t *local, Double_t *master) const
convert a vector by multiplying its column vector (x, y, z, 1) to matrix inverse
Bool_t IsScale() const
Definition TGeoMatrix.h:67
void SetDefaultName()
If no name was supplied in the ctor, the type of transformation is checked.
void Print(Option_t *option="") const override
print the matrix in 4x4 format
Bool_t IsGeneral() const
Definition TGeoMatrix.h:71
@ kGeoSavePrimitive
Definition TGeoMatrix.h:48
@ kGeoTranslation
Definition TGeoMatrix.h:43
@ kGeoMatrixOwned
Definition TGeoMatrix.h:49
virtual void MasterToLocal(const Double_t *master, Double_t *local) const
convert a point by multiplying its column vector (x, y, z, 1) to matrix
virtual void MasterToLocalVect(const Double_t *master, Double_t *local) const
convert a point by multiplying its column vector (x, y, z, 1) to matrix
virtual void ReflectZ(Bool_t leftside, Bool_t rotonly=kFALSE)
Multiply by a reflection respect to XY.
virtual const Double_t * GetTranslation() const =0
Bool_t IsTranslation() const
Definition TGeoMatrix.h:64
Bool_t IsReflection() const
Definition TGeoMatrix.h:66
Bool_t IsRotation() const
Definition TGeoMatrix.h:65
virtual void LocalToMasterBomb(const Double_t *local, Double_t *master) const
convert a point by multiplying its column vector (x, y, z, 1) to matrix inverse
virtual void RegisterYourself()
Register the matrix in the current manager, which will become the owner.
virtual void LocalToMaster(const Double_t *local, Double_t *master) const
convert a point by multiplying its column vector (x, y, z, 1) to matrix inverse
virtual void MasterToLocalBomb(const Double_t *master, Double_t *local) const
convert a point by multiplying its column vector (x, y, z, 1) to matrix
Bool_t IsRotAboutZ() const
Returns true if no rotation or the rotation is about Z axis.
void GetHomogenousMatrix(Double_t *hmat) const
The homogenous matrix associated with the transformation is used for piling up's and visualization.
TGeoMatrix()
dummy constructor
Bool_t IsOwned() const
Definition TGeoMatrix.h:69
virtual const Double_t * GetScale() const =0
static void Normalize(Double_t *vect)
Normalize a vector.
Bool_t IsIdentity() const
Definition TGeoMatrix.h:63
const char * GetPointerName() const
Provide a pointer name containing uid.
Bool_t IsCombi() const
Definition TGeoMatrix.h:70
Bool_t IsRegistered() const
Definition TGeoMatrix.h:72
Bool_t IsShared() const
Definition TGeoMatrix.h:68
virtual const Double_t * GetRotationMatrix() const =0
virtual Int_t GetByteCount() const
Get total size in bytes of this.
~TGeoMatrix() override
Destructor.
virtual void ReflectY(Bool_t leftside, Bool_t rotonly=kFALSE)
Multiply by a reflection respect to ZX.
virtual void ReflectX(Bool_t leftside, Bool_t rotonly=kFALSE)
Multiply by a reflection respect to YZ.
Class describing rotations.
Definition TGeoMatrix.h:168
void RotateX(Double_t angle) override
Rotate about X axis of the master frame with angle expressed in degrees.
void ReflectZ(Bool_t leftside, Bool_t rotonly=kFALSE) override
Multiply by a reflection respect to XY.
TGeoRotation()
Default constructor.
void Clear(Option_t *option="") override
reset data members
const Double_t * GetRotationMatrix() const override
Definition TGeoMatrix.h:239
void SetAngles(Double_t phi, Double_t theta, Double_t psi)
Set matrix elements according to Euler angles.
void MultiplyBy(const TGeoRotation *rot, Bool_t after=kTRUE)
Multiply this rotation with the one specified by ROT.
void RotateY(Double_t angle) override
Rotate about Y axis of the master frame with angle expressed in degrees.
Bool_t operator==(const TGeoRotation &other) const
Is-equal operator.
void SetMatrix(const Double_t *rot)
Definition TGeoMatrix.h:230
void RotateZ(Double_t angle) override
Rotate about Z axis of the master frame with angle expressed in degrees.
void LocalToMaster(const Double_t *local, Double_t *master) const override
convert a point by multiplying its column vector (x, y, z, 1) to matrix inverse
TGeoRotation & operator*=(const TGeoRotation &other)
Composition.
void CheckMatrix()
performes an orthogonality check and finds if the matrix is a reflection Warning("CheckMatrix",...
void ReflectY(Bool_t leftside, Bool_t rotonly=kFALSE) override
Multiply by a reflection respect to ZX.
Double_t GetPhiRotation(Bool_t fixX=kFALSE) const
Returns rotation angle about Z axis in degrees.
void FastRotZ(const Double_t *sincos)
Perform a rotation about Z having the sine/cosine of the rotation angle.
void GetInverse(Double_t *invmat) const
Get the inverse rotation matrix (which is simply the transpose)
Double_t Determinant() const
computes determinant of the rotation matrix
void GetAngles(Double_t &theta1, Double_t &phi1, Double_t &theta2, Double_t &phi2, Double_t &theta3, Double_t &phi3) const
Retrieve rotation angles.
Bool_t IsValid() const
Perform orthogonality test for rotation.
void MasterToLocal(const Double_t *master, Double_t *local) const override
convert a point by multiplying its column vector (x, y, z, 1) to matrix
TGeoMatrix * MakeClone() const override
Make a clone of this matrix.
TGeoRotation operator*(const TGeoRotation &other) const
void SavePrimitive(std::ostream &out, Option_t *option="") override
Save a primitive as a C++ statement(s) on output stream "out".
void ReflectX(Bool_t leftside, Bool_t rotonly=kFALSE) override
Multiply by a reflection respect to YZ.
Double_t fRotationMatrix[3 *3]
Definition TGeoMatrix.h:170
void SetRotation(const TGeoMatrix &other)
Copy rotation elements from other rotation matrix.
TGeoRotation & operator=(const TGeoRotation &other)
Definition TGeoMatrix.h:185
TGeoHMatrix Inverse() const override
Return a temporary inverse of this.
Class describing scale transformations.
Definition TGeoMatrix.h:253
TGeoScale()
default constructor
const Double_t * GetScale() const override
Definition TGeoMatrix.h:305
TGeoScale & operator=(const TGeoScale &other)
Definition TGeoMatrix.h:264
TGeoMatrix * MakeClone() const override
Make a clone of this matrix.
Bool_t operator==(const TGeoScale &other) const
Is-equal operator.
~TGeoScale() override
destructor
void SetScale(Double_t sx, Double_t sy, Double_t sz)
scale setter
void LocalToMaster(const Double_t *local, Double_t *master) const override
Convert a local point to the master frame.
TGeoHMatrix Inverse() const override
Return a temporary inverse of this.
Double_t fScale[3]
Definition TGeoMatrix.h:255
TGeoScale operator*(const TGeoScale &other) const
TGeoScale & operator*=(const TGeoScale &other)
Scale composition.
void MasterToLocal(const Double_t *master, Double_t *local) const override
Convert a global point to local frame.
Class describing translations.
Definition TGeoMatrix.h:116
void RotateX(Double_t angle) override
Rotate about X axis of the master frame with angle expressed in degrees.
void RotateY(Double_t angle) override
Rotate about Y axis of the master frame with angle expressed in degrees.
Bool_t operator==(const TGeoTranslation &other) const
Is-equal operator.
TGeoTranslation & operator*=(const TGeoTranslation &other)
Translation composition.
TGeoTranslation operator*(const TGeoTranslation &right) const
void Add(const TGeoTranslation *other)
Adding a translation to this one.
void RotateZ(Double_t angle) override
Rotate about Z axis of the master frame with angle expressed in degrees.
void LocalToMasterVect(const Double_t *local, Double_t *master) const override
convert a vector to MARS
void LocalToMaster(const Double_t *local, Double_t *master) const override
convert a point by multiplying its column vector (x, y, z, 1) to matrix inverse
void MasterToLocalBomb(const Double_t *master, Double_t *local) const override
convert a point by multiplying its column vector (x, y, z, 1) to matrix
void SetTranslation(Double_t dx, Double_t dy, Double_t dz)
Set translation components.
TGeoTranslation & operator=(const TGeoTranslation &other)
Definition TGeoMatrix.h:127
Double_t fTranslation[3]
Definition TGeoMatrix.h:118
const Double_t * GetTranslation() const override
Definition TGeoMatrix.h:154
void MasterToLocal(const Double_t *master, Double_t *local) const override
convert a point by multiplying its column vector (x, y, z, 1) to matrix
void LocalToMasterBomb(const Double_t *local, Double_t *master) const override
convert a point by multiplying its column vector (x, y, z, 1) to matrix inverse
void SavePrimitive(std::ostream &out, Option_t *option="") override
Save a primitive as a C++ statement(s) on output stream "out".
TGeoTranslation()
Default constructor.
void Subtract(const TGeoTranslation *other)
Subtracting a translation from this one.
TGeoMatrix * MakeClone() const override
Make a clone of this matrix.
void MasterToLocalVect(const Double_t *master, Double_t *local) const override
convert a vector from MARS to local
TGeoHMatrix Inverse() const override
Return a temporary inverse of this.
The TNamed class is the base class for all named ROOT classes.
Definition TNamed.h:29
const char * GetName() const override
Returns name of object.
Definition TNamed.h:47
const char * GetTitle() const override
Returns title of object.
Definition TNamed.h:48
virtual void SetName(const char *name)
Set the name of the TNamed.
Definition TNamed.cxx:140
TNamed & operator=(const TNamed &rhs)
TNamed assignment operator.
Definition TNamed.cxx:51
An array of TObjects.
Definition TObjArray.h:31
Int_t GetEntriesFast() const
Definition TObjArray.h:58
TObject * Remove(TObject *obj) override
Remove object from array.
R__ALWAYS_INLINE Bool_t TestBit(UInt_t f) const
Definition TObject.h:201
virtual UInt_t GetUniqueID() const
Return the unique object id.
Definition TObject.cxx:457
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition TObject.cxx:973
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
Definition TObject.cxx:780
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition TObject.cxx:987
void ResetBit(UInt_t f)
Definition TObject.h:200
Basic string class.
Definition TString.h:139
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:2378
void Form(const char *fmt,...)
Formats a string using a printf style format descriptor.
Definition TString.cxx:2356
Double_t ACos(Double_t)
Returns the principal value of the arc cosine of x, expressed in radians.
Definition TMath.h:632
Double_t ASin(Double_t)
Returns the principal value of the arc sine of x, expressed in radians.
Definition TMath.h:624
Double_t ATan2(Double_t y, Double_t x)
Returns the principal value of the arc tangent of y/x, expressed in radians.
Definition TMath.h:646
constexpr Double_t DegToRad()
Conversion from degree to radian: .
Definition TMath.h:79
Double_t Sqrt(Double_t x)
Returns the square root of x.
Definition TMath.h:662
Double_t Cos(Double_t)
Returns the cosine of an angle of x radians.
Definition TMath.h:594
constexpr Double_t Pi()
Definition TMath.h:37
Double_t Sin(Double_t)
Returns the sine of an angle of x radians.
Definition TMath.h:588
constexpr Double_t RadToDeg()
Conversion from radian to degree: .
Definition TMath.h:72
Short_t Abs(Short_t d)
Returns the absolute value of parameter Short_t d.
Definition TMathBase.h:123
auto * th3
Definition textalign.C:22
auto * th2
Definition textalign.C:18
auto * th1
Definition textalign.C:14
TMarker m
Definition textangle.C:8