220 TGeoIdentity *gGeoIdentity = 0;
221 const Int_t kN3 = 3*
sizeof(Double_t);
222 const Int_t kN9 = 9*
sizeof(Double_t);
226 ClassImp(TGeoMatrix);
231 TGeoMatrix::TGeoMatrix()
233 ResetBit(kGeoMatrixBits);
239 TGeoMatrix::TGeoMatrix(
const TGeoMatrix &other)
242 ResetBit(kGeoRegistered);
248 TGeoMatrix::TGeoMatrix(
const char *name)
256 TGeoMatrix::~TGeoMatrix()
258 if (IsRegistered() && gGeoManager) {
259 if (!gGeoManager->IsCleaning()) {
260 gGeoManager->GetListOfMatrices()->Remove(
this);
261 Warning(
"dtor",
"Registered matrix %s was removed", GetName());
269 Bool_t TGeoMatrix::IsRotAboutZ()
const
271 if (IsIdentity())
return kTRUE;
272 const Double_t *rot = GetRotationMatrix();
273 if (TMath::Abs(rot[6])>1E-9)
return kFALSE;
274 if (TMath::Abs(rot[7])>1E-9)
return kFALSE;
275 if ((1.-TMath::Abs(rot[8]))>1E-9)
return kFALSE;
282 Int_t TGeoMatrix::GetByteCount()
const
284 Int_t count = 4+28+strlen(GetName())+strlen(GetTitle());
285 if (IsTranslation()) count += 12;
286 if (IsScale()) count += 12;
287 if (IsCombi() || IsGeneral()) count += 4 + 36;
294 char *TGeoMatrix::GetPointerName()
const
297 name = TString::Format(
"pMatrix%d", GetUniqueID());
298 return (
char*)name.Data();
314 void TGeoMatrix::GetHomogenousMatrix(Double_t *hmat)
const
316 Double_t *hmatrix = hmat;
317 const Double_t *mat = GetRotationMatrix();
318 for (Int_t i=0; i<3; i++) {
319 memcpy(hmatrix, mat, kN3);
325 memcpy(hmatrix, GetTranslation(), kN3);
328 for (Int_t i=0; i<3; i++) {
329 *hmatrix *= GetScale()[i];
339 void TGeoMatrix::LocalToMaster(
const Double_t *local, Double_t *master)
const
342 memcpy(master, local, kN3);
346 const Double_t *tr = GetTranslation();
348 for (i=0; i<3; i++) master[i] = tr[i] + local[i];
351 const Double_t *rot = GetRotationMatrix();
352 for (i=0; i<3; i++) {
355 + local[1]*rot[3*i+1]
356 + local[2]*rot[3*i+2];
363 void TGeoMatrix::LocalToMasterVect(
const Double_t *local, Double_t *master)
const
366 memcpy(master, local, kN3);
369 const Double_t *rot = GetRotationMatrix();
370 for (Int_t i=0; i<3; i++) {
371 master[i] = local[0]*rot[3*i]
372 + local[1]*rot[3*i+1]
373 + local[2]*rot[3*i+2];
380 void TGeoMatrix::LocalToMasterBomb(
const Double_t *local, Double_t *master)
const
383 memcpy(master, local, kN3);
387 const Double_t *tr = GetTranslation();
388 Double_t bombtr[3] = {0.,0.,0.};
389 gGeoManager->BombTranslation(tr, &bombtr[0]);
391 for (i=0; i<3; i++) master[i] = bombtr[i] + local[i];
394 const Double_t *rot = GetRotationMatrix();
395 for (i=0; i<3; i++) {
396 master[i] = bombtr[i]
398 + local[1]*rot[3*i+1]
399 + local[2]*rot[3*i+2];
406 void TGeoMatrix::MasterToLocal(
const Double_t *master, Double_t *local)
const
409 memcpy(local, master, kN3);
412 const Double_t *tr = GetTranslation();
413 Double_t mt0 = master[0]-tr[0];
414 Double_t mt1 = master[1]-tr[1];
415 Double_t mt2 = master[2]-tr[2];
422 const Double_t *rot = GetRotationMatrix();
423 local[0] = mt0*rot[0] + mt1*rot[3] + mt2*rot[6];
424 local[1] = mt0*rot[1] + mt1*rot[4] + mt2*rot[7];
425 local[2] = mt0*rot[2] + mt1*rot[5] + mt2*rot[8];
431 void TGeoMatrix::MasterToLocalVect(
const Double_t *master, Double_t *local)
const
434 memcpy(local, master, kN3);
437 const Double_t *rot = GetRotationMatrix();
438 for (Int_t i=0; i<3; i++) {
439 local[i] = master[0]*rot[i]
441 + master[2]*rot[i+6];
448 void TGeoMatrix::MasterToLocalBomb(
const Double_t *master, Double_t *local)
const
451 memcpy(local, master, kN3);
454 const Double_t *tr = GetTranslation();
455 Double_t bombtr[3] = {0.,0.,0.};
457 gGeoManager->UnbombTranslation(tr, &bombtr[0]);
459 for (i=0; i<3; i++) local[i] = master[i]-bombtr[i];
462 const Double_t *rot = GetRotationMatrix();
463 for (i=0; i<3; i++) {
464 local[i] = (master[0]-bombtr[0])*rot[i]
465 + (master[1]-bombtr[1])*rot[i+3]
466 + (master[2]-bombtr[2])*rot[i+6];
473 void TGeoMatrix::Normalize(Double_t *vect)
475 Double_t normfactor = vect[0]*vect[0] + vect[1]*vect[1] + vect[2]*vect[2];
476 if (normfactor <= 1E-10)
return;
477 normfactor = 1./TMath::Sqrt(normfactor);
478 vect[0] *= normfactor;
479 vect[1] *= normfactor;
480 vect[2] *= normfactor;
486 void TGeoMatrix::Print(Option_t *)
const
488 const Double_t *rot = GetRotationMatrix();
489 const Double_t *tr = GetTranslation();
490 printf(
"matrix %s - tr=%d rot=%d refl=%d scl=%d shr=%d reg=%d own=%d\n", GetName(),(Int_t)IsTranslation(),
491 (Int_t)IsRotation(), (Int_t)IsReflection(), (Int_t)IsScale(), (Int_t)IsShared(), (Int_t)IsRegistered(),
493 printf(
"%10.6f%12.6f%12.6f Tx = %10.6f\n", rot[0], rot[1], rot[2], tr[0]);
494 printf(
"%10.6f%12.6f%12.6f Ty = %10.6f\n", rot[3], rot[4], rot[5], tr[1]);
495 printf(
"%10.6f%12.6f%12.6f Tz = %10.6f\n", rot[6], rot[7], rot[8], tr[2]);
497 const Double_t *scl = GetScale();
498 printf(
"Sx=%10.6fSy=%12.6fSz=%12.6f\n", scl[0], scl[1], scl[2]);
505 void TGeoMatrix::ReflectX(Bool_t, Bool_t)
512 void TGeoMatrix::ReflectY(Bool_t, Bool_t)
519 void TGeoMatrix::ReflectZ(Bool_t, Bool_t)
526 void TGeoMatrix::RegisterYourself()
529 Warning(
"RegisterYourself",
"cannot register without geometry");
532 if (!IsRegistered()) {
533 gGeoManager->RegisterMatrix(
this);
534 SetBit(kGeoRegistered);
549 void TGeoMatrix::SetDefaultName()
551 if (!gGeoManager)
return;
552 if (strlen(GetName()))
return;
554 if (IsTranslation()) type =
't';
555 if (IsRotation()) type =
'r';
556 if (IsScale()) type =
's';
557 if (IsCombi()) type =
'c';
558 if (IsGeneral()) type =
'g';
559 TObjArray *matrices = gGeoManager->GetListOfMatrices();
561 if (matrices) index =matrices->GetEntriesFast() - 1;
562 TString name = TString::Format(
"%c%d", type, index);
574 ClassImp(TGeoTranslation);
579 TGeoTranslation::TGeoTranslation()
581 for (Int_t i=0; i<3; i++) fTranslation[i] = 0;
587 TGeoTranslation::TGeoTranslation(
const TGeoTranslation &other)
590 SetTranslation(other);
596 TGeoTranslation::TGeoTranslation(
const TGeoMatrix &other)
599 ResetBit(kGeoRotation);
601 SetTranslation(other);
607 TGeoTranslation::TGeoTranslation(Double_t dx, Double_t dy, Double_t dz)
610 if (dx || dy || dz) SetBit(kGeoTranslation);
611 SetTranslation(dx, dy, dz);
617 TGeoTranslation::TGeoTranslation(
const char *name, Double_t dx, Double_t dy, Double_t dz)
620 if (dx || dy || dz) SetBit(kGeoTranslation);
621 SetTranslation(dx, dy, dz);
627 TGeoTranslation& TGeoTranslation::operator = (
const TGeoMatrix &matrix)
629 if (&matrix ==
this)
return *
this;
630 Bool_t registered = TestBit(kGeoRegistered);
631 TNamed::operator=(matrix);
632 SetTranslation(matrix);
633 SetBit(kGeoRegistered,registered);
634 ResetBit(kGeoRotation);
642 TGeoTranslation &TGeoTranslation::operator*=(
const TGeoTranslation &right)
644 const Double_t *tr = right.GetTranslation();
645 fTranslation[0] += tr[0];
646 fTranslation[1] += tr[1];
647 fTranslation[2] += tr[2];
648 if (!IsTranslation()) SetBit(kGeoTranslation, right.IsTranslation());
652 TGeoTranslation TGeoTranslation::operator*(
const TGeoTranslation &right)
const
654 TGeoTranslation t = *
this;
659 TGeoHMatrix TGeoTranslation::operator*(
const TGeoMatrix &right)
const
661 TGeoHMatrix t = *
this;
669 Bool_t TGeoTranslation::operator ==(
const TGeoTranslation &other)
const
671 if (&other ==
this)
return kTRUE;
672 const Double_t *tr = GetTranslation();
673 const Double_t *otr = other.GetTranslation();
674 for (
auto i=0; i<3; i++)
675 if (TMath::Abs(tr[i]-otr[i])>1.E-10)
return kFALSE;
682 TGeoHMatrix TGeoTranslation::Inverse()
const
687 tr[0] = -fTranslation[0];
688 tr[1] = -fTranslation[1];
689 tr[2] = -fTranslation[2];
690 h.SetTranslation(tr);
697 void TGeoTranslation::Add(
const TGeoTranslation *other)
699 const Double_t *trans = other->GetTranslation();
700 for (Int_t i=0; i<3; i++)
701 fTranslation[i] += trans[i];
707 TGeoMatrix *TGeoTranslation::MakeClone()
const
709 TGeoMatrix *matrix =
new TGeoTranslation(*
this);
716 void TGeoTranslation::RotateX(Double_t )
718 Warning(
"RotateX",
"Not implemented. Use TGeoCombiTrans instead");
724 void TGeoTranslation::RotateY(Double_t )
726 Warning(
"RotateY",
"Not implemented. Use TGeoCombiTrans instead");
732 void TGeoTranslation::RotateZ(Double_t )
734 Warning(
"RotateZ",
"Not implemented. Use TGeoCombiTrans instead");
740 void TGeoTranslation::Subtract(
const TGeoTranslation *other)
742 const Double_t *trans = other->GetTranslation();
743 for (Int_t i=0; i<3; i++)
744 fTranslation[i] -= trans[i];
750 void TGeoTranslation::SetTranslation(Double_t dx, Double_t dy, Double_t dz)
752 fTranslation[0] = dx;
753 fTranslation[1] = dy;
754 fTranslation[2] = dz;
755 if (dx || dy || dz) SetBit(kGeoTranslation);
756 else ResetBit(kGeoTranslation);
762 void TGeoTranslation::SetTranslation(
const TGeoMatrix &other)
764 SetBit(kGeoTranslation, other.IsTranslation());
765 const Double_t *transl = other.GetTranslation();
766 memcpy(fTranslation, transl, kN3);
772 void TGeoTranslation::LocalToMaster(
const Double_t *local, Double_t *master)
const
774 const Double_t *tr = GetTranslation();
775 for (Int_t i=0; i<3; i++)
776 master[i] = tr[i] + local[i];
782 void TGeoTranslation::LocalToMasterVect(
const Double_t *local, Double_t *master)
const
784 memcpy(master, local, kN3);
790 void TGeoTranslation::LocalToMasterBomb(
const Double_t *local, Double_t *master)
const
792 const Double_t *tr = GetTranslation();
793 Double_t bombtr[3] = {0.,0.,0.};
794 gGeoManager->BombTranslation(tr, &bombtr[0]);
795 for (Int_t i=0; i<3; i++)
796 master[i] = bombtr[i] + local[i];
802 void TGeoTranslation::MasterToLocal(
const Double_t *master, Double_t *local)
const
804 const Double_t *tr = GetTranslation();
805 for (Int_t i=0; i<3; i++)
806 local[i] = master[i]-tr[i];
812 void TGeoTranslation::MasterToLocalVect(
const Double_t *master, Double_t *local)
const
814 memcpy(local, master, kN3);
820 void TGeoTranslation::MasterToLocalBomb(
const Double_t *master, Double_t *local)
const
822 const Double_t *tr = GetTranslation();
823 Double_t bombtr[3] = {0.,0.,0.};
824 gGeoManager->UnbombTranslation(tr, &bombtr[0]);
825 for (Int_t i=0; i<3; i++)
826 local[i] = master[i]-bombtr[i];
832 void TGeoTranslation::SavePrimitive(std::ostream &out, Option_t * )
834 if (TestBit(kGeoSavePrimitive))
return;
835 out <<
" // Translation: " << GetName() << std::endl;
836 out <<
" dx = " << fTranslation[0] <<
";" << std::endl;
837 out <<
" dy = " << fTranslation[1] <<
";" << std::endl;
838 out <<
" dz = " << fTranslation[2] <<
";" << std::endl;
839 out <<
" TGeoTranslation *" << GetPointerName() <<
" = new TGeoTranslation(\"" << GetName() <<
"\",dx,dy,dz);" << std::endl;
840 TObject::SetBit(kGeoSavePrimitive);
849 ClassImp(TGeoRotation);
854 TGeoRotation::TGeoRotation()
856 for (Int_t i=0; i<9; i++) {
857 if (i%4) fRotationMatrix[i] = 0;
858 else fRotationMatrix[i] = 1.0;
865 TGeoRotation::TGeoRotation(
const TGeoRotation &other)
874 TGeoRotation::TGeoRotation(
const TGeoMatrix &other)
877 ResetBit(kGeoTranslation);
885 TGeoRotation::TGeoRotation(
const char *name)
888 for (Int_t i=0; i<9; i++) {
889 if (i%4) fRotationMatrix[i] = 0;
890 else fRotationMatrix[i] = 1.0;
900 TGeoRotation::TGeoRotation(
const char *name, Double_t phi, Double_t theta, Double_t psi)
903 SetAngles(phi, theta, psi);
914 TGeoRotation::TGeoRotation(
const char *name, Double_t theta1, Double_t phi1, Double_t theta2, Double_t phi2,
915 Double_t theta3, Double_t phi3)
918 SetAngles(theta1, phi1, theta2, phi2, theta3, phi3);
924 TGeoRotation& TGeoRotation::operator = (
const TGeoMatrix &other)
926 if (&other ==
this)
return *
this;
927 Bool_t registered = TestBit(kGeoRegistered);
928 TNamed::operator=(other);
930 SetBit(kGeoRegistered,registered);
931 ResetBit(kGeoTranslation);
939 TGeoRotation &TGeoRotation::operator*=(
const TGeoRotation &right)
941 if (!right.IsRotation())
return *
this;
942 MultiplyBy(&right,
true);
946 TGeoRotation TGeoRotation::operator*(
const TGeoRotation &right)
const
948 TGeoRotation r = *
this;
953 TGeoHMatrix TGeoRotation::operator*(
const TGeoMatrix &right)
const
955 TGeoHMatrix t = *
this;
963 Bool_t TGeoRotation::operator ==(
const TGeoRotation &other)
const
965 if (&other ==
this)
return kTRUE;
966 const Double_t *rot = GetRotationMatrix();
967 const Double_t *orot = other.GetRotationMatrix();
968 for (
auto i=0; i<9; i++)
969 if (TMath::Abs(rot[i]-orot[i])>1.E-10)
return kFALSE;
976 TGeoHMatrix TGeoRotation::Inverse()
const
981 newrot[0] = fRotationMatrix[0];
982 newrot[1] = fRotationMatrix[3];
983 newrot[2] = fRotationMatrix[6];
984 newrot[3] = fRotationMatrix[1];
985 newrot[4] = fRotationMatrix[4];
986 newrot[5] = fRotationMatrix[7];
987 newrot[6] = fRotationMatrix[2];
988 newrot[7] = fRotationMatrix[5];
989 newrot[8] = fRotationMatrix[8];
990 h.SetRotation(newrot);
997 Bool_t TGeoRotation::IsValid()
const
999 const Double_t *r = fRotationMatrix;
1001 for (Int_t i=0; i<2; i++) {
1002 for (Int_t j=i+1; j<3; j++) {
1004 cij = TMath::Abs(r[i]*r[j]+r[i+3]*r[j+3]+r[i+6]*r[j+6]);
1005 if (cij>1E-4)
return kFALSE;
1007 cij = TMath::Abs(r[3*i]*r[3*j]+r[3*i+1]*r[3*j+1]+r[3*i+2]*r[3*j+2]);
1008 if (cij>1E-4)
return kFALSE;
1017 void TGeoRotation::Clear(Option_t *)
1019 memcpy(fRotationMatrix,kIdentityMatrix,kN9);
1020 ResetBit(kGeoRotation);
1026 void TGeoRotation::FastRotZ(
const Double_t *sincos)
1028 fRotationMatrix[0] = sincos[1];
1029 fRotationMatrix[1] = -sincos[0];
1030 fRotationMatrix[3] = sincos[0];
1031 fRotationMatrix[4] = sincos[1];
1032 SetBit(kGeoRotation);
1041 Double_t TGeoRotation::GetPhiRotation(Bool_t fixX)
const
1044 if (fixX) phi = 180.*TMath::ATan2(-fRotationMatrix[1],fRotationMatrix[4])/TMath::Pi();
1045 else phi = 180.*TMath::ATan2(fRotationMatrix[3], fRotationMatrix[0])/TMath::Pi();
1052 void TGeoRotation::LocalToMaster(
const Double_t *local, Double_t *master)
const
1054 const Double_t *rot = GetRotationMatrix();
1055 for (Int_t i=0; i<3; i++) {
1056 master[i] = local[0]*rot[3*i]
1057 + local[1]*rot[3*i+1]
1058 + local[2]*rot[3*i+2];
1065 void TGeoRotation::MasterToLocal(
const Double_t *master, Double_t *local)
const
1067 const Double_t *rot = GetRotationMatrix();
1068 for (Int_t i=0; i<3; i++) {
1069 local[i] = master[0]*rot[i]
1070 + master[1]*rot[i+3]
1071 + master[2]*rot[i+6];
1078 TGeoMatrix *TGeoRotation::MakeClone()
const
1080 TGeoMatrix *matrix =
new TGeoRotation(*
this);
1087 void TGeoRotation::RotateX(Double_t angle)
1089 SetBit(kGeoRotation);
1090 Double_t phi = angle*TMath::DegToRad();
1091 Double_t c = TMath::Cos(phi);
1092 Double_t s = TMath::Sin(phi);
1094 v[0] = fRotationMatrix[0];
1095 v[1] = fRotationMatrix[1];
1096 v[2] = fRotationMatrix[2];
1097 v[3] = c*fRotationMatrix[3]-s*fRotationMatrix[6];
1098 v[4] = c*fRotationMatrix[4]-s*fRotationMatrix[7];
1099 v[5] = c*fRotationMatrix[5]-s*fRotationMatrix[8];
1100 v[6] = s*fRotationMatrix[3]+c*fRotationMatrix[6];
1101 v[7] = s*fRotationMatrix[4]+c*fRotationMatrix[7];
1102 v[8] = s*fRotationMatrix[5]+c*fRotationMatrix[8];
1104 memcpy(fRotationMatrix, v, kN9);
1110 void TGeoRotation::RotateY(Double_t angle)
1112 SetBit(kGeoRotation);
1113 Double_t phi = angle*TMath::DegToRad();
1114 Double_t c = TMath::Cos(phi);
1115 Double_t s = TMath::Sin(phi);
1117 v[0] = c*fRotationMatrix[0]+s*fRotationMatrix[6];
1118 v[1] = c*fRotationMatrix[1]+s*fRotationMatrix[7];
1119 v[2] = c*fRotationMatrix[2]+s*fRotationMatrix[8];
1120 v[3] = fRotationMatrix[3];
1121 v[4] = fRotationMatrix[4];
1122 v[5] = fRotationMatrix[5];
1123 v[6] = -s*fRotationMatrix[0]+c*fRotationMatrix[6];
1124 v[7] = -s*fRotationMatrix[1]+c*fRotationMatrix[7];
1125 v[8] = -s*fRotationMatrix[2]+c*fRotationMatrix[8];
1127 memcpy(fRotationMatrix, v, kN9);
1133 void TGeoRotation::RotateZ(Double_t angle)
1135 SetBit(kGeoRotation);
1136 Double_t phi = angle*TMath::DegToRad();
1137 Double_t c = TMath::Cos(phi);
1138 Double_t s = TMath::Sin(phi);
1140 v[0] = c*fRotationMatrix[0]-s*fRotationMatrix[3];
1141 v[1] = c*fRotationMatrix[1]-s*fRotationMatrix[4];
1142 v[2] = c*fRotationMatrix[2]-s*fRotationMatrix[5];
1143 v[3] = s*fRotationMatrix[0]+c*fRotationMatrix[3];
1144 v[4] = s*fRotationMatrix[1]+c*fRotationMatrix[4];
1145 v[5] = s*fRotationMatrix[2]+c*fRotationMatrix[5];
1146 v[6] = fRotationMatrix[6];
1147 v[7] = fRotationMatrix[7];
1148 v[8] = fRotationMatrix[8];
1150 memcpy(&fRotationMatrix[0],v,kN9);
1156 void TGeoRotation::ReflectX(Bool_t leftside, Bool_t)
1159 fRotationMatrix[0]=-fRotationMatrix[0];
1160 fRotationMatrix[1]=-fRotationMatrix[1];
1161 fRotationMatrix[2]=-fRotationMatrix[2];
1163 fRotationMatrix[0]=-fRotationMatrix[0];
1164 fRotationMatrix[3]=-fRotationMatrix[3];
1165 fRotationMatrix[6]=-fRotationMatrix[6];
1167 SetBit(kGeoRotation);
1168 SetBit(kGeoReflection, !IsReflection());
1174 void TGeoRotation::ReflectY(Bool_t leftside, Bool_t)
1177 fRotationMatrix[3]=-fRotationMatrix[3];
1178 fRotationMatrix[4]=-fRotationMatrix[4];
1179 fRotationMatrix[5]=-fRotationMatrix[5];
1181 fRotationMatrix[1]=-fRotationMatrix[1];
1182 fRotationMatrix[4]=-fRotationMatrix[4];
1183 fRotationMatrix[7]=-fRotationMatrix[7];
1185 SetBit(kGeoRotation);
1186 SetBit(kGeoReflection, !IsReflection());
1192 void TGeoRotation::ReflectZ(Bool_t leftside, Bool_t)
1195 fRotationMatrix[6]=-fRotationMatrix[6];
1196 fRotationMatrix[7]=-fRotationMatrix[7];
1197 fRotationMatrix[8]=-fRotationMatrix[8];
1199 fRotationMatrix[2]=-fRotationMatrix[2];
1200 fRotationMatrix[5]=-fRotationMatrix[5];
1201 fRotationMatrix[8]=-fRotationMatrix[8];
1203 SetBit(kGeoRotation);
1204 SetBit(kGeoReflection, !IsReflection());
1210 void TGeoRotation::SavePrimitive(std::ostream &out, Option_t * )
1212 if (TestBit(kGeoSavePrimitive))
return;
1213 out <<
" // Rotation: " << GetName() << std::endl;
1214 Double_t th1,ph1,th2,ph2,th3,ph3;
1215 GetAngles(th1,ph1,th2,ph2,th3,ph3);
1216 out <<
" thx = " << th1 <<
"; phx = " << ph1 <<
";" << std::endl;
1217 out <<
" thy = " << th2 <<
"; phy = " << ph2 <<
";" << std::endl;
1218 out <<
" thz = " << th3 <<
"; phz = " << ph3 <<
";" << std::endl;
1219 out <<
" TGeoRotation *" << GetPointerName() <<
" = new TGeoRotation(\"" << GetName() <<
"\",thx,phx,thy,phy,thz,phz);" << std::endl;
1220 TObject::SetBit(kGeoSavePrimitive);
1226 void TGeoRotation::SetRotation(
const TGeoMatrix &other)
1228 SetBit(kGeoRotation, other.IsRotation());
1229 SetMatrix(other.GetRotationMatrix());
1238 void TGeoRotation::SetAngles(Double_t phi, Double_t theta, Double_t psi)
1240 Double_t degrad = TMath::Pi()/180.;
1241 Double_t sinphi = TMath::Sin(degrad*phi);
1242 Double_t cosphi = TMath::Cos(degrad*phi);
1243 Double_t sinthe = TMath::Sin(degrad*theta);
1244 Double_t costhe = TMath::Cos(degrad*theta);
1245 Double_t sinpsi = TMath::Sin(degrad*psi);
1246 Double_t cospsi = TMath::Cos(degrad*psi);
1248 fRotationMatrix[0] = cospsi*cosphi - costhe*sinphi*sinpsi;
1249 fRotationMatrix[1] = -sinpsi*cosphi - costhe*sinphi*cospsi;
1250 fRotationMatrix[2] = sinthe*sinphi;
1251 fRotationMatrix[3] = cospsi*sinphi + costhe*cosphi*sinpsi;
1252 fRotationMatrix[4] = -sinpsi*sinphi + costhe*cosphi*cospsi;
1253 fRotationMatrix[5] = -sinthe*cosphi;
1254 fRotationMatrix[6] = sinpsi*sinthe;
1255 fRotationMatrix[7] = cospsi*sinthe;
1256 fRotationMatrix[8] = costhe;
1258 if (!IsValid()) Error(
"SetAngles",
"invalid rotation (Euler angles : phi=%f theta=%f psi=%f)",phi,theta,psi);
1265 void TGeoRotation::SetAngles(Double_t theta1, Double_t phi1, Double_t theta2, Double_t phi2,
1266 Double_t theta3, Double_t phi3)
1268 Double_t degrad = TMath::Pi()/180.;
1269 fRotationMatrix[0] = TMath::Cos(degrad*phi1)*TMath::Sin(degrad*theta1);
1270 fRotationMatrix[3] = TMath::Sin(degrad*phi1)*TMath::Sin(degrad*theta1);
1271 fRotationMatrix[6] = TMath::Cos(degrad*theta1);
1272 fRotationMatrix[1] = TMath::Cos(degrad*phi2)*TMath::Sin(degrad*theta2);
1273 fRotationMatrix[4] = TMath::Sin(degrad*phi2)*TMath::Sin(degrad*theta2);
1274 fRotationMatrix[7] = TMath::Cos(degrad*theta2);
1275 fRotationMatrix[2] = TMath::Cos(degrad*phi3)*TMath::Sin(degrad*theta3);
1276 fRotationMatrix[5] = TMath::Sin(degrad*phi3)*TMath::Sin(degrad*theta3);
1277 fRotationMatrix[8] = TMath::Cos(degrad*theta3);
1279 for (Int_t i=0; i<9; i++) {
1280 if (TMath::Abs(fRotationMatrix[i])<1E-15) fRotationMatrix[i] = 0;
1281 if (TMath::Abs(fRotationMatrix[i]-1)<1E-15) fRotationMatrix[i] = 1;
1282 if (TMath::Abs(fRotationMatrix[i]+1)<1E-15) fRotationMatrix[i] = -1;
1284 if (!IsValid()) Error(
"SetAngles",
"invalid rotation (G3 angles, th1=%f phi1=%f, th2=%f ph2=%f, th3=%f phi3=%f)",
1285 theta1,phi1,theta2,phi2,theta3,phi3);
1292 void TGeoRotation::GetAngles(Double_t &theta1, Double_t &phi1, Double_t &theta2, Double_t &phi2,
1293 Double_t &theta3, Double_t &phi3)
const
1295 Double_t raddeg = 180./TMath::Pi();
1296 theta1 = raddeg*TMath::ACos(fRotationMatrix[6]);
1297 theta2 = raddeg*TMath::ACos(fRotationMatrix[7]);
1298 theta3 = raddeg*TMath::ACos(fRotationMatrix[8]);
1299 if (TMath::Abs(fRotationMatrix[0])<1E-6 && TMath::Abs(fRotationMatrix[3])<1E-6) phi1=0.;
1300 else phi1 = raddeg*TMath::ATan2(fRotationMatrix[3],fRotationMatrix[0]);
1301 if (phi1<0) phi1+=360.;
1302 if (TMath::Abs(fRotationMatrix[1])<1E-6 && TMath::Abs(fRotationMatrix[4])<1E-6) phi2=0.;
1303 else phi2 = raddeg*TMath::ATan2(fRotationMatrix[4],fRotationMatrix[1]);
1304 if (phi2<0) phi2+=360.;
1305 if (TMath::Abs(fRotationMatrix[2])<1E-6 && TMath::Abs(fRotationMatrix[5])<1E-6) phi3=0.;
1306 else phi3 = raddeg*TMath::ATan2(fRotationMatrix[5],fRotationMatrix[2]);
1307 if (phi3<0) phi3+=360.;
1313 void TGeoRotation::GetAngles(Double_t &phi, Double_t &theta, Double_t &psi)
const
1315 const Double_t *m = fRotationMatrix;
1317 if (TMath::Abs(1.-TMath::Abs(m[8]))<1.e-9) {
1318 theta = TMath::ACos(m[8])*TMath::RadToDeg();
1319 phi = TMath::ATan2(-m[8]*m[1],m[0])*TMath::RadToDeg();
1324 phi = TMath::ATan2(m[2],-m[5]);
1325 Double_t sphi = TMath::Sin(phi);
1326 if (TMath::Abs(sphi)<1.e-9) theta = -TMath::ASin(m[5]/TMath::Cos(phi))*TMath::RadToDeg();
1327 else theta = TMath::ASin(m[2]/sphi)*TMath::RadToDeg();
1328 phi *= TMath::RadToDeg();
1329 psi = TMath::ATan2(m[6],m[7])*TMath::RadToDeg();
1335 Double_t TGeoRotation::Determinant()
const
1338 det = fRotationMatrix[0]*fRotationMatrix[4]*fRotationMatrix[8] +
1339 fRotationMatrix[3]*fRotationMatrix[7]*fRotationMatrix[2] +
1340 fRotationMatrix[6]*fRotationMatrix[1]*fRotationMatrix[5] -
1341 fRotationMatrix[2]*fRotationMatrix[4]*fRotationMatrix[6] -
1342 fRotationMatrix[5]*fRotationMatrix[7]*fRotationMatrix[0] -
1343 fRotationMatrix[8]*fRotationMatrix[1]*fRotationMatrix[3];
1351 void TGeoRotation::CheckMatrix()
1353 if (Determinant() < 0) SetBit(kGeoReflection);
1354 Double_t dd = fRotationMatrix[0] + fRotationMatrix[4] + fRotationMatrix[8] - 3.;
1355 if (TMath::Abs(dd) < 1.E-12) ResetBit(kGeoRotation);
1356 else SetBit(kGeoRotation);
1362 void TGeoRotation::GetInverse(Double_t *invmat)
const
1365 Error(
"GetInverse",
"no place to store the inverse matrix");
1368 for (Int_t i=0; i<3; i++) {
1369 for (Int_t j=0; j<3; j++) {
1370 invmat[3*i+j] = fRotationMatrix[3*j+i];
1380 void TGeoRotation::MultiplyBy(
const TGeoRotation *rot, Bool_t after)
1382 const Double_t *matleft, *matright;
1383 SetBit(kGeoRotation);
1384 Double_t newmat[9] = {0};
1386 matleft = &fRotationMatrix[0];
1387 matright = rot->GetRotationMatrix();
1389 matleft = rot->GetRotationMatrix();
1390 matright = &fRotationMatrix[0];
1392 for (Int_t i=0; i<3; i++) {
1393 for (Int_t j=0; j<3; j++) {
1394 for (Int_t k=0; k<3; k++) {
1395 newmat[3*i+j] += matleft[3*i+k] * matright[3*k+j];
1399 memcpy(&fRotationMatrix[0], &newmat[0], kN9);
1409 ClassImp(TGeoScale);
1414 TGeoScale::TGeoScale()
1417 for (Int_t i=0; i<3; i++) fScale[i] = 1.;
1423 TGeoScale::TGeoScale(
const TGeoScale &other)
1432 TGeoScale::TGeoScale(
const TGeoMatrix &other)
1435 ResetBit(kGeoTranslation);
1436 ResetBit(kGeoRotation);
1443 TGeoScale::TGeoScale(Double_t sx, Double_t sy, Double_t sz)
1447 SetScale(sx, sy, sz);
1453 TGeoScale::TGeoScale(
const char *name, Double_t sx, Double_t sy, Double_t sz)
1457 SetScale(sx, sy, sz);
1463 TGeoScale::~TGeoScale()
1470 TGeoScale& TGeoScale::operator = (
const TGeoMatrix &matrix)
1472 if (&matrix ==
this)
return *
this;
1473 Bool_t registered = TestBit(kGeoRegistered);
1474 TNamed::operator=(matrix);
1476 SetBit(kGeoRegistered,registered);
1477 ResetBit(kGeoTranslation);
1478 ResetBit(kGeoRotation);
1485 TGeoScale &TGeoScale::operator*=(
const TGeoScale &right)
1487 const Double_t *scl = right.GetScale();
1488 fScale[0] *= scl[0];
1489 fScale[1] *= scl[1];
1490 fScale[2] *= scl[2];
1491 SetBit(kGeoReflection, fScale[0] * fScale[1] * fScale[2] < 0);
1492 if (!IsScale()) SetBit(kGeoScale, right.IsScale());
1496 TGeoScale TGeoScale::operator*(
const TGeoScale &right)
const
1498 TGeoScale s = *
this;
1503 TGeoHMatrix TGeoScale::operator*(
const TGeoMatrix &right)
const
1505 TGeoHMatrix t = *
this;
1513 Bool_t TGeoScale::operator ==(
const TGeoScale &other)
const
1515 if (&other ==
this)
return kTRUE;
1516 const Double_t *scl = GetScale();
1517 const Double_t *oscl = other.GetScale();
1518 for (
auto i=0; i<3; i++)
1519 if (TMath::Abs(scl[i]-oscl[i])>1.E-10)
return kFALSE;
1526 TGeoHMatrix TGeoScale::Inverse()
const
1531 scale[0] = 1./fScale[0];
1532 scale[1] = 1./fScale[1];
1533 scale[2] = 1./fScale[2];
1541 void TGeoScale::SetScale(Double_t sx, Double_t sy, Double_t sz)
1543 if (TMath::Abs(sx*sy*sz) < 1.E-10) {
1544 Error(
"SetScale",
"Invalid scale %f, %f, %f for transformation %s",sx,sy,sx,GetName());
1550 if (sx*sy*sz<0) SetBit(kGeoReflection);
1551 else SetBit(kGeoReflection, kFALSE);
1557 void TGeoScale::SetScale(
const TGeoMatrix &other)
1559 SetBit(kGeoScale, other.IsScale());
1560 SetBit(kGeoReflection, other.IsReflection());
1561 memcpy(fScale, other.GetScale(), kN3);
1567 void TGeoScale::LocalToMaster(
const Double_t *local, Double_t *master)
const
1569 master[0] = local[0]*fScale[0];
1570 master[1] = local[1]*fScale[1];
1571 master[2] = local[2]*fScale[2];
1579 Double_t TGeoScale::LocalToMaster(Double_t dist,
const Double_t *dir)
const
1583 scale = TMath::Abs(fScale[0]);
1584 if (TMath::Abs(fScale[1])<scale) scale = TMath::Abs(fScale[1]);
1585 if (TMath::Abs(fScale[2])<scale) scale = TMath::Abs(fScale[2]);
1587 scale = fScale[0]*fScale[0]*dir[0]*dir[0] +
1588 fScale[1]*fScale[1]*dir[1]*dir[1] +
1589 fScale[2]*fScale[2]*dir[2]*dir[2];
1590 scale = TMath::Sqrt(scale);
1598 TGeoMatrix *TGeoScale::MakeClone()
const
1600 TGeoMatrix *matrix =
new TGeoScale(*
this);
1607 void TGeoScale::MasterToLocal(
const Double_t *master, Double_t *local)
const
1609 local[0] = master[0]/fScale[0];
1610 local[1] = master[1]/fScale[1];
1611 local[2] = master[2]/fScale[2];
1619 Double_t TGeoScale::MasterToLocal(Double_t dist,
const Double_t *dir)
const
1623 scale = TMath::Abs(fScale[0]);
1624 if (TMath::Abs(fScale[1])>scale) scale = TMath::Abs(fScale[1]);
1625 if (TMath::Abs(fScale[2])>scale) scale = TMath::Abs(fScale[2]);
1628 scale = (dir[0]*dir[0])/(fScale[0]*fScale[0]) +
1629 (dir[1]*dir[1])/(fScale[1]*fScale[1]) +
1630 (dir[2]*dir[2])/(fScale[2]*fScale[2]);
1631 scale = TMath::Sqrt(scale);
1642 ClassImp(TGeoCombiTrans);
1647 TGeoCombiTrans::TGeoCombiTrans()
1649 for (Int_t i=0; i<3; i++) fTranslation[i] = 0.0;
1656 TGeoCombiTrans::TGeoCombiTrans(
const TGeoMatrix &other)
1659 ResetBit(kGeoScale);
1660 if (other.IsTranslation()) {
1661 SetBit(kGeoTranslation);
1662 memcpy(fTranslation,other.GetTranslation(),kN3);
1664 for (Int_t i=0; i<3; i++) fTranslation[i] = 0.0;
1666 if (other.IsRotation()) {
1667 SetBit(kGeoRotation);
1668 SetBit(kGeoMatrixOwned);
1669 fRotation =
new TGeoRotation(other);
1677 TGeoCombiTrans::TGeoCombiTrans(
const TGeoTranslation &tr,
const TGeoRotation &rot)
1679 if (tr.IsTranslation()) {
1680 SetBit(kGeoTranslation);
1681 const Double_t *trans = tr.GetTranslation();
1682 memcpy(fTranslation, trans, kN3);
1684 for (Int_t i=0; i<3; i++) fTranslation[i] = 0.0;
1686 if (rot.IsRotation()) {
1687 SetBit(kGeoRotation);
1688 SetBit(kGeoMatrixOwned);
1689 fRotation =
new TGeoRotation(rot);
1690 SetBit(kGeoReflection, rot.TestBit(kGeoReflection));
1698 TGeoCombiTrans::TGeoCombiTrans(
const char *name)
1701 for (Int_t i=0; i<3; i++) fTranslation[i] = 0.0;
1708 TGeoCombiTrans::TGeoCombiTrans(Double_t dx, Double_t dy, Double_t dz, TGeoRotation *rot)
1711 SetTranslation(dx, dy, dz);
1719 TGeoCombiTrans::TGeoCombiTrans(
const char *name, Double_t dx, Double_t dy, Double_t dz, TGeoRotation *rot)
1722 SetTranslation(dx, dy, dz);
1730 TGeoCombiTrans &TGeoCombiTrans::operator=(
const TGeoMatrix &matrix)
1732 if (&matrix ==
this)
return *
this;
1733 Bool_t registered = TestBit(kGeoRegistered);
1735 TNamed::operator=(matrix);
1737 if (matrix.IsTranslation()) {
1738 memcpy(fTranslation,matrix.GetTranslation(),kN3);
1740 if (matrix.IsRotation()) {
1742 fRotation =
new TGeoRotation();
1743 SetBit(kGeoMatrixOwned);
1745 if (!TestBit(kGeoMatrixOwned)) {
1746 fRotation =
new TGeoRotation();
1747 SetBit(kGeoMatrixOwned);
1750 fRotation->SetMatrix(matrix.GetRotationMatrix());
1751 fRotation->SetBit(kGeoReflection, matrix.TestBit(kGeoReflection));
1752 fRotation->SetBit(kGeoRotation);
1754 if (fRotation && TestBit(kGeoMatrixOwned))
delete fRotation;
1755 ResetBit(kGeoMatrixOwned);
1758 SetBit(kGeoRegistered,registered);
1759 ResetBit(kGeoScale);
1766 Bool_t TGeoCombiTrans::operator==(
const TGeoMatrix &other)
const
1768 if (&other ==
this)
return kTRUE;
1769 const Double_t *tr = GetTranslation();
1770 const Double_t *otr = other.GetTranslation();
1771 for (
auto i=0; i<3; i++)
if (TMath::Abs(tr[i]-otr[i])>1.E-10)
return kFALSE;
1772 const Double_t *rot = GetRotationMatrix();
1773 const Double_t *orot = other.GetRotationMatrix();
1774 for (
auto i=0; i<9; i++)
if (TMath::Abs(rot[i]-orot[i])>1.E-10)
return kFALSE;
1781 TGeoCombiTrans &TGeoCombiTrans::operator*=(
const TGeoMatrix &right)
1787 TGeoCombiTrans TGeoCombiTrans::operator*(
const TGeoMatrix &right)
const
1789 TGeoHMatrix h = *
this;
1797 TGeoCombiTrans::~TGeoCombiTrans()
1800 if(TestBit(TGeoMatrix::kGeoMatrixOwned) && !fRotation->IsRegistered())
delete fRotation;
1807 void TGeoCombiTrans::Clear(Option_t *)
1809 if (IsTranslation()) {
1810 ResetBit(kGeoTranslation);
1811 memset(fTranslation, 0, kN3);
1814 if (TestBit(kGeoMatrixOwned))
delete fRotation;
1817 ResetBit(kGeoRotation);
1818 ResetBit(kGeoTranslation);
1819 ResetBit(kGeoMatrixOwned);
1825 TGeoHMatrix TGeoCombiTrans::Inverse()
const
1829 Bool_t is_tr = IsTranslation();
1830 Bool_t is_rot = IsRotation();
1833 const Double_t *rot = GetRotationMatrix();
1834 tr[0] = -fTranslation[0]*rot[0] - fTranslation[1]*rot[3] - fTranslation[2]*rot[6];
1835 tr[1] = -fTranslation[0]*rot[1] - fTranslation[1]*rot[4] - fTranslation[2]*rot[7];
1836 tr[2] = -fTranslation[0]*rot[2] - fTranslation[1]*rot[5] - fTranslation[2]*rot[8];
1837 h.SetTranslation(tr);
1847 h.SetRotation(newrot);
1848 h.SetBit(kGeoTranslation,is_tr);
1849 h.SetBit(kGeoRotation,is_rot);
1856 TGeoMatrix *TGeoCombiTrans::MakeClone()
const
1858 TGeoMatrix *matrix =
new TGeoCombiTrans(*
this);
1866 void TGeoCombiTrans::Multiply(
const TGeoMatrix *right)
1868 if (right->IsIdentity())
return;
1869 TGeoHMatrix h = *
this;
1877 void TGeoCombiTrans::RegisterYourself()
1879 TGeoMatrix::RegisterYourself();
1880 if (fRotation && fRotation->IsRotation()) fRotation->RegisterYourself();
1886 void TGeoCombiTrans::RotateX(Double_t angle)
1888 if (!fRotation || !TestBit(kGeoMatrixOwned)) {
1889 if (fRotation) fRotation =
new TGeoRotation(*fRotation);
1890 else fRotation =
new TGeoRotation();
1891 SetBit(kGeoMatrixOwned);
1893 SetBit(kGeoRotation);
1894 const Double_t *rot = fRotation->GetRotationMatrix();
1895 Double_t phi = angle*TMath::DegToRad();
1896 Double_t c = TMath::Cos(phi);
1897 Double_t s = TMath::Sin(phi);
1902 v[3] = c*rot[3]-s*rot[6];
1903 v[4] = c*rot[4]-s*rot[7];
1904 v[5] = c*rot[5]-s*rot[8];
1905 v[6] = s*rot[3]+c*rot[6];
1906 v[7] = s*rot[4]+c*rot[7];
1907 v[8] = s*rot[5]+c*rot[8];
1908 fRotation->SetMatrix(v);
1909 fRotation->SetBit(kGeoRotation);
1910 if (!IsTranslation())
return;
1911 v[0] = fTranslation[0];
1912 v[1] = c*fTranslation[1]-s*fTranslation[2];
1913 v[2] = s*fTranslation[1]+c*fTranslation[2];
1914 memcpy(fTranslation,v,kN3);
1920 void TGeoCombiTrans::RotateY(Double_t angle)
1922 if (!fRotation || !TestBit(kGeoMatrixOwned)) {
1923 if (fRotation) fRotation =
new TGeoRotation(*fRotation);
1924 else fRotation =
new TGeoRotation();
1925 SetBit(kGeoMatrixOwned);
1927 SetBit(kGeoRotation);
1928 const Double_t *rot = fRotation->GetRotationMatrix();
1929 Double_t phi = angle*TMath::DegToRad();
1930 Double_t c = TMath::Cos(phi);
1931 Double_t s = TMath::Sin(phi);
1933 v[0] = c*rot[0]+s*rot[6];
1934 v[1] = c*rot[1]+s*rot[7];
1935 v[2] = c*rot[2]+s*rot[8];
1939 v[6] = -s*rot[0]+c*rot[6];
1940 v[7] = -s*rot[1]+c*rot[7];
1941 v[8] = -s*rot[2]+c*rot[8];
1942 fRotation->SetMatrix(v);
1943 fRotation->SetBit(kGeoRotation);
1944 if (!IsTranslation())
return;
1945 v[0] = c*fTranslation[0]+s*fTranslation[2];
1946 v[1] = fTranslation[1];
1947 v[2] = -s*fTranslation[0]+c*fTranslation[2];
1948 memcpy(fTranslation,v,kN3);
1954 void TGeoCombiTrans::RotateZ(Double_t angle)
1956 if (!fRotation || !TestBit(kGeoMatrixOwned)) {
1957 if (fRotation) fRotation =
new TGeoRotation(*fRotation);
1958 else fRotation =
new TGeoRotation();
1959 SetBit(kGeoMatrixOwned);
1961 SetBit(kGeoRotation);
1962 const Double_t *rot = fRotation->GetRotationMatrix();
1963 Double_t phi = angle*TMath::DegToRad();
1964 Double_t c = TMath::Cos(phi);
1965 Double_t s = TMath::Sin(phi);
1967 v[0] = c*rot[0]-s*rot[3];
1968 v[1] = c*rot[1]-s*rot[4];
1969 v[2] = c*rot[2]-s*rot[5];
1970 v[3] = s*rot[0]+c*rot[3];
1971 v[4] = s*rot[1]+c*rot[4];
1972 v[5] = s*rot[2]+c*rot[5];
1976 fRotation->SetMatrix(v);
1977 fRotation->SetBit(kGeoRotation);
1978 if (!IsTranslation())
return;
1979 v[0] = c*fTranslation[0]-s*fTranslation[1];
1980 v[1] = s*fTranslation[0]+c*fTranslation[1];
1981 v[2] = fTranslation[2];
1982 memcpy(fTranslation,v,kN3);
1988 void TGeoCombiTrans::ReflectX(Bool_t leftside, Bool_t rotonly)
1990 if (leftside && !rotonly) fTranslation[0] = -fTranslation[0];
1991 if (!fRotation || !TestBit(kGeoMatrixOwned)) {
1992 if (fRotation) fRotation =
new TGeoRotation(*fRotation);
1993 else fRotation =
new TGeoRotation();
1994 SetBit(kGeoMatrixOwned);
1996 SetBit(kGeoRotation);
1997 fRotation->ReflectX(leftside);
1998 SetBit(kGeoReflection, !IsReflection());
2004 void TGeoCombiTrans::ReflectY(Bool_t leftside, Bool_t rotonly)
2006 if (leftside && !rotonly) fTranslation[1] = -fTranslation[1];
2007 if (!fRotation || !TestBit(kGeoMatrixOwned)) {
2008 if (fRotation) fRotation =
new TGeoRotation(*fRotation);
2009 else fRotation =
new TGeoRotation();
2010 SetBit(kGeoMatrixOwned);
2012 SetBit(kGeoRotation);
2013 fRotation->ReflectY(leftside);
2014 SetBit(kGeoReflection, !IsReflection());
2020 void TGeoCombiTrans::ReflectZ(Bool_t leftside, Bool_t rotonly)
2022 if (leftside && !rotonly) fTranslation[2] = -fTranslation[2];
2023 if (!fRotation || !TestBit(kGeoMatrixOwned)) {
2024 if (fRotation) fRotation =
new TGeoRotation(*fRotation);
2025 else fRotation =
new TGeoRotation();
2026 SetBit(kGeoMatrixOwned);
2028 SetBit(kGeoRotation);
2029 fRotation->ReflectZ(leftside);
2030 SetBit(kGeoReflection, !IsReflection());
2036 void TGeoCombiTrans::SavePrimitive(std::ostream &out, Option_t *option )
2038 if (TestBit(kGeoSavePrimitive))
return;
2039 out <<
" // Combi transformation: " << GetName() << std::endl;
2040 out <<
" dx = " << fTranslation[0] <<
";" << std::endl;
2041 out <<
" dy = " << fTranslation[1] <<
";" << std::endl;
2042 out <<
" dz = " << fTranslation[2] <<
";" << std::endl;
2043 if (fRotation && fRotation->IsRotation()) {
2044 fRotation->SavePrimitive(out,option);
2045 out <<
" " << GetPointerName() <<
" = new TGeoCombiTrans(\"" << GetName() <<
"\", dx,dy,dz,";
2046 out << fRotation->GetPointerName() <<
");" << std::endl;
2048 out <<
" " << GetPointerName() <<
" = new TGeoCombiTrans(\"" << GetName() <<
"\");" << std::endl;
2049 out <<
" " << GetPointerName() <<
"->SetTranslation(dx,dy,dz);" << std::endl;
2051 TObject::SetBit(kGeoSavePrimitive);
2057 void TGeoCombiTrans::SetRotation(
const TGeoRotation *rot)
2059 if (fRotation && TestBit(kGeoMatrixOwned))
delete fRotation;
2061 ResetBit(TGeoMatrix::kGeoMatrixOwned);
2062 ResetBit(kGeoRotation);
2063 ResetBit(kGeoReflection);
2065 if (!rot->IsRotation())
return;
2067 SetBit(kGeoRotation);
2068 SetBit(kGeoReflection, rot->TestBit(kGeoReflection));
2069 TGeoRotation *rr = (TGeoRotation*)rot;
2076 void TGeoCombiTrans::SetRotation(
const TGeoRotation &rot)
2078 if (fRotation && TestBit(kGeoMatrixOwned))
delete fRotation;
2080 if (!rot.IsRotation()) {
2081 ResetBit(kGeoRotation);
2082 ResetBit(kGeoReflection);
2083 ResetBit(TGeoMatrix::kGeoMatrixOwned);
2087 SetBit(kGeoRotation);
2088 SetBit(kGeoReflection, rot.TestBit(kGeoReflection));
2089 fRotation =
new TGeoRotation(rot);
2090 SetBit(kGeoMatrixOwned);
2096 void TGeoCombiTrans::SetTranslation(
const TGeoTranslation &tr)
2098 if (tr.IsTranslation()) {
2099 SetBit(kGeoTranslation);
2100 const Double_t *trans = tr.GetTranslation();
2101 memcpy(fTranslation, trans, kN3);
2103 if (!IsTranslation())
return;
2104 memset(fTranslation, 0, kN3);
2105 ResetBit(kGeoTranslation);
2112 void TGeoCombiTrans::SetTranslation(Double_t dx, Double_t dy, Double_t dz)
2114 fTranslation[0] = dx;
2115 fTranslation[1] = dy;
2116 fTranslation[2] = dz;
2117 if (fTranslation[0] || fTranslation[1] || fTranslation[2]) SetBit(kGeoTranslation);
2118 else ResetBit(kGeoTranslation);
2124 void TGeoCombiTrans::SetTranslation(Double_t *vect)
2126 fTranslation[0] = vect[0];
2127 fTranslation[1] = vect[1];
2128 fTranslation[2] = vect[2];
2129 if (fTranslation[0] || fTranslation[1] || fTranslation[2]) SetBit(kGeoTranslation);
2130 else ResetBit(kGeoTranslation);
2136 const Double_t *TGeoCombiTrans::GetRotationMatrix()
const
2138 if (!fRotation)
return kIdentityMatrix;
2139 return fRotation->GetRotationMatrix();
2147 ClassImp(TGeoGenTrans);
2152 TGeoGenTrans::TGeoGenTrans()
2154 SetBit(kGeoGenTrans);
2155 for (Int_t i=0; i<3; i++) fTranslation[i] = 0.0;
2156 for (Int_t j=0; j<3; j++) fScale[j] = 1.0;
2163 TGeoGenTrans::TGeoGenTrans(
const char *name)
2164 :TGeoCombiTrans(name)
2166 SetBit(kGeoGenTrans);
2167 for (Int_t i=0; i<3; i++) fTranslation[i] = 0.0;
2168 for (Int_t j=0; j<3; j++) fScale[j] = 1.0;
2175 TGeoGenTrans::TGeoGenTrans(Double_t dx, Double_t dy, Double_t dz,
2176 Double_t sx, Double_t sy, Double_t sz, TGeoRotation *rot)
2179 SetBit(kGeoGenTrans);
2180 SetTranslation(dx, dy, dz);
2181 SetScale(sx, sy, sz);
2188 TGeoGenTrans::TGeoGenTrans(
const char *name, Double_t dx, Double_t dy, Double_t dz,
2189 Double_t sx, Double_t sy, Double_t sz, TGeoRotation *rot)
2190 :TGeoCombiTrans(name)
2192 SetBit(kGeoGenTrans);
2193 SetTranslation(dx, dy, dz);
2194 SetScale(sx, sy, sz);
2201 TGeoGenTrans::~TGeoGenTrans()
2208 void TGeoGenTrans::Clear(Option_t *)
2210 memset(&fTranslation[0], 0, kN3);
2211 memset(&fScale[0], 0, kN3);
2212 if (fRotation) fRotation->Clear();
2218 void TGeoGenTrans::SetScale(Double_t sx, Double_t sy, Double_t sz)
2220 if (sx<1.E-5 || sy<1.E-5 || sz<1.E-5) {
2221 Error(
"ctor",
"Invalid scale");
2232 TGeoHMatrix TGeoGenTrans::Inverse()
const
2234 TGeoHMatrix h = *
this;
2241 Bool_t TGeoGenTrans::Normalize()
2243 Double_t normfactor = fScale[0]*fScale[1]*fScale[2];
2244 if (normfactor <= 1E-5)
return kFALSE;
2245 for (Int_t i=0; i<3; i++)
2246 fScale[i] /= normfactor;
2257 ClassImp(TGeoIdentity);
2262 TGeoIdentity::TGeoIdentity()
2264 if (!gGeoIdentity) gGeoIdentity =
this;
2271 TGeoIdentity::TGeoIdentity(
const char *name)
2274 if (!gGeoIdentity) gGeoIdentity =
this;
2281 TGeoHMatrix TGeoIdentity::Inverse()
const
2283 TGeoHMatrix h = *gGeoIdentity;
2296 ClassImp(TGeoHMatrix);
2301 TGeoHMatrix::TGeoHMatrix()
2303 memset(&fTranslation[0], 0, kN3);
2304 memcpy(fRotationMatrix,kIdentityMatrix,kN9);
2305 memcpy(fScale,kUnitScale,kN3);
2311 TGeoHMatrix::TGeoHMatrix(
const char* name)
2314 memset(&fTranslation[0], 0, kN3);
2315 memcpy(fRotationMatrix,kIdentityMatrix,kN9);
2316 memcpy(fScale,kUnitScale,kN3);
2322 TGeoHMatrix::TGeoHMatrix(
const TGeoMatrix &matrix)
2325 memset(&fTranslation[0], 0, kN3);
2326 memcpy(fRotationMatrix,kIdentityMatrix,kN9);
2327 memcpy(fScale,kUnitScale,kN3);
2328 if (matrix.IsIdentity())
return;
2329 if (matrix.IsTranslation())
2330 SetTranslation(matrix.GetTranslation());
2331 if (matrix.IsRotation())
2332 memcpy(fRotationMatrix,matrix.GetRotationMatrix(),kN9);
2333 if (matrix.IsScale())
2334 memcpy(fScale,matrix.GetScale(),kN3);
2340 TGeoHMatrix::~TGeoHMatrix()
2347 TGeoHMatrix &TGeoHMatrix::operator=(
const TGeoMatrix *matrix)
2349 return TGeoHMatrix::operator=(*matrix);
2355 TGeoHMatrix &TGeoHMatrix::operator=(
const TGeoMatrix &matrix)
2357 if (&matrix ==
this)
return *
this;
2359 Bool_t registered = TestBit(kGeoRegistered);
2360 TNamed::operator=(matrix);
2361 if (matrix.IsIdentity())
return *
this;
2362 if (matrix.IsTranslation())
2363 memcpy(fTranslation,matrix.GetTranslation(),kN3);
2364 if (matrix.IsRotation())
2365 memcpy(fRotationMatrix,matrix.GetRotationMatrix(),kN9);
2366 if (matrix.IsScale())
2367 memcpy(fScale,matrix.GetScale(),kN3);
2368 SetBit(kGeoRegistered,registered);
2375 TGeoHMatrix &TGeoHMatrix::operator*=(
const TGeoMatrix &right)
2381 TGeoHMatrix TGeoHMatrix::operator*(
const TGeoMatrix &right)
const
2383 TGeoHMatrix h = *
this;
2391 Bool_t TGeoHMatrix::operator==(
const TGeoMatrix &other)
const
2393 if (&other ==
this)
return kTRUE;
2394 const Double_t *tr = GetTranslation();
2395 const Double_t *otr = other.GetTranslation();
2396 for (
auto i=0; i<3; i++)
if (TMath::Abs(tr[i]-otr[i])>1.E-10)
return kFALSE;
2397 const Double_t *rot = GetRotationMatrix();
2398 const Double_t *orot = other.GetRotationMatrix();
2399 for (
auto i=0; i<9; i++)
if (TMath::Abs(rot[i]-orot[i])>1.E-10)
return kFALSE;
2400 const Double_t *scl = GetScale();
2401 const Double_t *oscl = other.GetScale();
2402 for (
auto i=0; i<3; i++)
if (TMath::Abs(scl[i]-oscl[i])>1.E-10)
return kFALSE;
2409 void TGeoHMatrix::CopyFrom(
const TGeoMatrix *other)
2411 SetBit(kGeoTranslation, other->IsTranslation());
2412 SetBit(kGeoRotation, other->IsRotation());
2413 SetBit(kGeoReflection, other->IsReflection());
2414 memcpy(fTranslation,other->GetTranslation(),kN3);
2415 memcpy(fRotationMatrix,other->GetRotationMatrix(),kN9);
2421 void TGeoHMatrix::Clear(Option_t *)
2423 SetBit(kGeoReflection, kFALSE);
2424 if (IsIdentity())
return;
2425 ResetBit(kGeoTranslation);
2426 ResetBit(kGeoRotation);
2427 ResetBit(kGeoScale);
2428 memcpy(fTranslation,kNullVector,kN3);
2429 memcpy(fRotationMatrix,kIdentityMatrix,kN9);
2430 memcpy(fScale,kUnitScale,kN3);
2436 TGeoMatrix *TGeoHMatrix::MakeClone()
const
2438 TGeoMatrix *matrix =
new TGeoHMatrix(*
this);
2445 void TGeoHMatrix::FastRotZ(
const Double_t *sincos)
2447 fRotationMatrix[0] = sincos[1];
2448 fRotationMatrix[1] = -sincos[0];
2449 fRotationMatrix[3] = sincos[0];
2450 fRotationMatrix[4] = sincos[1];
2451 SetBit(kGeoRotation);
2457 TGeoHMatrix TGeoHMatrix::Inverse()
const
2461 if (IsTranslation()) {
2463 tr[0] = -fTranslation[0]*fRotationMatrix[0] - fTranslation[1]*fRotationMatrix[3] - fTranslation[2]*fRotationMatrix[6];
2464 tr[1] = -fTranslation[0]*fRotationMatrix[1] - fTranslation[1]*fRotationMatrix[4] - fTranslation[2]*fRotationMatrix[7];
2465 tr[2] = -fTranslation[0]*fRotationMatrix[2] - fTranslation[1]*fRotationMatrix[5] - fTranslation[2]*fRotationMatrix[8];
2466 h.SetTranslation(tr);
2470 newrot[0] = fRotationMatrix[0];
2471 newrot[1] = fRotationMatrix[3];
2472 newrot[2] = fRotationMatrix[6];
2473 newrot[3] = fRotationMatrix[1];
2474 newrot[4] = fRotationMatrix[4];
2475 newrot[5] = fRotationMatrix[7];
2476 newrot[6] = fRotationMatrix[2];
2477 newrot[7] = fRotationMatrix[5];
2478 newrot[8] = fRotationMatrix[8];
2479 h.SetRotation(newrot);
2483 sc[0] = 1./fScale[0];
2484 sc[1] = 1./fScale[1];
2485 sc[2] = 1./fScale[2];
2494 Double_t TGeoHMatrix::Determinant()
const
2497 det = fRotationMatrix[0]*fRotationMatrix[4]*fRotationMatrix[8] +
2498 fRotationMatrix[3]*fRotationMatrix[7]*fRotationMatrix[2] +
2499 fRotationMatrix[6]*fRotationMatrix[1]*fRotationMatrix[5] -
2500 fRotationMatrix[2]*fRotationMatrix[4]*fRotationMatrix[6] -
2501 fRotationMatrix[5]*fRotationMatrix[7]*fRotationMatrix[0] -
2502 fRotationMatrix[8]*fRotationMatrix[1]*fRotationMatrix[3];
2510 void TGeoHMatrix::Multiply(
const TGeoMatrix *right)
2512 if (right->IsIdentity())
return;
2513 const Double_t *r_tra = right->GetTranslation();
2514 const Double_t *r_rot = right->GetRotationMatrix();
2515 const Double_t *r_scl = right->GetScale();
2517 if (right->IsRotation()) {
2518 SetBit(kGeoRotation);
2519 memcpy(fRotationMatrix,r_rot,kN9);
2520 if (right->IsReflection()) SetBit(kGeoReflection, !TestBit(kGeoReflection));
2522 if (right->IsScale()) {
2524 memcpy(fScale,r_scl,kN3);
2526 if (right->IsTranslation()) {
2527 SetBit(kGeoTranslation);
2528 memcpy(fTranslation,r_tra,kN3);
2533 Double_t new_rot[9];
2535 if (right->IsRotation()) {
2536 SetBit(kGeoRotation);
2537 if (right->IsReflection()) SetBit(kGeoReflection, !TestBit(kGeoReflection));
2539 if (right->IsScale()) SetBit(kGeoScale);
2540 if (right->IsTranslation()) SetBit(kGeoTranslation);
2543 if (IsTranslation()) {
2544 for (i=0; i<3; i++) {
2545 fTranslation[i] += fRotationMatrix[3*i]*r_tra[0]
2546 + fRotationMatrix[3*i+1]*r_tra[1]
2547 + fRotationMatrix[3*i+2]*r_tra[2];
2552 for (i=0; i<3; i++) {
2553 for (j=0; j<3; j++) {
2554 new_rot[3*i+j] = fRotationMatrix[3*i]*r_rot[j] +
2555 fRotationMatrix[3*i+1]*r_rot[3+j] +
2556 fRotationMatrix[3*i+2]*r_rot[6+j];
2559 memcpy(fRotationMatrix,new_rot,kN9);
2563 for (i=0; i<3; i++) fScale[i] *= r_scl[i];
2571 void TGeoHMatrix::MultiplyLeft(
const TGeoMatrix *left)
2573 if (left == gGeoIdentity)
return;
2574 const Double_t *l_tra = left->GetTranslation();
2575 const Double_t *l_rot = left->GetRotationMatrix();
2576 const Double_t *l_scl = left->GetScale();
2578 if (left->IsRotation()) {
2579 if (left->IsReflection()) SetBit(kGeoReflection, !TestBit(kGeoReflection));
2580 SetBit(kGeoRotation);
2581 memcpy(fRotationMatrix,l_rot,kN9);
2583 if (left->IsScale()) {
2585 memcpy(fScale,l_scl,kN3);
2587 if (left->IsTranslation()) {
2588 SetBit(kGeoTranslation);
2589 memcpy(fTranslation,l_tra,kN3);
2594 Double_t new_tra[3];
2595 Double_t new_rot[9];
2597 if (left->IsRotation()) {
2598 SetBit(kGeoRotation);
2599 if (left->IsReflection()) SetBit(kGeoReflection, !TestBit(kGeoReflection));
2601 if (left->IsScale()) SetBit(kGeoScale);
2602 if (left->IsTranslation()) SetBit(kGeoTranslation);
2605 if (IsTranslation()) {
2606 for (i=0; i<3; i++) {
2607 new_tra[i] = l_tra[i]
2608 + l_rot[3*i]* fTranslation[0]
2609 + l_rot[3*i+1]*fTranslation[1]
2610 + l_rot[3*i+2]*fTranslation[2];
2612 memcpy(fTranslation,new_tra,kN3);
2616 for (i=0; i<3; i++) {
2617 for (j=0; j<3; j++) {
2618 new_rot[3*i+j] = l_rot[3*i]*fRotationMatrix[j] +
2619 l_rot[3*i+1]*fRotationMatrix[3+j] +
2620 l_rot[3*i+2]*fRotationMatrix[6+j];
2623 memcpy(fRotationMatrix,new_rot,kN9);
2627 for (i=0; i<3; i++) fScale[i] *= l_scl[i];
2634 void TGeoHMatrix::RotateX(Double_t angle)
2636 SetBit(kGeoRotation);
2637 Double_t phi = angle*TMath::DegToRad();
2638 Double_t c = TMath::Cos(phi);
2639 Double_t s = TMath::Sin(phi);
2641 v[0] = fRotationMatrix[0];
2642 v[1] = fRotationMatrix[1];
2643 v[2] = fRotationMatrix[2];
2644 v[3] = c*fRotationMatrix[3]-s*fRotationMatrix[6];
2645 v[4] = c*fRotationMatrix[4]-s*fRotationMatrix[7];
2646 v[5] = c*fRotationMatrix[5]-s*fRotationMatrix[8];
2647 v[6] = s*fRotationMatrix[3]+c*fRotationMatrix[6];
2648 v[7] = s*fRotationMatrix[4]+c*fRotationMatrix[7];
2649 v[8] = s*fRotationMatrix[5]+c*fRotationMatrix[8];
2650 memcpy(fRotationMatrix, v, kN9);
2652 v[0] = fTranslation[0];
2653 v[1] = c*fTranslation[1]-s*fTranslation[2];
2654 v[2] = s*fTranslation[1]+c*fTranslation[2];
2655 memcpy(fTranslation,v,kN3);
2661 void TGeoHMatrix::RotateY(Double_t angle)
2663 SetBit(kGeoRotation);
2664 Double_t phi = angle*TMath::DegToRad();
2665 Double_t c = TMath::Cos(phi);
2666 Double_t s = TMath::Sin(phi);
2668 v[0] = c*fRotationMatrix[0]+s*fRotationMatrix[6];
2669 v[1] = c*fRotationMatrix[1]+s*fRotationMatrix[7];
2670 v[2] = c*fRotationMatrix[2]+s*fRotationMatrix[8];
2671 v[3] = fRotationMatrix[3];
2672 v[4] = fRotationMatrix[4];
2673 v[5] = fRotationMatrix[5];
2674 v[6] = -s*fRotationMatrix[0]+c*fRotationMatrix[6];
2675 v[7] = -s*fRotationMatrix[1]+c*fRotationMatrix[7];
2676 v[8] = -s*fRotationMatrix[2]+c*fRotationMatrix[8];
2677 memcpy(fRotationMatrix, v, kN9);
2679 v[0] = c*fTranslation[0]+s*fTranslation[2];
2680 v[1] = fTranslation[1];
2681 v[2] = -s*fTranslation[0]+c*fTranslation[2];
2682 memcpy(fTranslation,v,kN3);
2688 void TGeoHMatrix::RotateZ(Double_t angle)
2690 SetBit(kGeoRotation);
2691 Double_t phi = angle*TMath::DegToRad();
2692 Double_t c = TMath::Cos(phi);
2693 Double_t s = TMath::Sin(phi);
2695 v[0] = c*fRotationMatrix[0]-s*fRotationMatrix[3];
2696 v[1] = c*fRotationMatrix[1]-s*fRotationMatrix[4];
2697 v[2] = c*fRotationMatrix[2]-s*fRotationMatrix[5];
2698 v[3] = s*fRotationMatrix[0]+c*fRotationMatrix[3];
2699 v[4] = s*fRotationMatrix[1]+c*fRotationMatrix[4];
2700 v[5] = s*fRotationMatrix[2]+c*fRotationMatrix[5];
2701 v[6] = fRotationMatrix[6];
2702 v[7] = fRotationMatrix[7];
2703 v[8] = fRotationMatrix[8];
2704 memcpy(&fRotationMatrix[0],v,kN9);
2706 v[0] = c*fTranslation[0]-s*fTranslation[1];
2707 v[1] = s*fTranslation[0]+c*fTranslation[1];
2708 v[2] = fTranslation[2];
2709 memcpy(fTranslation,v,kN3);
2715 void TGeoHMatrix::ReflectX(Bool_t leftside, Bool_t rotonly)
2717 if (leftside && !rotonly) fTranslation[0] = -fTranslation[0];
2719 fRotationMatrix[0]=-fRotationMatrix[0];
2720 fRotationMatrix[1]=-fRotationMatrix[1];
2721 fRotationMatrix[2]=-fRotationMatrix[2];
2723 fRotationMatrix[0]=-fRotationMatrix[0];
2724 fRotationMatrix[3]=-fRotationMatrix[3];
2725 fRotationMatrix[6]=-fRotationMatrix[6];
2727 SetBit(kGeoRotation);
2728 SetBit(kGeoReflection, !IsReflection());
2734 void TGeoHMatrix::ReflectY(Bool_t leftside, Bool_t rotonly)
2736 if (leftside && !rotonly) fTranslation[1] = -fTranslation[1];
2738 fRotationMatrix[3]=-fRotationMatrix[3];
2739 fRotationMatrix[4]=-fRotationMatrix[4];
2740 fRotationMatrix[5]=-fRotationMatrix[5];
2742 fRotationMatrix[1]=-fRotationMatrix[1];
2743 fRotationMatrix[4]=-fRotationMatrix[4];
2744 fRotationMatrix[7]=-fRotationMatrix[7];
2746 SetBit(kGeoRotation);
2747 SetBit(kGeoReflection, !IsReflection());
2753 void TGeoHMatrix::ReflectZ(Bool_t leftside, Bool_t rotonly)
2755 if (leftside && !rotonly) fTranslation[2] = -fTranslation[2];
2757 fRotationMatrix[6]=-fRotationMatrix[6];
2758 fRotationMatrix[7]=-fRotationMatrix[7];
2759 fRotationMatrix[8]=-fRotationMatrix[8];
2761 fRotationMatrix[2]=-fRotationMatrix[2];
2762 fRotationMatrix[5]=-fRotationMatrix[5];
2763 fRotationMatrix[8]=-fRotationMatrix[8];
2765 SetBit(kGeoRotation);
2766 SetBit(kGeoReflection, !IsReflection());
2772 void TGeoHMatrix::SavePrimitive(std::ostream &out, Option_t * )
2774 if (TestBit(kGeoSavePrimitive))
return;
2775 const Double_t *tr = fTranslation;
2776 const Double_t *rot = fRotationMatrix;
2777 out <<
" // HMatrix: " << GetName() << std::endl;
2778 out <<
" tr[0] = " << tr[0] <<
"; " <<
"tr[1] = " << tr[1] <<
"; " <<
"tr[2] = " << tr[2] <<
";" << std::endl;
2779 out <<
" rot[0] =" << rot[0] <<
"; " <<
"rot[1] = " << rot[1] <<
"; " <<
"rot[2] = " << rot[2] <<
";" << std::endl;
2780 out <<
" rot[3] =" << rot[3] <<
"; " <<
"rot[4] = " << rot[4] <<
"; " <<
"rot[5] = " << rot[5] <<
";" << std::endl;
2781 out <<
" rot[6] =" << rot[6] <<
"; " <<
"rot[7] = " << rot[7] <<
"; " <<
"rot[8] = " << rot[8] <<
";" << std::endl;
2782 char *name = GetPointerName();
2783 out <<
" TGeoHMatrix *" << name <<
" = new TGeoHMatrix(\"" << GetName() <<
"\");" << std::endl;
2784 out <<
" " << name <<
"->SetTranslation(tr);" << std::endl;
2785 out <<
" " << name <<
"->SetRotation(rot);" << std::endl;
2786 if (IsTranslation()) out <<
" " << name <<
"->SetBit(TGeoMatrix::kGeoTranslation);" << std::endl;
2787 if (IsRotation()) out <<
" " << name <<
"->SetBit(TGeoMatrix::kGeoRotation);" << std::endl;
2788 if (IsReflection()) out <<
" " << name <<
"->SetBit(TGeoMatrix::kGeoReflection);" << std::endl;
2789 TObject::SetBit(kGeoSavePrimitive);