Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
TGeoMatrix.cxx
Go to the documentation of this file.
1// @(#)root/geom:$Id$
2// Author: Andrei Gheata 25/10/01
3
4/*************************************************************************
5 * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. *
6 * All rights reserved. *
7 * *
8 * For the licensing terms see $ROOTSYS/LICENSE. *
9 * For the list of contributors see $ROOTSYS/README/CREDITS. *
10 *************************************************************************/
11
12/** \class TGeoMatrix
13\ingroup Geometry_classes
14
15Geometrical transformation package.
16
17 All geometrical transformations handled by the modeller are provided as a
18built-in package. This was designed to minimize memory requirements and
19optimize performance of point/vector master-to-local and local-to-master
20computation. We need to have in mind that a transformation in TGeo has 2
21major use-cases. The first one is for defining the placement of a volume
22with respect to its container reference frame. This frame will be called
23'master' and the frame of the positioned volume - 'local'. If T is a
24transformation used for positioning volume daughters, then:
25
26~~~ {.cpp}
27 MASTER = T * LOCAL
28~~~
29
30 Therefore a local-to-master conversion will be performed by using T, while
31a master-to-local by using its inverse. The second use case is the computation
32of the global transformation of a given object in the geometry. Since the
33geometry is built as 'volumes-inside-volumes', this global transformation
34represent the pile-up of all local transformations in the corresponding
35branch. The conversion from the global reference frame and the given object
36is also called master-to-local, but it is handled by the manager class.
37 A general homogenous transformation is defined as a 4x4 matrix embedding
38a rotation, a translation and a scale. The advantage of this description
39is that each basic transformation can be represented as a homogenous matrix,
40composition being performed as simple matrix multiplication.
41
42 Rotation: Inverse rotation:
43
44~~~ {.cpp}
45 r11 r12 r13 0 r11 r21 r31 0
46 r21 r22 r23 0 r12 r22 r32 0
47 r31 r32 r33 0 r13 r23 r33 0
48 0 0 0 1 0 0 0 1
49~~~
50
51 Translation: Inverse translation:
52
53~~~ {.cpp}
54 1 0 0 tx 1 0 0 -tx
55 0 1 0 ty 0 1 0 -ty
56 0 0 1 tz 0 0 1 -tz
57 0 0 0 1 0 0 0 1
58~~~
59
60 Scale: Inverse scale:
61
62~~~ {.cpp}
63 sx 0 0 0 1/sx 0 0 0
64 0 sy 0 0 0 1/sy 0 0
65 0 0 sz 0 0 0 1/sz 0
66 0 0 0 1 0 0 0 1
67~~~
68
69 where:
70 - `rij` are the 3x3 rotation matrix components,
71 - `tx`, `ty`, `tz` are the translation components
72 - `sx`, `sy`, `sz` are arbitrary scale constants on each axis,
73
74 The disadvantage in using this approach is that computation for 4x4 matrices
75is expensive. Even combining two translation would become a multiplication
76of their corresponding matrices, which is quite an undesired effect. On the
77other hand, it is not a good idea to store a translation as a block of 16
78numbers. We have therefore chosen to implement each basic transformation type
79as a class deriving from the same basic abstract class and handling its specific
80data and point/vector transformation algorithms.
81
82\image html geom_transf.jpg
83
84### The base class TGeoMatrix defines abstract metods for:
85
86#### translation, rotation and scale getters. Every derived class stores only
87 its specific data, e.g. a translation stores an array of 3 doubles and a
88 rotation an array of 9. However, asking which is the rotation array of a
89 TGeoTranslation through the base TGeoMatrix interface is a legal operation.
90 The answer in this case is a pointer to a global constant array representing
91 an identity rotation.
92
93~~~ {.cpp}
94 Double_t *TGeoMatrix::GetTranslation()
95 Double_t *TGeoMatrix::GetRotation()
96 Double_t *TGeoMatrix::GetScale()
97~~~
98
99#### MasterToLocal() and LocalToMaster() point and vector transformations :
100
101~~~ {.cpp}
102 void TGeoMatrix::MasterToLocal(const Double_t *master, Double_t *local)
103 void TGeoMatrix::LocalToMaster(const Double_t *local, Double_t *master)
104 void TGeoMatrix::MasterToLocalVect(const Double_t *master, Double_t *local)
105 void TGeoMatrix::LocalToMasterVect(const Double_t *local, Double_t *master)
106~~~
107
108 These allow correct conversion also for reflections.
109
110#### Transformation type getters :
111
112~~~ {.cpp}
113 Bool_t TGeoMatrix::IsIdentity()
114 Bool_t TGeoMatrix::IsTranslation()
115 Bool_t TGeoMatrix::IsRotation()
116 Bool_t TGeoMatrix::IsScale()
117 Bool_t TGeoMatrix::IsCombi() (translation + rotation)
118 Bool_t TGeoMatrix::IsGeneral() (translation + rotation + scale)
119~~~
120
121 Combinations of basic transformations are represented by specific classes
122deriving from TGeoMatrix. In order to define a matrix as a combination of several
123others, a special class TGeoHMatrix is provided. Here is an example of matrix
124creation :
125
126### Matrix creation example:
127
128~~~ {.cpp}
129 root[0] TGeoRotation r1,r2;
130 r1.SetAngles(90,0,30); // rotation defined by Euler angles
131 r2.SetAngles(90,90,90,180,0,0); // rotation defined by GEANT3 angles
132 TGeoTranslation t1(-10,10,0);
133 TGeoTranslation t2(10,-10,5);
134 TGeoCombiTrans c1(t1,r1);
135 TGeoCombiTrans c2(t2,r2);
136 TGeoHMatrix h = c1 * c2; // composition is done via TGeoHMatrix class
137 root[7] TGeoHMatrix *ph = new TGeoHMatrix(hm); // this is the one we want to
138 // use for positioning a volume
139 root[8] ph->Print();
140 ...
141 pVolume->AddNode(pVolDaughter,id,ph) // now ph is owned by the manager
142~~~
143
144### Rule for matrix creation:
145 Unless explicitly used for positioning nodes (TGeoVolume::AddNode()) all
146matrices deletion have to be managed by users. Matrices passed to geometry
147have to be created by using new() operator and their deletion is done by
148TGeoManager class.
149
150### Available geometrical transformations
151
152#### TGeoTranslation
153Represent a (dx,dy,dz) translation. Data members:
154 Double_t fTranslation[3]. Translations can be added/subtracted.
155
156~~~ {.cpp}
157 TGeoTranslation t1;
158 t1->SetTranslation(-5,10,4);
159 TGeoTranslation *t2 = new TGeoTranslation(4,3,10);
160 t2->Subtract(&t1);
161~~~
162
163#### Rotations
164 Represent a pure rotation. Data members: Double_t fRotationMatrix[3*3].
165 Rotations can be defined either by Euler angles, either, by GEANT3 angles :
166
167~~~ {.cpp}
168 TGeoRotation *r1 = new TGeoRotation();
169 r1->SetAngles(phi, theta, psi); // all angles in degrees
170~~~
171
172 This represent the composition of : first a rotation about Z axis with
173 angle phi, then a rotation with theta about the rotated X axis, and
174 finally a rotation with psi about the new Z axis.
175
176~~~ {.cpp}
177 r1->SetAngles(th1,phi1, th2,phi2, th3,phi3)
178~~~
179
180 This is a rotation defined in GEANT3 style. Theta and phi are the spherical
181 angles of each axis of the rotated coordinate system with respect to the
182 initial one. This construction allows definition of malformed rotations,
183 e.g. not orthogonal. A check is performed and an error message is issued
184 in this case.
185
186 Specific utilities : determinant, inverse.
187
188#### Scale transformations
189 Represent a scale shrinking/enlargement. Data
190 members :Double_t fScale[3]. Not fully implemented yet.
191
192#### Combined transformations
193Represent a rotation followed by a translation.
194Data members: Double_t fTranslation[3], TGeoRotation *fRotation.
195
196~~~ {.cpp}
197 TGeoRotation *rot = new TGeoRotation("rot",10,20,30);
198 TGeoTranslation trans;
199 ...
200 TGeoCombiTrans *c1 = new TGeoCombiTrans(trans, rot);
201 TGeoCombiTrans *c2 = new TGeoCombiTrans("somename",10,20,30,rot)
202~~~
203
204
205#### TGeoGenTrans
206Combined transformations including a scale. Not implemented.
207
208#### TGeoIdentity
209A generic singleton matrix representing a identity transformation
210 NOTE: identified by the global variable gGeoIdentity.
211*/
212
213#include <iostream>
214#include "TObjArray.h"
215
216#include "TGeoManager.h"
217#include "TGeoMatrix.h"
218#include "TMath.h"
219
221const Int_t kN3 = 3 * sizeof(Double_t);
222const Int_t kN9 = 9 * sizeof(Double_t);
223
224// statics and globals
225
226////////////////////////////////////////////////////////////////////////////////
227/// dummy constructor
228
233
234////////////////////////////////////////////////////////////////////////////////
235/// copy constructor
236
241
242////////////////////////////////////////////////////////////////////////////////
243/// Constructor
244
246
247////////////////////////////////////////////////////////////////////////////////
248/// Destructor
249
251{
252 if (IsRegistered() && gGeoManager) {
253 if (!gGeoManager->IsCleaning()) {
255 Warning("dtor", "Registered matrix %s was removed", GetName());
256 }
257 }
258}
259
260////////////////////////////////////////////////////////////////////////////////
261/// Returns true if no rotation or the rotation is about Z axis
262
264{
265 if (IsIdentity())
266 return kTRUE;
267 const Double_t *rot = GetRotationMatrix();
268 if (TMath::Abs(rot[6]) > 1E-9)
269 return kFALSE;
270 if (TMath::Abs(rot[7]) > 1E-9)
271 return kFALSE;
272 if ((1. - TMath::Abs(rot[8])) > 1E-9)
273 return kFALSE;
274 return kTRUE;
275}
276
277////////////////////////////////////////////////////////////////////////////////
278/// Get total size in bytes of this
279
281{
282 Int_t count = 4 + 28 + strlen(GetName()) + strlen(GetTitle()); // fId + TNamed
283 if (IsTranslation())
284 count += 12;
285 if (IsScale())
286 count += 12;
287 if (IsCombi() || IsGeneral())
288 count += 4 + 36;
289 return count;
290}
291
292////////////////////////////////////////////////////////////////////////////////
293/// Provide a pointer name containing uid.
294
295const char *TGeoMatrix::GetPointerName() const
296{
297 static TString name;
298 name.Form("pMatrix%d", GetUniqueID());
299 return name.Data();
300}
301
302////////////////////////////////////////////////////////////////////////////////
303/// The homogenous matrix associated with the transformation is used for
304/// piling up's and visualization. A homogenous matrix is a 4*4 array
305/// containing the translation, the rotation and the scale components
306/// ~~~ {.cpp}
307/// | R00*sx R01 R02 dx |
308/// | R10 R11*sy R12 dy |
309/// | R20 R21 R22*sz dz |
310/// | 0 0 0 1 |
311/// ~~~
312/// where Rij is the rotation matrix, (sx, sy, sz) is the scale
313/// transformation and (dx, dy, dz) is the translation.
314
316{
318 const Double_t *mat = GetRotationMatrix();
319 for (Int_t i = 0; i < 3; i++) {
321 mat += 3;
322 hmatrix += 3;
323 *hmatrix = 0.0;
324 hmatrix++;
325 }
327 hmatrix = hmat;
328 if (IsScale()) {
329 for (Int_t i = 0; i < 3; i++) {
330 *hmatrix *= GetScale()[i];
331 hmatrix += 5;
332 }
333 }
334 hmatrix[15] = 1.;
335}
336
337////////////////////////////////////////////////////////////////////////////////
338/// @brief Extract world-space axes of a placed TGeoBBox.
339///
340/// The axes correspond to the directions of the local X, Y and Z axes
341/// of the box, expressed in the common (master) reference frame.
342///
343/// ROOT stores the rotation as a 3x3 matrix in row-major order:
344///
345/// [ r0 r1 r2 ]
346/// [ r3 r4 r5 ]
347/// [ r6 r7 r8 ]
348///
349/// The columns of this matrix represent the transformed local axes.
350///
351/// @param[out] ax World-space direction of the local X axis.
352/// @param[out] ay World-space direction of the local Y axis.
353/// @param[out] az World-space direction of the local Z axis.
354
356{
357 const Double_t *r = GetRotationMatrix();
358 ax.SetXYZ(r[0], r[3], r[6]);
359 ay.SetXYZ(r[1], r[4], r[7]);
360 az.SetXYZ(r[2], r[5], r[8]);
361}
362
363////////////////////////////////////////////////////////////////////////////////
364/// convert a point by multiplying its column vector (x, y, z, 1) to matrix inverse
365
367{
368 if (IsIdentity()) {
370 return;
371 }
372 Int_t i;
373 const Double_t *tr = GetTranslation();
374 if (!IsRotation()) {
375 for (i = 0; i < 3; i++)
376 master[i] = tr[i] + local[i];
377 return;
378 }
379 const Double_t *rot = GetRotationMatrix();
380 for (i = 0; i < 3; i++) {
381 master[i] = tr[i] + local[0] * rot[3 * i] + local[1] * rot[3 * i + 1] + local[2] * rot[3 * i + 2];
382 }
383}
384
385////////////////////////////////////////////////////////////////////////////////
386/// convert a vector by multiplying its column vector (x, y, z, 1) to matrix inverse
387
389{
390 if (!IsRotation()) {
392 return;
393 }
394 const Double_t *rot = GetRotationMatrix();
395 for (Int_t i = 0; i < 3; i++) {
396 master[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 inverse
402
404{
405 if (IsIdentity()) {
407 return;
408 }
409 Int_t i;
410 const Double_t *tr = GetTranslation();
411 Double_t bombtr[3] = {0., 0., 0.};
413 if (!IsRotation()) {
414 for (i = 0; i < 3; i++)
415 master[i] = bombtr[i] + local[i];
416 return;
417 }
418 const Double_t *rot = GetRotationMatrix();
419 for (i = 0; i < 3; i++) {
420 master[i] = bombtr[i] + local[0] * rot[3 * i] + local[1] * rot[3 * i + 1] + local[2] * rot[3 * i + 2];
421 }
422}
423
424////////////////////////////////////////////////////////////////////////////////
425/// convert a point by multiplying its column vector (x, y, z, 1) to matrix
426
428{
429 if (IsIdentity()) {
431 return;
432 }
433 const Double_t *tr = GetTranslation();
434 Double_t mt0 = master[0] - tr[0];
435 Double_t mt1 = master[1] - tr[1];
436 Double_t mt2 = master[2] - tr[2];
437 if (!IsRotation()) {
438 local[0] = mt0;
439 local[1] = mt1;
440 local[2] = mt2;
441 return;
442 }
443 const Double_t *rot = GetRotationMatrix();
444 local[0] = mt0 * rot[0] + mt1 * rot[3] + mt2 * rot[6];
445 local[1] = mt0 * rot[1] + mt1 * rot[4] + mt2 * rot[7];
446 local[2] = mt0 * rot[2] + mt1 * rot[5] + mt2 * rot[8];
447}
448
449////////////////////////////////////////////////////////////////////////////////
450/// convert a point by multiplying its column vector (x, y, z, 1) to matrix
451
453{
454 if (!IsRotation()) {
456 return;
457 }
458 const Double_t *rot = GetRotationMatrix();
459 for (Int_t i = 0; i < 3; i++) {
460 local[i] = master[0] * rot[i] + master[1] * rot[i + 3] + master[2] * rot[i + 6];
461 }
462}
463
464////////////////////////////////////////////////////////////////////////////////
465/// convert a point by multiplying its column vector (x, y, z, 1) to matrix
466
468{
469 if (IsIdentity()) {
471 return;
472 }
473 const Double_t *tr = GetTranslation();
474 Double_t bombtr[3] = {0., 0., 0.};
475 Int_t i;
477 if (!IsRotation()) {
478 for (i = 0; i < 3; i++)
479 local[i] = master[i] - bombtr[i];
480 return;
481 }
482 const Double_t *rot = GetRotationMatrix();
483 for (i = 0; i < 3; i++) {
484 local[i] =
485 (master[0] - bombtr[0]) * rot[i] + (master[1] - bombtr[1]) * rot[i + 3] + (master[2] - bombtr[2]) * rot[i + 6];
486 }
487}
488
489////////////////////////////////////////////////////////////////////////////////
490/// Normalize a vector.
491
493{
494 Double_t normfactor = vect[0] * vect[0] + vect[1] * vect[1] + vect[2] * vect[2];
495 if (normfactor <= 1E-10)
496 return;
498 vect[0] *= normfactor;
499 vect[1] *= normfactor;
500 vect[2] *= normfactor;
501}
502
503////////////////////////////////////////////////////////////////////////////////
504/// print the matrix in 4x4 format
505
507{
508 const Double_t *rot = GetRotationMatrix();
509 const Double_t *tr = GetTranslation();
510 printf("matrix %s - tr=%d rot=%d refl=%d scl=%d shr=%d reg=%d own=%d\n", GetName(), (Int_t)IsTranslation(),
512 (Int_t)IsOwned());
513 printf("%10.6f%12.6f%12.6f Tx = %10.6f\n", rot[0], rot[1], rot[2], tr[0]);
514 printf("%10.6f%12.6f%12.6f Ty = %10.6f\n", rot[3], rot[4], rot[5], tr[1]);
515 printf("%10.6f%12.6f%12.6f Tz = %10.6f\n", rot[6], rot[7], rot[8], tr[2]);
516 if (IsScale()) {
517 const Double_t *scl = GetScale();
518 printf("Sx=%10.6fSy=%12.6fSz=%12.6f\n", scl[0], scl[1], scl[2]);
519 }
520}
521
522////////////////////////////////////////////////////////////////////////////////
523/// Multiply by a reflection respect to YZ.
524
526
527////////////////////////////////////////////////////////////////////////////////
528/// Multiply by a reflection respect to ZX.
529
531
532////////////////////////////////////////////////////////////////////////////////
533/// Multiply by a reflection respect to XY.
534
536
537////////////////////////////////////////////////////////////////////////////////
538/// Register the matrix in the current manager, which will become the owner.
539
541{
542 if (!gGeoManager) {
543 Warning("RegisterYourself", "cannot register without geometry");
544 return;
545 }
546 if (!IsRegistered()) {
549 }
550}
551
552////////////////////////////////////////////////////////////////////////////////
553/// If no name was supplied in the ctor, the type of transformation is checked.
554/// A letter will be prepended to the name :
555/// - t - translation
556/// - r - rotation
557/// - s - scale
558/// - c - combi (translation + rotation)
559/// - g - general (tr+rot+scale)
560/// The index of the transformation in gGeoManager list of transformations will
561/// be appended.
562
564{
565 if (!gGeoManager)
566 return;
567 if (strlen(GetName()))
568 return;
569 char type = 'n';
570 if (IsTranslation())
571 type = 't';
572 if (IsRotation())
573 type = 'r';
574 if (IsScale())
575 type = 's';
576 if (IsCombi())
577 type = 'c';
578 if (IsGeneral())
579 type = 'g';
581 Int_t index = 0;
582 if (matrices)
583 index = matrices->GetEntriesFast() - 1;
585 SetName(name);
586}
587
588/** \class TGeoTranslation
589\ingroup Geometry_classes
590
591Class describing translations. A translation is
592basically an array of 3 doubles matching the positions 12, 13
593and 14 in the homogenous matrix description.
594*/
595
596////////////////////////////////////////////////////////////////////////////////
597/// Default constructor
598
600{
601 for (Int_t i = 0; i < 3; i++)
602 fTranslation[i] = 0;
603}
604
605////////////////////////////////////////////////////////////////////////////////
606/// Copy ctor.
607
612
613////////////////////////////////////////////////////////////////////////////////
614/// Ctor. based on a general matrix
615
622
623////////////////////////////////////////////////////////////////////////////////
624/// Default constructor defining the translation
625
632
633////////////////////////////////////////////////////////////////////////////////
634/// Default constructor defining the translation
635
642
643////////////////////////////////////////////////////////////////////////////////
644/// Assignment from a general matrix
645
658
659////////////////////////////////////////////////////////////////////////////////
660/// Translation composition
661
663{
664 const Double_t *tr = right.GetTranslation();
665 fTranslation[0] += tr[0];
666 fTranslation[1] += tr[1];
667 fTranslation[2] += tr[2];
668 if (!IsTranslation())
670 return *this;
671}
672
674{
675 TGeoTranslation t = *this;
676 t *= right;
677 return t;
678}
679
681{
682 TGeoHMatrix t = *this;
683 t *= right;
684 return t;
685}
686
687////////////////////////////////////////////////////////////////////////////////
688/// Is-equal operator
689
691{
692 if (&other == this)
693 return kTRUE;
694 const Double_t *tr = GetTranslation();
695 const Double_t *otr = other.GetTranslation();
696 for (auto i = 0; i < 3; i++)
697 if (TMath::Abs(tr[i] - otr[i]) > 1.E-10)
698 return kFALSE;
699 return kTRUE;
700}
701
702////////////////////////////////////////////////////////////////////////////////
703/// Return a temporary inverse of this.
704
706{
708 h = *this;
710 Double_t tr[3];
711 tr[0] = -fTranslation[0];
712 tr[1] = -fTranslation[1];
713 tr[2] = -fTranslation[2];
714 h.SetTranslation(tr);
715 return h;
716}
717
718////////////////////////////////////////////////////////////////////////////////
719/// Adding a translation to this one
720
722{
723 const Double_t *trans = other->GetTranslation();
724 for (Int_t i = 0; i < 3; i++)
725 fTranslation[i] += trans[i];
726}
727
728////////////////////////////////////////////////////////////////////////////////
729/// Make a clone of this matrix.
730
732{
733 TGeoMatrix *matrix = new TGeoTranslation(*this);
734 return matrix;
735}
736
737////////////////////////////////////////////////////////////////////////////////
738/// Rotate about X axis of the master frame with angle expressed in degrees.
739
741{
742 Warning("RotateX", "Not implemented. Use TGeoCombiTrans instead");
743}
744
745////////////////////////////////////////////////////////////////////////////////
746/// Rotate about Y axis of the master frame with angle expressed in degrees.
747
749{
750 Warning("RotateY", "Not implemented. Use TGeoCombiTrans instead");
751}
752
753////////////////////////////////////////////////////////////////////////////////
754/// Rotate about Z axis of the master frame with angle expressed in degrees.
755
757{
758 Warning("RotateZ", "Not implemented. Use TGeoCombiTrans instead");
759}
760
761////////////////////////////////////////////////////////////////////////////////
762/// Subtracting a translation from this one
763
765{
766 const Double_t *trans = other->GetTranslation();
767 for (Int_t i = 0; i < 3; i++)
768 fTranslation[i] -= trans[i];
769}
770
771////////////////////////////////////////////////////////////////////////////////
772/// Set translation components
773
784
785////////////////////////////////////////////////////////////////////////////////
786/// Set translation components
787
789{
790 SetBit(kGeoTranslation, other.IsTranslation());
791 const Double_t *transl = other.GetTranslation();
793}
794
795////////////////////////////////////////////////////////////////////////////////
796/// convert a point by multiplying its column vector (x, y, z, 1) to matrix inverse
797
799{
800 const Double_t *tr = GetTranslation();
801 for (Int_t i = 0; i < 3; i++)
802 master[i] = tr[i] + local[i];
803}
804
805////////////////////////////////////////////////////////////////////////////////
806/// convert a vector to MARS
807
812
813////////////////////////////////////////////////////////////////////////////////
814/// convert a point by multiplying its column vector (x, y, z, 1) to matrix inverse
815
817{
818 const Double_t *tr = GetTranslation();
819 Double_t bombtr[3] = {0., 0., 0.};
821 for (Int_t i = 0; i < 3; i++)
822 master[i] = bombtr[i] + local[i];
823}
824
825////////////////////////////////////////////////////////////////////////////////
826/// convert a point by multiplying its column vector (x, y, z, 1) to matrix
827
829{
830 const Double_t *tr = GetTranslation();
831 for (Int_t i = 0; i < 3; i++)
832 local[i] = master[i] - tr[i];
833}
834
835////////////////////////////////////////////////////////////////////////////////
836/// convert a vector from MARS to local
837
842
843////////////////////////////////////////////////////////////////////////////////
844/// convert a point by multiplying its column vector (x, y, z, 1) to matrix
845
847{
848 const Double_t *tr = GetTranslation();
849 Double_t bombtr[3] = {0., 0., 0.};
851 for (Int_t i = 0; i < 3; i++)
852 local[i] = master[i] - bombtr[i];
853}
854
855////////////////////////////////////////////////////////////////////////////////
856/// Save a primitive as a C++ statement(s) on output stream "out".
857
858void TGeoTranslation::SavePrimitive(std::ostream &out, Option_t * /*option*/ /*= ""*/)
859{
861 return;
862 out << " // Translation: " << GetName() << std::endl;
863 out << " dx = " << fTranslation[0] << ";" << std::endl;
864 out << " dy = " << fTranslation[1] << ";" << std::endl;
865 out << " dz = " << fTranslation[2] << ";" << std::endl;
866 out << " TGeoTranslation *" << GetPointerName() << " = new TGeoTranslation(\"" << GetName() << "\",dx,dy,dz);"
867 << std::endl;
869}
870
871/** \class TGeoRotation
872\ingroup Geometry_classes
873Class describing rotations. A rotation is a 3*3 array
874Column vectors has to be orthogonal unit vectors.
875*/
876
877////////////////////////////////////////////////////////////////////////////////
878/// Default constructor.
879
881{
882 for (Int_t i = 0; i < 9; i++) {
883 if (i % 4)
884 fRotationMatrix[i] = 0;
885 else
886 fRotationMatrix[i] = 1.0;
887 }
888}
889
890////////////////////////////////////////////////////////////////////////////////
891/// Copy ctor.
892
897
898////////////////////////////////////////////////////////////////////////////////
899/// Copy ctor.
900
907
908////////////////////////////////////////////////////////////////////////////////
909/// Named rotation constructor
910
912{
913 for (Int_t i = 0; i < 9; i++) {
914 if (i % 4)
915 fRotationMatrix[i] = 0;
916 else
917 fRotationMatrix[i] = 1.0;
918 }
919}
920
921////////////////////////////////////////////////////////////////////////////////
922/// Default rotation constructor with Euler angles. Phi is the rotation angle about
923/// Z axis and is done first, theta is the rotation about new X and is done
924/// second, psi is the rotation angle about new Z and is done third. All angles are in
925/// degrees.
926
928{
929 SetAngles(phi, theta, psi);
930}
931
932////////////////////////////////////////////////////////////////////////////////
933/// Rotation constructor a la GEANT3. Angles theta(i), phi(i) are the polar and azimuthal
934/// angles of the (i) axis of the rotated system with respect to the initial non-rotated
935/// system.
936/// Example : the identity matrix (no rotation) is composed by
937/// theta1=90, phi1=0, theta2=90, phi2=90, theta3=0, phi3=0
938/// SetBit(kGeoRotation);
939
946
947////////////////////////////////////////////////////////////////////////////////
948/// Assignment from a general matrix
949
962
963////////////////////////////////////////////////////////////////////////////////
964/// Composition
965
967{
968 if (!right.IsRotation())
969 return *this;
970 MultiplyBy(&right, true);
971 return *this;
972}
973
975{
976 TGeoRotation r = *this;
977 r *= right;
978 return r;
979}
980
982{
983 TGeoHMatrix t = *this;
984 t *= right;
985 return t;
986}
987
988////////////////////////////////////////////////////////////////////////////////
989/// Is-equal operator
990
992{
993 if (&other == this)
994 return kTRUE;
995 const Double_t *rot = GetRotationMatrix();
996 const Double_t *orot = other.GetRotationMatrix();
997 for (auto i = 0; i < 9; i++)
998 if (TMath::Abs(rot[i] - orot[i]) > 1.E-10)
999 return kFALSE;
1000 return kTRUE;
1001}
1002
1003////////////////////////////////////////////////////////////////////////////////
1004/// Return a temporary inverse of this.
1005
1007{
1008 TGeoHMatrix h;
1009 h = *this;
1011 Double_t newrot[9];
1012 newrot[0] = fRotationMatrix[0];
1013 newrot[1] = fRotationMatrix[3];
1014 newrot[2] = fRotationMatrix[6];
1015 newrot[3] = fRotationMatrix[1];
1016 newrot[4] = fRotationMatrix[4];
1017 newrot[5] = fRotationMatrix[7];
1018 newrot[6] = fRotationMatrix[2];
1019 newrot[7] = fRotationMatrix[5];
1020 newrot[8] = fRotationMatrix[8];
1021 h.SetRotation(newrot);
1022 return h;
1023}
1024
1025////////////////////////////////////////////////////////////////////////////////
1026/// Perform orthogonality test for rotation.
1027
1029{
1030 const Double_t *r = fRotationMatrix;
1031 Double_t cij;
1032 for (Int_t i = 0; i < 2; i++) {
1033 for (Int_t j = i + 1; j < 3; j++) {
1034 // check columns
1035 cij = TMath::Abs(r[i] * r[j] + r[i + 3] * r[j + 3] + r[i + 6] * r[j + 6]);
1036 if (cij > 1E-4)
1037 return kFALSE;
1038 // check rows
1039 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]);
1040 if (cij > 1E-4)
1041 return kFALSE;
1042 }
1043 }
1044 return kTRUE;
1045}
1046
1047////////////////////////////////////////////////////////////////////////////////
1048/// reset data members
1049
1055
1056////////////////////////////////////////////////////////////////////////////////
1057/// Perform a rotation about Z having the sine/cosine of the rotation angle.
1058
1060{
1061 fRotationMatrix[0] = sincos[1];
1062 fRotationMatrix[1] = -sincos[0];
1063 fRotationMatrix[3] = sincos[0];
1064 fRotationMatrix[4] = sincos[1];
1066}
1067
1068////////////////////////////////////////////////////////////////////////////////
1069/// Returns rotation angle about Z axis in degrees. If the rotation is a pure
1070/// rotation about Z, fixX parameter does not matter, otherwise its meaning is:
1071/// - fixX = true : result is the phi angle of the projection of the rotated X axis in the un-rotated XY
1072/// - fixX = false : result is the phi angle of the projection of the rotated Y axis - 90 degrees
1073
1075{
1076 Double_t phi;
1077 if (fixX)
1078 phi = 180. * TMath::ATan2(-fRotationMatrix[1], fRotationMatrix[4]) / TMath::Pi();
1079 else
1080 phi = 180. * TMath::ATan2(fRotationMatrix[3], fRotationMatrix[0]) / TMath::Pi();
1081 return phi;
1082}
1083
1084////////////////////////////////////////////////////////////////////////////////
1085/// convert a point by multiplying its column vector (x, y, z, 1) to matrix inverse
1086
1088{
1089 const Double_t *rot = GetRotationMatrix();
1090 for (Int_t i = 0; i < 3; i++) {
1091 master[i] = local[0] * rot[3 * i] + local[1] * rot[3 * i + 1] + local[2] * rot[3 * i + 2];
1092 }
1093}
1094
1095////////////////////////////////////////////////////////////////////////////////
1096/// convert a point by multiplying its column vector (x, y, z, 1) to matrix
1097
1099{
1100 const Double_t *rot = GetRotationMatrix();
1101 for (Int_t i = 0; i < 3; i++) {
1102 local[i] = master[0] * rot[i] + master[1] * rot[i + 3] + master[2] * rot[i + 6];
1103 }
1104}
1105
1106////////////////////////////////////////////////////////////////////////////////
1107/// Make a clone of this matrix.
1108
1110{
1111 TGeoMatrix *matrix = new TGeoRotation(*this);
1112 return matrix;
1113}
1114
1115////////////////////////////////////////////////////////////////////////////////
1116/// Rotate about X axis of the master frame with angle expressed in degrees.
1117
1119{
1121 Double_t phi = angle * TMath::DegToRad();
1122 Double_t c = TMath::Cos(phi);
1123 Double_t s = TMath::Sin(phi);
1124 Double_t v[9];
1125 v[0] = fRotationMatrix[0];
1126 v[1] = fRotationMatrix[1];
1127 v[2] = fRotationMatrix[2];
1128 v[3] = c * fRotationMatrix[3] - s * fRotationMatrix[6];
1129 v[4] = c * fRotationMatrix[4] - s * fRotationMatrix[7];
1130 v[5] = c * fRotationMatrix[5] - s * fRotationMatrix[8];
1131 v[6] = s * fRotationMatrix[3] + c * fRotationMatrix[6];
1132 v[7] = s * fRotationMatrix[4] + c * fRotationMatrix[7];
1133 v[8] = s * fRotationMatrix[5] + c * fRotationMatrix[8];
1134
1136}
1137
1138////////////////////////////////////////////////////////////////////////////////
1139/// Rotate about Y axis of the master frame with angle expressed in degrees.
1140
1142{
1144 Double_t phi = angle * TMath::DegToRad();
1145 Double_t c = TMath::Cos(phi);
1146 Double_t s = TMath::Sin(phi);
1147 Double_t v[9];
1148 v[0] = c * fRotationMatrix[0] + s * fRotationMatrix[6];
1149 v[1] = c * fRotationMatrix[1] + s * fRotationMatrix[7];
1150 v[2] = c * fRotationMatrix[2] + s * fRotationMatrix[8];
1151 v[3] = fRotationMatrix[3];
1152 v[4] = fRotationMatrix[4];
1153 v[5] = fRotationMatrix[5];
1154 v[6] = -s * fRotationMatrix[0] + c * fRotationMatrix[6];
1155 v[7] = -s * fRotationMatrix[1] + c * fRotationMatrix[7];
1156 v[8] = -s * fRotationMatrix[2] + c * fRotationMatrix[8];
1157
1159}
1160
1161////////////////////////////////////////////////////////////////////////////////
1162/// Rotate about Z axis of the master frame with angle expressed in degrees.
1163
1165{
1167 Double_t phi = angle * TMath::DegToRad();
1168 Double_t c = TMath::Cos(phi);
1169 Double_t s = TMath::Sin(phi);
1170 Double_t v[9];
1171 v[0] = c * fRotationMatrix[0] - s * fRotationMatrix[3];
1172 v[1] = c * fRotationMatrix[1] - s * fRotationMatrix[4];
1173 v[2] = c * fRotationMatrix[2] - s * fRotationMatrix[5];
1174 v[3] = s * fRotationMatrix[0] + c * fRotationMatrix[3];
1175 v[4] = s * fRotationMatrix[1] + c * fRotationMatrix[4];
1176 v[5] = s * fRotationMatrix[2] + c * fRotationMatrix[5];
1177 v[6] = fRotationMatrix[6];
1178 v[7] = fRotationMatrix[7];
1179 v[8] = fRotationMatrix[8];
1180
1181 memcpy(&fRotationMatrix[0], v, kN9);
1182}
1183
1184////////////////////////////////////////////////////////////////////////////////
1185/// Multiply by a reflection respect to YZ.
1186
1201
1202////////////////////////////////////////////////////////////////////////////////
1203/// Multiply by a reflection respect to ZX.
1204
1219
1220////////////////////////////////////////////////////////////////////////////////
1221/// Multiply by a reflection respect to XY.
1222
1237
1238////////////////////////////////////////////////////////////////////////////////
1239/// Save a primitive as a C++ statement(s) on output stream "out".
1240
1241void TGeoRotation::SavePrimitive(std::ostream &out, Option_t * /*option*/ /*= ""*/)
1242{
1244 return;
1245 out << " // Rotation: " << GetName() << std::endl;
1246 Double_t th1, ph1, th2, ph2, th3, ph3;
1247 GetAngles(th1, ph1, th2, ph2, th3, ph3);
1248 out << " thx = " << th1 << "; phx = " << ph1 << ";" << std::endl;
1249 out << " thy = " << th2 << "; phy = " << ph2 << ";" << std::endl;
1250 out << " thz = " << th3 << "; phz = " << ph3 << ";" << std::endl;
1251 out << " TGeoRotation *" << GetPointerName() << " = new TGeoRotation(\"" << GetName()
1252 << "\",thx,phx,thy,phy,thz,phz);" << std::endl;
1254}
1255
1256////////////////////////////////////////////////////////////////////////////////
1257/// Copy rotation elements from other rotation matrix.
1258
1260{
1261 SetBit(kGeoRotation, other.IsRotation());
1262 SetMatrix(other.GetRotationMatrix());
1263}
1264
1265////////////////////////////////////////////////////////////////////////////////
1266/// Set matrix elements according to Euler angles. Phi is the rotation angle about
1267/// Z axis and is done first, theta is the rotation about new X and is done
1268/// second, psi is the rotation angle about new Z and is done third. All angles are in
1269/// degrees.
1270
1272{
1273 Double_t degrad = TMath::Pi() / 180.;
1276 Double_t sinthe = TMath::Sin(degrad * theta);
1277 Double_t costhe = TMath::Cos(degrad * theta);
1280
1290
1291 if (!IsValid())
1292 Error("SetAngles", "invalid rotation (Euler angles : phi=%f theta=%f psi=%f)", phi, theta, psi);
1293 CheckMatrix();
1294}
1295
1296////////////////////////////////////////////////////////////////////////////////
1297/// Set matrix elements in the GEANT3 way
1298
1300 Double_t phi3)
1301{
1302 Double_t degrad = TMath::Pi() / 180.;
1312 // do the trick to eliminate most of the floating point errors
1313 for (Int_t i = 0; i < 9; i++) {
1314 if (TMath::Abs(fRotationMatrix[i]) < 1E-15)
1315 fRotationMatrix[i] = 0;
1316 if (TMath::Abs(fRotationMatrix[i] - 1) < 1E-15)
1317 fRotationMatrix[i] = 1;
1318 if (TMath::Abs(fRotationMatrix[i] + 1) < 1E-15)
1319 fRotationMatrix[i] = -1;
1320 }
1321 if (!IsValid())
1322 Error("SetAngles", "invalid rotation (G3 angles, th1=%f phi1=%f, th2=%f ph2=%f, th3=%f phi3=%f)", theta1, phi1,
1323 theta2, phi2, theta3, phi3);
1324 CheckMatrix();
1325}
1326
1327////////////////////////////////////////////////////////////////////////////////
1328/// Retrieve rotation angles
1329
1331 Double_t &phi3) const
1332{
1333 Double_t raddeg = 180. / TMath::Pi();
1337 if (TMath::Abs(fRotationMatrix[0]) < 1E-6 && TMath::Abs(fRotationMatrix[3]) < 1E-6)
1338 phi1 = 0.;
1339 else
1341 if (phi1 < 0)
1342 phi1 += 360.;
1343 if (TMath::Abs(fRotationMatrix[1]) < 1E-6 && TMath::Abs(fRotationMatrix[4]) < 1E-6)
1344 phi2 = 0.;
1345 else
1347 if (phi2 < 0)
1348 phi2 += 360.;
1349 if (TMath::Abs(fRotationMatrix[2]) < 1E-6 && TMath::Abs(fRotationMatrix[5]) < 1E-6)
1350 phi3 = 0.;
1351 else
1353 if (phi3 < 0)
1354 phi3 += 360.;
1355}
1356
1357////////////////////////////////////////////////////////////////////////////////
1358/// Retrieve Euler angles.
1359
1361{
1362 const Double_t *m = fRotationMatrix;
1363 // Check if theta is 0 or 180.
1364 if (TMath::Abs(1. - TMath::Abs(m[8])) < 1.e-9) {
1365 theta = TMath::ACos(m[8]) * TMath::RadToDeg();
1366 phi = TMath::ATan2(-m[8] * m[1], m[0]) * TMath::RadToDeg();
1367 psi = 0.; // convention, phi+psi matters
1368 return;
1369 }
1370 // sin(theta) != 0
1371 phi = TMath::ATan2(m[2], -m[5]);
1372 Double_t sphi = TMath::Sin(phi);
1373 if (TMath::Abs(sphi) < 1.e-9)
1374 theta = -TMath::ASin(m[5] / TMath::Cos(phi)) * TMath::RadToDeg();
1375 else
1376 theta = TMath::ASin(m[2] / sphi) * TMath::RadToDeg();
1377 phi *= TMath::RadToDeg();
1378 psi = TMath::ATan2(m[6], m[7]) * TMath::RadToDeg();
1379}
1380
1381////////////////////////////////////////////////////////////////////////////////
1382/// computes determinant of the rotation matrix
1383
1394
1395////////////////////////////////////////////////////////////////////////////////
1396/// performes an orthogonality check and finds if the matrix is a reflection
1397/// Warning("CheckMatrix", "orthogonality check not performed yet");
1398
1400{
1401 if (Determinant() < 0)
1404 if (TMath::Abs(dd) < 1.E-12)
1406 else
1408}
1409
1410////////////////////////////////////////////////////////////////////////////////
1411/// Get the inverse rotation matrix (which is simply the transpose)
1412
1414{
1415 if (!invmat) {
1416 Error("GetInverse", "no place to store the inverse matrix");
1417 return;
1418 }
1419 for (Int_t i = 0; i < 3; i++) {
1420 for (Int_t j = 0; j < 3; j++) {
1421 invmat[3 * i + j] = fRotationMatrix[3 * j + i];
1422 }
1423 }
1424}
1425
1426////////////////////////////////////////////////////////////////////////////////
1427/// Multiply this rotation with the one specified by ROT.
1428/// - after=TRUE (default): THIS*ROT
1429/// - after=FALSE : ROT*THIS
1430
1432{
1433 const Double_t *matleft, *matright;
1435 Double_t newmat[9] = {0};
1436 if (after) {
1438 matright = rot->GetRotationMatrix();
1439 } else {
1440 matleft = rot->GetRotationMatrix();
1442 }
1443 for (Int_t i = 0; i < 3; i++) {
1444 for (Int_t j = 0; j < 3; j++) {
1445 for (Int_t k = 0; k < 3; k++) {
1446 newmat[3 * i + j] += matleft[3 * i + k] * matright[3 * k + j];
1447 }
1448 }
1449 }
1450 memcpy(&fRotationMatrix[0], &newmat[0], kN9);
1451}
1452
1453/** \class TGeoScale
1454\ingroup Geometry_classes
1455Class describing scale transformations. A scale is an
1456array of 3 doubles (sx, sy, sz) multiplying elements 0, 5 and 10
1457of the homogenous matrix. A scale is normalized : sx*sy*sz = 1
1458*/
1459
1460////////////////////////////////////////////////////////////////////////////////
1461/// default constructor
1462
1464{
1466 for (Int_t i = 0; i < 3; i++)
1467 fScale[i] = 1.;
1468}
1469
1470////////////////////////////////////////////////////////////////////////////////
1471/// Copy constructor
1472
1477
1478////////////////////////////////////////////////////////////////////////////////
1479/// Ctor. based on a general matrix
1480
1487
1488////////////////////////////////////////////////////////////////////////////////
1489/// default constructor
1490
1496
1497////////////////////////////////////////////////////////////////////////////////
1498/// default constructor
1499
1505
1506////////////////////////////////////////////////////////////////////////////////
1507/// destructor
1508
1510
1511////////////////////////////////////////////////////////////////////////////////
1512/// Assignment from a general matrix
1513
1515{
1516 if (&matrix == this)
1517 return *this;
1524 return *this;
1525}
1526
1527////////////////////////////////////////////////////////////////////////////////
1528/// Scale composition
1529
1531{
1532 const Double_t *scl = right.GetScale();
1533 fScale[0] *= scl[0];
1534 fScale[1] *= scl[1];
1535 fScale[2] *= scl[2];
1536 SetBit(kGeoReflection, fScale[0] * fScale[1] * fScale[2] < 0);
1537 if (!IsScale())
1538 SetBit(kGeoScale, right.IsScale());
1539 return *this;
1540}
1541
1543{
1544 TGeoScale s = *this;
1545 s *= right;
1546 return s;
1547}
1548
1550{
1551 TGeoHMatrix t = *this;
1552 t *= right;
1553 return t;
1554}
1555
1556////////////////////////////////////////////////////////////////////////////////
1557/// Is-equal operator
1558
1560{
1561 if (&other == this)
1562 return kTRUE;
1563 const Double_t *scl = GetScale();
1564 const Double_t *oscl = other.GetScale();
1565 for (auto i = 0; i < 3; i++)
1566 if (TMath::Abs(scl[i] - oscl[i]) > 1.E-10)
1567 return kFALSE;
1568 return kTRUE;
1569}
1570
1571////////////////////////////////////////////////////////////////////////////////
1572/// Return a temporary inverse of this.
1573
1575{
1576 TGeoHMatrix h;
1577 h = *this;
1579 Double_t scale[3];
1580 scale[0] = 1. / fScale[0];
1581 scale[1] = 1. / fScale[1];
1582 scale[2] = 1. / fScale[2];
1583 h.SetScale(scale);
1584 return h;
1585}
1586
1587////////////////////////////////////////////////////////////////////////////////
1588/// scale setter
1589
1591{
1592 if (TMath::Abs(sx * sy * sz) < 1.E-10) {
1593 Error("SetScale", "Invalid scale %f, %f, %f for transformation %s", sx, sy, sx, GetName());
1594 return;
1595 }
1596 fScale[0] = sx;
1597 fScale[1] = sy;
1598 fScale[2] = sz;
1599 if (sx * sy * sz < 0)
1601 else
1603}
1604
1605////////////////////////////////////////////////////////////////////////////////
1606/// Set scale from other transformation
1607
1609{
1610 SetBit(kGeoScale, other.IsScale());
1611 SetBit(kGeoReflection, other.IsReflection());
1612 memcpy(fScale, other.GetScale(), kN3);
1613}
1614
1615////////////////////////////////////////////////////////////////////////////////
1616/// Convert a local point to the master frame.
1617
1619{
1620 master[0] = local[0] * fScale[0];
1621 master[1] = local[1] * fScale[1];
1622 master[2] = local[2] * fScale[2];
1623}
1624
1625////////////////////////////////////////////////////////////////////////////////
1626/// Convert the local distance along unit vector DIR to master frame. If DIR
1627/// is not specified perform a conversion such as the returned distance is the
1628/// the minimum for all possible directions.
1629
1631{
1633 if (!dir) {
1634 scale = TMath::Abs(fScale[0]);
1635 if (TMath::Abs(fScale[1]) < scale)
1636 scale = TMath::Abs(fScale[1]);
1637 if (TMath::Abs(fScale[2]) < scale)
1638 scale = TMath::Abs(fScale[2]);
1639 } else {
1640 scale = fScale[0] * fScale[0] * dir[0] * dir[0] + fScale[1] * fScale[1] * dir[1] * dir[1] +
1641 fScale[2] * fScale[2] * dir[2] * dir[2];
1643 }
1644 return scale * dist;
1645}
1646
1647////////////////////////////////////////////////////////////////////////////////
1648/// Make a clone of this matrix.
1649
1651{
1652 TGeoMatrix *matrix = new TGeoScale(*this);
1653 return matrix;
1654}
1655
1656////////////////////////////////////////////////////////////////////////////////
1657/// Convert a global point to local frame.
1658
1660{
1661 local[0] = master[0] / fScale[0];
1662 local[1] = master[1] / fScale[1];
1663 local[2] = master[2] / fScale[2];
1664}
1665
1666////////////////////////////////////////////////////////////////////////////////
1667/// Convert the distance along unit vector DIR to local frame. If DIR
1668/// is not specified perform a conversion such as the returned distance is the
1669/// the minimum for all possible directions.
1670
1672{
1674 if (!dir) {
1675 scale = TMath::Abs(fScale[0]);
1676 if (TMath::Abs(fScale[1]) > scale)
1677 scale = TMath::Abs(fScale[1]);
1678 if (TMath::Abs(fScale[2]) > scale)
1679 scale = TMath::Abs(fScale[2]);
1680 scale = 1. / scale;
1681 } else {
1682 scale = (dir[0] * dir[0]) / (fScale[0] * fScale[0]) + (dir[1] * dir[1]) / (fScale[1] * fScale[1]) +
1683 (dir[2] * dir[2]) / (fScale[2] * fScale[2]);
1685 }
1686 return scale * dist;
1687}
1688
1689/** \class TGeoCombiTrans
1690\ingroup Geometry_classes
1691Class describing rotation + translation. Most frequently used in the description
1692of TGeoNode 's
1693*/
1694
1695////////////////////////////////////////////////////////////////////////////////
1696/// dummy ctor
1697
1699{
1700 for (Int_t i = 0; i < 3; i++)
1701 fTranslation[i] = 0.0;
1702 fRotation = nullptr;
1703}
1704
1705////////////////////////////////////////////////////////////////////////////////
1706/// Copy ctor from generic matrix.
1707
1709{
1711 if (other.IsTranslation()) {
1713 memcpy(fTranslation, other.GetTranslation(), kN3);
1714 } else {
1715 for (Int_t i = 0; i < 3; i++)
1716 fTranslation[i] = 0.0;
1717 }
1718 if (other.IsRotation()) {
1722 } else
1723 fRotation = nullptr;
1724}
1725
1726////////////////////////////////////////////////////////////////////////////////
1727/// Constructor from a translation and a rotation.
1728
1730{
1731 if (tr.IsTranslation()) {
1733 const Double_t *trans = tr.GetTranslation();
1734 memcpy(fTranslation, trans, kN3);
1735 } else {
1736 for (Int_t i = 0; i < 3; i++)
1737 fTranslation[i] = 0.0;
1738 }
1739 if (rot.IsRotation()) {
1742 fRotation = new TGeoRotation(rot);
1744 } else
1745 fRotation = nullptr;
1746}
1747
1748////////////////////////////////////////////////////////////////////////////////
1749/// Named ctor.
1750
1752{
1753 for (Int_t i = 0; i < 3; i++)
1754 fTranslation[i] = 0.0;
1755 fRotation = nullptr;
1756}
1757
1758////////////////////////////////////////////////////////////////////////////////
1759/// Constructor from a translation specified by X,Y,Z and a pointer to a rotation. The rotation will not be owned by
1760/// this.
1761
1768
1769////////////////////////////////////////////////////////////////////////////////
1770/// Named ctor
1771
1779
1780////////////////////////////////////////////////////////////////////////////////
1781/// Assignment operator with generic matrix.
1782
1784{
1785 if (&matrix == this)
1786 return *this;
1788 Clear();
1790
1791 if (matrix.IsTranslation()) {
1792 memcpy(fTranslation, matrix.GetTranslation(), kN3);
1793 }
1794 if (matrix.IsRotation()) {
1795 if (!fRotation) {
1796 fRotation = new TGeoRotation();
1798 } else {
1799 if (!TestBit(kGeoMatrixOwned)) {
1800 fRotation = new TGeoRotation();
1802 }
1803 }
1804 fRotation->SetMatrix(matrix.GetRotationMatrix());
1807 } else {
1809 delete fRotation;
1811 fRotation = nullptr;
1812 }
1815 return *this;
1816}
1817
1818////////////////////////////////////////////////////////////////////////////////
1819/// Is-equal operator
1820
1822{
1823 if (&other == this)
1824 return kTRUE;
1825 const Double_t *tr = GetTranslation();
1826 const Double_t *otr = other.GetTranslation();
1827 for (auto i = 0; i < 3; i++)
1828 if (TMath::Abs(tr[i] - otr[i]) > 1.E-10)
1829 return kFALSE;
1830 const Double_t *rot = GetRotationMatrix();
1831 const Double_t *orot = other.GetRotationMatrix();
1832 for (auto i = 0; i < 9; i++)
1833 if (TMath::Abs(rot[i] - orot[i]) > 1.E-10)
1834 return kFALSE;
1835 return kTRUE;
1836}
1837
1838////////////////////////////////////////////////////////////////////////////////
1839/// Composition
1840
1842{
1843 Multiply(&right);
1844 return *this;
1845}
1846
1848{
1849 TGeoHMatrix h = *this;
1850 h *= right;
1851 return h;
1852}
1853
1854////////////////////////////////////////////////////////////////////////////////
1855/// destructor
1856
1864
1865////////////////////////////////////////////////////////////////////////////////
1866/// Reset translation/rotation to identity
1867
1869{
1870 if (IsTranslation()) {
1872 memset(fTranslation, 0, kN3);
1873 }
1874 if (fRotation) {
1876 delete fRotation;
1877 fRotation = nullptr;
1878 }
1882}
1883
1884////////////////////////////////////////////////////////////////////////////////
1885/// Return a temporary inverse of this.
1886
1888{
1889 TGeoHMatrix h;
1890 h = *this;
1894 Double_t tr[3];
1895 Double_t newrot[9];
1896 const Double_t *rot = GetRotationMatrix();
1897 tr[0] = -fTranslation[0] * rot[0] - fTranslation[1] * rot[3] - fTranslation[2] * rot[6];
1898 tr[1] = -fTranslation[0] * rot[1] - fTranslation[1] * rot[4] - fTranslation[2] * rot[7];
1899 tr[2] = -fTranslation[0] * rot[2] - fTranslation[1] * rot[5] - fTranslation[2] * rot[8];
1900 h.SetTranslation(tr);
1901 newrot[0] = rot[0];
1902 newrot[1] = rot[3];
1903 newrot[2] = rot[6];
1904 newrot[3] = rot[1];
1905 newrot[4] = rot[4];
1906 newrot[5] = rot[7];
1907 newrot[6] = rot[2];
1908 newrot[7] = rot[5];
1909 newrot[8] = rot[8];
1910 h.SetRotation(newrot);
1911 h.SetBit(kGeoTranslation, is_tr);
1912 h.SetBit(kGeoRotation, is_rot);
1913 return h;
1914}
1915
1916////////////////////////////////////////////////////////////////////////////////
1917/// Make a clone of this matrix.
1918
1920{
1921 TGeoMatrix *matrix = new TGeoCombiTrans(*this);
1922 return matrix;
1923}
1924
1925////////////////////////////////////////////////////////////////////////////////
1926/// multiply to the right with an other transformation
1927/// if right is identity matrix, just return
1928
1930{
1931 if (right->IsIdentity())
1932 return;
1933 TGeoHMatrix h = *this;
1934 h.Multiply(right);
1935 operator=(h);
1936}
1937
1938////////////////////////////////////////////////////////////////////////////////
1939/// Register the matrix in the current manager, which will become the owner.
1940
1947
1948////////////////////////////////////////////////////////////////////////////////
1949/// Rotate about X axis with angle expressed in degrees.
1950
1952{
1953 if (!fRotation || !TestBit(kGeoMatrixOwned)) {
1954 if (fRotation)
1956 else
1957 fRotation = new TGeoRotation();
1959 }
1962 Double_t phi = angle * TMath::DegToRad();
1963 Double_t c = TMath::Cos(phi);
1964 Double_t s = TMath::Sin(phi);
1965 Double_t v[9];
1966 v[0] = rot[0];
1967 v[1] = rot[1];
1968 v[2] = rot[2];
1969 v[3] = c * rot[3] - s * rot[6];
1970 v[4] = c * rot[4] - s * rot[7];
1971 v[5] = c * rot[5] - s * rot[8];
1972 v[6] = s * rot[3] + c * rot[6];
1973 v[7] = s * rot[4] + c * rot[7];
1974 v[8] = s * rot[5] + c * rot[8];
1977 if (!IsTranslation())
1978 return;
1979 v[0] = fTranslation[0];
1980 v[1] = c * fTranslation[1] - s * fTranslation[2];
1981 v[2] = s * fTranslation[1] + c * fTranslation[2];
1983}
1984
1985////////////////////////////////////////////////////////////////////////////////
1986/// Rotate about Y axis with angle expressed in degrees.
1987
1989{
1990 if (!fRotation || !TestBit(kGeoMatrixOwned)) {
1991 if (fRotation)
1993 else
1994 fRotation = new TGeoRotation();
1996 }
1999 Double_t phi = angle * TMath::DegToRad();
2000 Double_t c = TMath::Cos(phi);
2001 Double_t s = TMath::Sin(phi);
2002 Double_t v[9];
2003 v[0] = c * rot[0] + s * rot[6];
2004 v[1] = c * rot[1] + s * rot[7];
2005 v[2] = c * rot[2] + s * rot[8];
2006 v[3] = rot[3];
2007 v[4] = rot[4];
2008 v[5] = rot[5];
2009 v[6] = -s * rot[0] + c * rot[6];
2010 v[7] = -s * rot[1] + c * rot[7];
2011 v[8] = -s * rot[2] + c * rot[8];
2014 if (!IsTranslation())
2015 return;
2016 v[0] = c * fTranslation[0] + s * fTranslation[2];
2017 v[1] = fTranslation[1];
2018 v[2] = -s * fTranslation[0] + c * fTranslation[2];
2020}
2021
2022////////////////////////////////////////////////////////////////////////////////
2023/// Rotate about Z axis with angle expressed in degrees.
2024
2026{
2027 if (!fRotation || !TestBit(kGeoMatrixOwned)) {
2028 if (fRotation)
2030 else
2031 fRotation = new TGeoRotation();
2033 }
2036 Double_t phi = angle * TMath::DegToRad();
2037 Double_t c = TMath::Cos(phi);
2038 Double_t s = TMath::Sin(phi);
2039 Double_t v[9];
2040 v[0] = c * rot[0] - s * rot[3];
2041 v[1] = c * rot[1] - s * rot[4];
2042 v[2] = c * rot[2] - s * rot[5];
2043 v[3] = s * rot[0] + c * rot[3];
2044 v[4] = s * rot[1] + c * rot[4];
2045 v[5] = s * rot[2] + c * rot[5];
2046 v[6] = rot[6];
2047 v[7] = rot[7];
2048 v[8] = rot[8];
2051 if (!IsTranslation())
2052 return;
2053 v[0] = c * fTranslation[0] - s * fTranslation[1];
2054 v[1] = s * fTranslation[0] + c * fTranslation[1];
2055 v[2] = fTranslation[2];
2057}
2058
2059////////////////////////////////////////////////////////////////////////////////
2060/// Multiply by a reflection respect to YZ.
2061
2077
2078////////////////////////////////////////////////////////////////////////////////
2079/// Multiply by a reflection respect to ZX.
2080
2096
2097////////////////////////////////////////////////////////////////////////////////
2098/// Multiply by a reflection respect to XY.
2099
2115
2116////////////////////////////////////////////////////////////////////////////////
2117/// Save a primitive as a C++ statement(s) on output stream "out".
2118
2119void TGeoCombiTrans::SavePrimitive(std::ostream &out, Option_t *option /*= ""*/)
2120{
2122 return;
2123 out << " // Combi transformation: " << GetName() << std::endl;
2124 out << " dx = " << fTranslation[0] << ";" << std::endl;
2125 out << " dy = " << fTranslation[1] << ";" << std::endl;
2126 out << " dz = " << fTranslation[2] << ";" << std::endl;
2127 if (fRotation && fRotation->IsRotation()) {
2129 out << " auto " << GetPointerName() << " = new TGeoCombiTrans(\"" << GetName() << "\", dx, dy, dz, "
2130 << fRotation->GetPointerName() << ");" << std::endl;
2131 } else {
2132 out << " auto " << GetPointerName() << " = new TGeoCombiTrans(\"" << GetName() << "\");" << std::endl;
2133 out << " " << GetPointerName() << "->SetTranslation(dx, dy, dz);" << std::endl;
2134 }
2136}
2137
2138////////////////////////////////////////////////////////////////////////////////
2139/// Assign a foreign rotation to the combi. The rotation is NOT owned by this.
2140
2142{
2144 delete fRotation;
2145 fRotation = nullptr;
2149 if (!rot)
2150 return;
2151 if (!rot->IsRotation())
2152 return;
2153
2157 fRotation = rr;
2158}
2159
2160////////////////////////////////////////////////////////////////////////////////
2161/// Copy the rotation from another one.
2162
2164{
2166 delete fRotation;
2167 fRotation = nullptr;
2168 if (!rot.IsRotation()) {
2172 return;
2173 }
2174
2177 fRotation = new TGeoRotation(rot);
2179}
2180
2181////////////////////////////////////////////////////////////////////////////////
2182/// copy the translation component
2183
2185{
2186 if (tr.IsTranslation()) {
2188 const Double_t *trans = tr.GetTranslation();
2189 memcpy(fTranslation, trans, kN3);
2190 } else {
2191 if (!IsTranslation())
2192 return;
2193 memset(fTranslation, 0, kN3);
2195 }
2196}
2197
2198////////////////////////////////////////////////////////////////////////////////
2199/// set the translation component
2200
2211
2212////////////////////////////////////////////////////////////////////////////////
2213/// set the translation component
2214
2216{
2217 fTranslation[0] = vect[0];
2218 fTranslation[1] = vect[1];
2219 fTranslation[2] = vect[2];
2220 if (fTranslation[0] || fTranslation[1] || fTranslation[2])
2222 else
2224}
2225
2226////////////////////////////////////////////////////////////////////////////////
2227/// get the rotation array
2228
2230{
2231 if (!fRotation)
2232 return kIdentityMatrix;
2233 return fRotation->GetRotationMatrix();
2234}
2235
2236/** \class TGeoGenTrans
2237\ingroup Geometry_classes
2238Most general transformation, holding a translation, a rotation and a scale
2239*/
2240
2241////////////////////////////////////////////////////////////////////////////////
2242/// dummy ctor
2243
2245{
2247 for (Int_t i = 0; i < 3; i++)
2248 fTranslation[i] = 0.0;
2249 for (Int_t j = 0; j < 3; j++)
2250 fScale[j] = 1.0;
2251 fRotation = nullptr;
2252}
2253
2254////////////////////////////////////////////////////////////////////////////////
2255/// constructor
2256
2258{
2260 for (Int_t i = 0; i < 3; i++)
2261 fTranslation[i] = 0.0;
2262 for (Int_t j = 0; j < 3; j++)
2263 fScale[j] = 1.0;
2264 fRotation = nullptr;
2265}
2266
2267////////////////////////////////////////////////////////////////////////////////
2268/// constructor
2269
2279
2280////////////////////////////////////////////////////////////////////////////////
2281/// constructor
2282
2292
2293////////////////////////////////////////////////////////////////////////////////
2294/// destructor
2295
2297
2298////////////////////////////////////////////////////////////////////////////////
2299/// clear the fields of this transformation
2300
2302{
2303 memset(&fTranslation[0], 0, kN3);
2304 memset(&fScale[0], 0, kN3);
2305 if (fRotation)
2306 fRotation->Clear();
2307}
2308
2309////////////////////////////////////////////////////////////////////////////////
2310/// set the scale
2311
2313{
2314 if (sx < 1.E-5 || sy < 1.E-5 || sz < 1.E-5) {
2315 Error("ctor", "Invalid scale");
2316 return;
2317 }
2318 fScale[0] = sx;
2319 fScale[1] = sy;
2320 fScale[2] = sz;
2321}
2322
2323////////////////////////////////////////////////////////////////////////////////
2324/// Return a temporary inverse of this.
2325
2327{
2328 TGeoHMatrix h = *this;
2330 return h;
2331}
2332
2333////////////////////////////////////////////////////////////////////////////////
2334/// A scale transformation should be normalized by sx*sy*sz factor
2335
2337{
2338 Double_t normfactor = fScale[0] * fScale[1] * fScale[2];
2339 if (normfactor <= 1E-5)
2340 return kFALSE;
2341 for (Int_t i = 0; i < 3; i++)
2342 fScale[i] /= normfactor;
2343 return kTRUE;
2344}
2345
2346/** \class TGeoIdentity
2347\ingroup Geometry_classes
2348An identity transformation. It holds no data member
2349and returns pointers to static null translation and identity
2350transformations for rotation and scale
2351*/
2352
2353////////////////////////////////////////////////////////////////////////////////
2354/// dummy ctor
2355
2357{
2358 if (!gGeoIdentity)
2359 gGeoIdentity = this;
2361}
2362
2363////////////////////////////////////////////////////////////////////////////////
2364/// constructor
2365
2367{
2368 if (!gGeoIdentity)
2369 gGeoIdentity = this;
2371}
2372
2373////////////////////////////////////////////////////////////////////////////////
2374/// Return a temporary inverse of this.
2375
2377{
2379 return h;
2380}
2381
2382/** \class TGeoHMatrix
2383\ingroup Geometry_classes
2384
2385Matrix class used for computing global transformations
2386Should NOT be used for node definition. An instance of this class
2387is generally used to pile-up local transformations starting from
2388the top level physical node, down to the current node.
2389*/
2390
2391////////////////////////////////////////////////////////////////////////////////
2392/// dummy ctor
2393
2400
2401////////////////////////////////////////////////////////////////////////////////
2402/// constructor
2403
2410
2411////////////////////////////////////////////////////////////////////////////////
2412/// copy constructor
2413
2415{
2416 memcpy(fTranslation, other.fTranslation, kN3);
2417 memcpy(fRotationMatrix, other.fRotationMatrix, kN9);
2418 memcpy(fScale, other.fScale, kN3);
2419}
2420
2421////////////////////////////////////////////////////////////////////////////////
2422/// copy constructor from generic matrix
2423
2425{
2426 memset(&fTranslation[0], 0, kN3);
2429 if (matrix.IsIdentity())
2430 return;
2431 if (matrix.IsTranslation())
2432 SetTranslation(matrix.GetTranslation());
2433 if (matrix.IsRotation())
2434 memcpy(fRotationMatrix, matrix.GetRotationMatrix(), kN9);
2435 if (matrix.IsScale())
2436 memcpy(fScale, matrix.GetScale(), kN3);
2437}
2438
2439////////////////////////////////////////////////////////////////////////////////
2440/// destructor
2441
2443
2444////////////////////////////////////////////////////////////////////////////////
2445/// assignment
2446
2451
2452////////////////////////////////////////////////////////////////////////////////
2453/// assignment
2454
2456{
2457 if (&matrix == this)
2458 return *this;
2459 Clear();
2462 if (matrix.IsIdentity()) {
2464 return *this;
2465 }
2466 if (matrix.IsTranslation())
2467 memcpy(fTranslation, matrix.GetTranslation(), kN3);
2468 if (matrix.IsRotation())
2469 memcpy(fRotationMatrix, matrix.GetRotationMatrix(), kN9);
2470 if (matrix.IsScale())
2471 memcpy(fScale, matrix.GetScale(), kN3);
2473 return *this;
2474}
2475
2476////////////////////////////////////////////////////////////////////////////////
2477/// Composition
2478
2480{
2481 Multiply(&right);
2482 return *this;
2483}
2484
2486{
2487 TGeoHMatrix h = *this;
2488 h *= right;
2489 return h;
2490}
2491
2492////////////////////////////////////////////////////////////////////////////////
2493/// Is-equal operator
2494
2496{
2497 if (&other == this)
2498 return kTRUE;
2499 const Double_t *tr = GetTranslation();
2500 const Double_t *otr = other.GetTranslation();
2501 for (auto i = 0; i < 3; i++)
2502 if (TMath::Abs(tr[i] - otr[i]) > 1.E-10)
2503 return kFALSE;
2504 const Double_t *rot = GetRotationMatrix();
2505 const Double_t *orot = other.GetRotationMatrix();
2506 for (auto i = 0; i < 9; i++)
2507 if (TMath::Abs(rot[i] - orot[i]) > 1.E-10)
2508 return kFALSE;
2509 const Double_t *scl = GetScale();
2510 const Double_t *oscl = other.GetScale();
2511 for (auto i = 0; i < 3; i++)
2512 if (TMath::Abs(scl[i] - oscl[i]) > 1.E-10)
2513 return kFALSE;
2514 return kTRUE;
2515}
2516
2517////////////////////////////////////////////////////////////////////////////////
2518/// Fast copy method.
2519
2521{
2522 SetBit(kGeoTranslation, other->IsTranslation());
2523 SetBit(kGeoRotation, other->IsRotation());
2524 SetBit(kGeoReflection, other->IsReflection());
2525 memcpy(fTranslation, other->GetTranslation(), kN3);
2526 memcpy(fRotationMatrix, other->GetRotationMatrix(), kN9);
2527}
2528
2529////////////////////////////////////////////////////////////////////////////////
2530/// clear the data for this matrix
2531
2544
2545////////////////////////////////////////////////////////////////////////////////
2546/// Make a clone of this matrix.
2547
2549{
2550 TGeoMatrix *matrix = new TGeoHMatrix(*this);
2551 return matrix;
2552}
2553
2554////////////////////////////////////////////////////////////////////////////////
2555/// Perform a rotation about Z having the sine/cosine of the rotation angle.
2556
2558{
2559 fRotationMatrix[0] = sincos[1];
2560 fRotationMatrix[1] = -sincos[0];
2561 fRotationMatrix[3] = sincos[0];
2562 fRotationMatrix[4] = sincos[1];
2564}
2565
2566////////////////////////////////////////////////////////////////////////////////
2567/// Return a temporary inverse of this.
2568
2570{
2571 TGeoHMatrix h;
2572 h = *this;
2574 if (IsTranslation()) {
2575 Double_t tr[3];
2582 h.SetTranslation(tr);
2583 }
2584 if (IsRotation()) {
2585 Double_t newrot[9];
2586 newrot[0] = fRotationMatrix[0];
2587 newrot[1] = fRotationMatrix[3];
2588 newrot[2] = fRotationMatrix[6];
2589 newrot[3] = fRotationMatrix[1];
2590 newrot[4] = fRotationMatrix[4];
2591 newrot[5] = fRotationMatrix[7];
2592 newrot[6] = fRotationMatrix[2];
2593 newrot[7] = fRotationMatrix[5];
2594 newrot[8] = fRotationMatrix[8];
2595 h.SetRotation(newrot);
2596 }
2597 if (IsScale()) {
2598 Double_t sc[3];
2599 sc[0] = 1. / fScale[0];
2600 sc[1] = 1. / fScale[1];
2601 sc[2] = 1. / fScale[2];
2602 h.SetScale(sc);
2603 }
2604 return h;
2605}
2606
2607////////////////////////////////////////////////////////////////////////////////
2608/// computes determinant of the rotation matrix
2609
2620
2621////////////////////////////////////////////////////////////////////////////////
2622/// multiply to the right with an other transformation
2623/// if right is identity matrix, just return
2624
2626{
2627 if (right->IsIdentity())
2628 return;
2629 const Double_t *r_tra = right->GetTranslation();
2630 const Double_t *r_rot = right->GetRotationMatrix();
2631 const Double_t *r_scl = right->GetScale();
2632 if (IsIdentity()) {
2633 if (right->IsRotation()) {
2636 if (right->IsReflection())
2638 }
2639 if (right->IsScale()) {
2642 }
2643 if (right->IsTranslation()) {
2646 }
2647 return;
2648 }
2649 Int_t i, j;
2650 Double_t new_rot[9];
2651
2652 if (right->IsRotation()) {
2654 if (right->IsReflection())
2656 }
2657 if (right->IsScale())
2659 if (right->IsTranslation())
2661
2662 // new translation
2663 if (IsTranslation()) {
2664 for (i = 0; i < 3; i++) {
2665 fTranslation[i] += fRotationMatrix[3 * i] * r_tra[0] + fRotationMatrix[3 * i + 1] * r_tra[1] +
2666 fRotationMatrix[3 * i + 2] * r_tra[2];
2667 }
2668 }
2669 if (IsRotation()) {
2670 // new rotation
2671 for (i = 0; i < 3; i++) {
2672 for (j = 0; j < 3; j++) {
2673 new_rot[3 * i + j] = fRotationMatrix[3 * i] * r_rot[j] + fRotationMatrix[3 * i + 1] * r_rot[3 + j] +
2674 fRotationMatrix[3 * i + 2] * r_rot[6 + j];
2675 }
2676 }
2678 }
2679 // new scale
2680 if (IsScale()) {
2681 for (i = 0; i < 3; i++)
2682 fScale[i] *= r_scl[i];
2683 }
2684}
2685
2686////////////////////////////////////////////////////////////////////////////////
2687/// multiply to the left with an other transformation
2688/// if right is identity matrix, just return
2689
2691{
2692 if (left == gGeoIdentity)
2693 return;
2694 const Double_t *l_tra = left->GetTranslation();
2695 const Double_t *l_rot = left->GetRotationMatrix();
2696 const Double_t *l_scl = left->GetScale();
2697 if (IsIdentity()) {
2698 if (left->IsRotation()) {
2699 if (left->IsReflection())
2703 }
2704 if (left->IsScale()) {
2707 }
2708 if (left->IsTranslation()) {
2711 }
2712 return;
2713 }
2714 Int_t i, j;
2715 Double_t new_tra[3];
2716 Double_t new_rot[9];
2717
2718 if (left->IsRotation()) {
2720 if (left->IsReflection())
2722 }
2723 if (left->IsScale())
2725 if (left->IsTranslation())
2727
2728 // new translation
2729 if (IsTranslation()) {
2730 for (i = 0; i < 3; i++) {
2731 new_tra[i] = l_tra[i] + l_rot[3 * i] * fTranslation[0] + l_rot[3 * i + 1] * fTranslation[1] +
2732 l_rot[3 * i + 2] * fTranslation[2];
2733 }
2735 }
2736 if (IsRotation()) {
2737 // new rotation
2738 for (i = 0; i < 3; i++) {
2739 for (j = 0; j < 3; j++) {
2740 new_rot[3 * i + j] = l_rot[3 * i] * fRotationMatrix[j] + l_rot[3 * i + 1] * fRotationMatrix[3 + j] +
2741 l_rot[3 * i + 2] * fRotationMatrix[6 + j];
2742 }
2743 }
2745 }
2746 // new scale
2747 if (IsScale()) {
2748 for (i = 0; i < 3; i++)
2749 fScale[i] *= l_scl[i];
2750 }
2751}
2752
2753////////////////////////////////////////////////////////////////////////////////
2754/// Rotate about X axis with angle expressed in degrees.
2755
2757{
2759 Double_t phi = angle * TMath::DegToRad();
2760 Double_t c = TMath::Cos(phi);
2761 Double_t s = TMath::Sin(phi);
2762 Double_t v[9];
2763 v[0] = fRotationMatrix[0];
2764 v[1] = fRotationMatrix[1];
2765 v[2] = fRotationMatrix[2];
2766 v[3] = c * fRotationMatrix[3] - s * fRotationMatrix[6];
2767 v[4] = c * fRotationMatrix[4] - s * fRotationMatrix[7];
2768 v[5] = c * fRotationMatrix[5] - s * fRotationMatrix[8];
2769 v[6] = s * fRotationMatrix[3] + c * fRotationMatrix[6];
2770 v[7] = s * fRotationMatrix[4] + c * fRotationMatrix[7];
2771 v[8] = s * fRotationMatrix[5] + c * fRotationMatrix[8];
2773
2774 v[0] = fTranslation[0];
2775 v[1] = c * fTranslation[1] - s * fTranslation[2];
2776 v[2] = s * fTranslation[1] + c * fTranslation[2];
2778}
2779
2780////////////////////////////////////////////////////////////////////////////////
2781/// Rotate about Y axis with angle expressed in degrees.
2782
2784{
2786 Double_t phi = angle * TMath::DegToRad();
2787 Double_t c = TMath::Cos(phi);
2788 Double_t s = TMath::Sin(phi);
2789 Double_t v[9];
2790 v[0] = c * fRotationMatrix[0] + s * fRotationMatrix[6];
2791 v[1] = c * fRotationMatrix[1] + s * fRotationMatrix[7];
2792 v[2] = c * fRotationMatrix[2] + s * fRotationMatrix[8];
2793 v[3] = fRotationMatrix[3];
2794 v[4] = fRotationMatrix[4];
2795 v[5] = fRotationMatrix[5];
2796 v[6] = -s * fRotationMatrix[0] + c * fRotationMatrix[6];
2797 v[7] = -s * fRotationMatrix[1] + c * fRotationMatrix[7];
2798 v[8] = -s * fRotationMatrix[2] + c * fRotationMatrix[8];
2800
2801 v[0] = c * fTranslation[0] + s * fTranslation[2];
2802 v[1] = fTranslation[1];
2803 v[2] = -s * fTranslation[0] + c * fTranslation[2];
2805}
2806
2807////////////////////////////////////////////////////////////////////////////////
2808/// Rotate about Z axis with angle expressed in degrees.
2809
2811{
2813 Double_t phi = angle * TMath::DegToRad();
2814 Double_t c = TMath::Cos(phi);
2815 Double_t s = TMath::Sin(phi);
2816 Double_t v[9];
2817 v[0] = c * fRotationMatrix[0] - s * fRotationMatrix[3];
2818 v[1] = c * fRotationMatrix[1] - s * fRotationMatrix[4];
2819 v[2] = c * fRotationMatrix[2] - s * fRotationMatrix[5];
2820 v[3] = s * fRotationMatrix[0] + c * fRotationMatrix[3];
2821 v[4] = s * fRotationMatrix[1] + c * fRotationMatrix[4];
2822 v[5] = s * fRotationMatrix[2] + c * fRotationMatrix[5];
2823 v[6] = fRotationMatrix[6];
2824 v[7] = fRotationMatrix[7];
2825 v[8] = fRotationMatrix[8];
2826 memcpy(&fRotationMatrix[0], v, kN9);
2827
2828 v[0] = c * fTranslation[0] - s * fTranslation[1];
2829 v[1] = s * fTranslation[0] + c * fTranslation[1];
2830 v[2] = fTranslation[2];
2832}
2833
2834////////////////////////////////////////////////////////////////////////////////
2835/// Multiply by a reflection respect to YZ.
2836
2853
2854////////////////////////////////////////////////////////////////////////////////
2855/// Multiply by a reflection respect to ZX.
2856
2873
2874////////////////////////////////////////////////////////////////////////////////
2875/// Multiply by a reflection respect to XY.
2876
2893
2894////////////////////////////////////////////////////////////////////////////////
2895/// Save a primitive as a C++ statement(s) on output stream "out".
2896
2897void TGeoHMatrix::SavePrimitive(std::ostream &out, Option_t * /*option*/ /*= ""*/)
2898{
2900 return;
2901 const Double_t *tr = fTranslation;
2902 const Double_t *rot = fRotationMatrix;
2903 out << " // HMatrix: " << GetName() << std::endl;
2904 out << " tr[0] = " << tr[0] << "; "
2905 << "tr[1] = " << tr[1] << "; "
2906 << "tr[2] = " << tr[2] << ";" << std::endl;
2907 out << " rot[0] =" << rot[0] << "; "
2908 << "rot[1] = " << rot[1] << "; "
2909 << "rot[2] = " << rot[2] << ";" << std::endl;
2910 out << " rot[3] =" << rot[3] << "; "
2911 << "rot[4] = " << rot[4] << "; "
2912 << "rot[5] = " << rot[5] << ";" << std::endl;
2913 out << " rot[6] =" << rot[6] << "; "
2914 << "rot[7] = " << rot[7] << "; "
2915 << "rot[8] = " << rot[8] << ";" << std::endl;
2916 const char *name = GetPointerName();
2917 out << " auto " << name << " = new TGeoHMatrix(\"" << GetName() << "\");" << std::endl;
2918 out << " " << name << "->SetTranslation(tr);" << std::endl;
2919 out << " " << name << "->SetRotation(rot);" << std::endl;
2920 if (IsTranslation())
2921 out << " " << name << "->SetBit(TGeoMatrix::kGeoTranslation);" << std::endl;
2922 if (IsRotation())
2923 out << " " << name << "->SetBit(TGeoMatrix::kGeoRotation);" << std::endl;
2924 if (IsReflection())
2925 out << " " << name << "->SetBit(TGeoMatrix::kGeoReflection);" << std::endl;
2927}
#define c(i)
Definition RSha256.hxx:101
#define h(i)
Definition RSha256.hxx:106
int Int_t
Signed integer 4 bytes (int)
Definition RtypesCore.h:59
constexpr Bool_t kFALSE
Definition RtypesCore.h:108
double Double_t
Double 8 bytes.
Definition RtypesCore.h:73
constexpr Bool_t kTRUE
Definition RtypesCore.h:107
const char Option_t
Option string (const char)
Definition RtypesCore.h:80
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
Option_t Option_t option
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t r
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t index
Option_t Option_t TPoint TPoint angle
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t type
char name[80]
Definition TGX11.cxx:110
R__EXTERN TGeoManager * gGeoManager
const Int_t kN3
TGeoIdentity * gGeoIdentity
const Int_t kN9
const Double_t kUnitScale[3]
Definition TGeoMatrix.h:29
const Double_t kIdentityMatrix[3 *3]
Definition TGeoMatrix.h:27
R__EXTERN TGeoIdentity * gGeoIdentity
Definition TGeoMatrix.h:538
const Double_t kNullVector[3]
Definition TGeoMatrix.h:25
Class describing rotation + translation.
Definition TGeoMatrix.h:318
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:362
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:320
TGeoRotation * fRotation
Definition TGeoMatrix.h:321
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:331
void ReflectY(Bool_t leftside, Bool_t rotonly=kFALSE) override
Multiply by a reflection respect to ZX.
~TGeoCombiTrans() override
destructor
TGeoCombiTrans operator*(const TGeoMatrix &other) const
void RotateZ(Double_t angle) override
Rotate about Z axis with angle expressed in degrees.
const Double_t * GetRotationMatrix() const override
get the rotation array
void ReflectZ(Bool_t leftside, Bool_t rotonly=kFALSE) override
Multiply by a reflection respect to XY.
void Clear(Option_t *option="") override
clear the fields of this transformation
Double_t fScale[3]
Definition TGeoMatrix.h:378
~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:459
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:530
const Double_t * GetRotationMatrix() const override
Definition TGeoMatrix.h:529
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:461
Bool_t operator==(const TGeoMatrix &other) const
Is-equal operator.
Double_t fRotationMatrix[9]
Definition TGeoMatrix.h:462
~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:528
TGeoHMatrix & operator=(const TGeoHMatrix &other)
Definition TGeoMatrix.h:472
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:512
Double_t fScale[3]
Definition TGeoMatrix.h:463
An identity transformation.
Definition TGeoMatrix.h:407
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:39
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:68
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:72
@ kGeoSavePrimitive
Definition TGeoMatrix.h:49
@ kGeoTranslation
Definition TGeoMatrix.h:44
@ kGeoMatrixOwned
Definition TGeoMatrix.h:50
virtual void MasterToLocal(const Double_t *master, Double_t *local) const
convert a point by multiplying its column vector (x, y, z, 1) to matrix
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:65
Bool_t IsReflection() const
Definition TGeoMatrix.h:67
Bool_t IsRotation() const
Definition TGeoMatrix.h:66
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:70
virtual const Double_t * GetScale() const =0
static void Normalize(Double_t *vect)
Normalize a vector.
Bool_t IsIdentity() const
Definition TGeoMatrix.h:64
const char * GetPointerName() const
Provide a pointer name containing uid.
Bool_t IsCombi() const
Definition TGeoMatrix.h:71
Bool_t IsRegistered() const
Definition TGeoMatrix.h:73
Bool_t IsShared() const
Definition TGeoMatrix.h:69
virtual const Double_t * GetRotationMatrix() const =0
virtual Int_t GetByteCount() const
Get total size in bytes of this.
void GetWorldAxes(ROOT::Math::XYZVector &ax, ROOT::Math::XYZVector &ay, ROOT::Math::XYZVector &az) const
Extract world-space axes of a placed TGeoBBox.
~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:169
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:240
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:231
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:171
void SetRotation(const TGeoMatrix &other)
Copy rotation elements from other rotation matrix.
TGeoRotation & operator=(const TGeoRotation &other)
Definition TGeoMatrix.h:186
TGeoHMatrix Inverse() const override
Return a temporary inverse of this.
Class describing scale transformations.
Definition TGeoMatrix.h:254
TGeoScale()
default constructor
const Double_t * GetScale() const override
Definition TGeoMatrix.h:306
TGeoScale & operator=(const TGeoScale &other)
Definition TGeoMatrix.h:265
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:256
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:117
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:128
Double_t fTranslation[3]
Definition TGeoMatrix.h:119
const Double_t * GetTranslation() const override
Definition TGeoMatrix.h:155
void MasterToLocal(const Double_t *master, Double_t *local) const override
convert a point by multiplying its column vector (x, y, z, 1) to matrix
void LocalToMasterBomb(const Double_t *local, Double_t *master) const override
convert a point by multiplying its column vector (x, y, z, 1) to matrix inverse
void SavePrimitive(std::ostream &out, Option_t *option="") override
Save a primitive as a C++ statement(s) on output stream "out".
TGeoTranslation()
Default constructor.
void Subtract(const TGeoTranslation *other)
Subtracting a translation from this one.
TGeoMatrix * MakeClone() const override
Make a clone of this matrix.
void MasterToLocalVect(const Double_t *master, Double_t *local) const override
convert a vector from MARS to local
TGeoHMatrix Inverse() const override
Return a temporary inverse of this.
The TNamed class is the base class for all named ROOT classes.
Definition TNamed.h:29
const char * GetName() const override
Returns name of object.
Definition TNamed.h:49
const char * GetTitle() const override
Returns title of object.
Definition TNamed.h:50
virtual void SetName(const char *name)
Set the name of the TNamed.
Definition TNamed.cxx:149
TNamed & operator=(const TNamed &rhs)
TNamed assignment operator.
Definition TNamed.cxx:50
An array of TObjects.
Definition TObjArray.h:31
TObject * Remove(TObject *obj) override
Remove object from array.
R__ALWAYS_INLINE Bool_t TestBit(UInt_t f) const
Definition TObject.h:202
virtual UInt_t GetUniqueID() const
Return the unique object id.
Definition TObject.cxx:475
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition TObject.cxx:1074
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
Definition TObject.cxx:881
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition TObject.cxx:1088
void ResetBit(UInt_t f)
Definition TObject.h:201
Basic string class.
Definition TString.h:138
static TString Format(const char *fmt,...)
Static method which formats a string using a printf style format descriptor and return a TString.
Definition TString.cxx:2384
Double_t ACos(Double_t)
Returns the principal value of the arc cosine of x, expressed in radians.
Definition TMath.h:643
Double_t ASin(Double_t)
Returns the principal value of the arc sine of x, expressed in radians.
Definition TMath.h:635
Double_t ATan2(Double_t y, Double_t x)
Returns the principal value of the arc tangent of y/x, expressed in radians.
Definition TMath.h:657
constexpr Double_t DegToRad()
Conversion from degree to radian: .
Definition TMath.h:82
Double_t Sqrt(Double_t x)
Returns the square root of x.
Definition TMath.h:673
Double_t Cos(Double_t)
Returns the cosine of an angle of x radians.
Definition TMath.h:605
constexpr Double_t Pi()
Definition TMath.h:40
Double_t Sin(Double_t)
Returns the sine of an angle of x radians.
Definition TMath.h:599
constexpr Double_t RadToDeg()
Conversion from radian to degree: .
Definition TMath.h:75
Short_t Abs(Short_t d)
Returns the absolute value of parameter Short_t d.
Definition TMathBase.h:122
auto * th3
Definition textalign.C:22
auto * th2
Definition textalign.C:18
auto * th1
Definition textalign.C:14
TMarker m
Definition textangle.C:8