00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170 #include "Riostream.h"
00171 #include "TObjArray.h"
00172
00173 #include "TGeoManager.h"
00174 #include "TGeoMatrix.h"
00175 #include "TMath.h"
00176
00177 TGeoIdentity *gGeoIdentity = 0;
00178 const Int_t kN3 = 3*sizeof(Double_t);
00179 const Int_t kN9 = 9*sizeof(Double_t);
00180
00181
00182
00183 ClassImp(TGeoMatrix)
00184
00185
00186 TGeoMatrix::TGeoMatrix()
00187 {
00188
00189 }
00190
00191
00192 TGeoMatrix::TGeoMatrix(const TGeoMatrix &other)
00193 :TNamed(other)
00194 {
00195
00196 ResetBit(kGeoRegistered);
00197 }
00198
00199
00200 TGeoMatrix::TGeoMatrix(const char *name)
00201 :TNamed(name, "")
00202 {
00203
00204 }
00205
00206
00207 TGeoMatrix::~TGeoMatrix()
00208 {
00209
00210 if (IsRegistered() && gGeoManager) {
00211 if (gGeoManager->GetListOfVolumes()) {
00212 gGeoManager->GetListOfMatrices()->Remove(this);
00213 Warning("dtor", "Registered matrix %s was removed", GetName());
00214 }
00215 }
00216 }
00217
00218
00219 TGeoMatrix& TGeoMatrix::operator = (const TGeoMatrix &matrix)
00220 {
00221
00222 if (&matrix == this) return *this;
00223 Bool_t registered = TestBit(kGeoRegistered);
00224 TNamed::operator=(matrix);
00225 SetBit(kGeoRegistered,registered);
00226 return *this;
00227 }
00228
00229
00230 TGeoMatrix &TGeoMatrix::operator*(const TGeoMatrix &right) const
00231 {
00232
00233 static TGeoHMatrix h;
00234 h = *this;
00235 h.Multiply(&right);
00236 return h;
00237 }
00238
00239
00240 Bool_t TGeoMatrix::operator ==(const TGeoMatrix &other) const
00241 {
00242
00243 if (&other == this) return kTRUE;
00244 Int_t i;
00245 Bool_t tr1 = IsTranslation();
00246 Bool_t tr2 = other.IsTranslation();
00247 if ((tr1 & !tr2) || (tr2 & !tr1)) return kFALSE;
00248 Bool_t rr1 = IsRotation();
00249 Bool_t rr2 = other.IsRotation();
00250 if ((rr1 & !rr2) || (rr2 & !rr1)) return kFALSE;
00251
00252 if (tr1) {
00253 const Double_t *tr = GetTranslation();
00254 const Double_t *otr = other.GetTranslation();
00255 for (i=0; i<3; i++) if (TMath::Abs(tr[i]-otr[i])>1.E-10) return kFALSE;
00256 }
00257
00258 if (rr1) {
00259 const Double_t *rot = GetRotationMatrix();
00260 const Double_t *orot = other.GetRotationMatrix();
00261 for (i=0; i<9; i++) if (TMath::Abs(rot[i]-orot[i])>1.E-10) return kFALSE;
00262 }
00263 return kTRUE;
00264 }
00265
00266
00267 Bool_t TGeoMatrix::IsRotAboutZ() const
00268 {
00269
00270 if (IsIdentity()) return kTRUE;
00271 const Double_t *rot = GetRotationMatrix();
00272 if (TMath::Abs(rot[6])>1E-9) return kFALSE;
00273 if (TMath::Abs(rot[7])>1E-9) return kFALSE;
00274 if ((1.-TMath::Abs(rot[8]))>1E-9) return kFALSE;
00275 return kTRUE;
00276 }
00277
00278
00279 Int_t TGeoMatrix::GetByteCount() const
00280 {
00281
00282 Int_t count = 4+28+strlen(GetName())+strlen(GetTitle());
00283 if (IsTranslation()) count += 12;
00284 if (IsScale()) count += 12;
00285 if (IsCombi() || IsGeneral()) count += 4 + 36;
00286 return count;
00287 }
00288
00289
00290 char *TGeoMatrix::GetPointerName() const
00291 {
00292
00293 static TString name;
00294 name = TString::Format("pMatrix%d", GetUniqueID());
00295 return (char*)name.Data();
00296 }
00297
00298
00299 void TGeoMatrix::GetHomogenousMatrix(Double_t *hmat) const
00300 {
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312 Double_t *hmatrix = hmat;
00313 const Double_t *mat = GetRotationMatrix();
00314 for (Int_t i=0; i<3; i++) {
00315 memcpy(hmatrix, mat, kN3);
00316 mat += 3;
00317 hmatrix += 3;
00318 *hmatrix = 0.0;
00319 hmatrix++;
00320 }
00321 memcpy(hmatrix, GetTranslation(), kN3);
00322 hmatrix = hmat;
00323 if (IsScale()) {
00324 for (Int_t i=0; i<3; i++) {
00325 *hmatrix *= GetScale()[i];
00326 hmatrix += 5;
00327 }
00328 }
00329 }
00330
00331
00332 void TGeoMatrix::LocalToMaster(const Double_t *local, Double_t *master) const
00333 {
00334
00335 if (IsIdentity()) {
00336 memcpy(master, local, kN3);
00337 return;
00338 }
00339 Int_t i;
00340 const Double_t *tr = GetTranslation();
00341 if (!IsRotation()) {
00342 for (i=0; i<3; i++) master[i] = tr[i] + local[i];
00343 return;
00344 }
00345 const Double_t *rot = GetRotationMatrix();
00346 for (i=0; i<3; i++) {
00347 master[i] = tr[i]
00348 + local[0]*rot[3*i]
00349 + local[1]*rot[3*i+1]
00350 + local[2]*rot[3*i+2];
00351 }
00352 }
00353
00354
00355 void TGeoMatrix::LocalToMasterVect(const Double_t *local, Double_t *master) const
00356 {
00357
00358 if (!IsRotation()) {
00359 memcpy(master, local, kN3);
00360 return;
00361 }
00362 const Double_t *rot = GetRotationMatrix();
00363 for (Int_t i=0; i<3; i++) {
00364 master[i] = local[0]*rot[3*i]
00365 + local[1]*rot[3*i+1]
00366 + local[2]*rot[3*i+2];
00367 }
00368 }
00369
00370
00371 void TGeoMatrix::LocalToMasterBomb(const Double_t *local, Double_t *master) const
00372 {
00373
00374 if (IsIdentity()) {
00375 memcpy(master, local, kN3);
00376 return;
00377 }
00378 Int_t i;
00379 const Double_t *tr = GetTranslation();
00380 Double_t bombtr[3];
00381 gGeoManager->BombTranslation(tr, &bombtr[0]);
00382 if (!IsRotation()) {
00383 for (i=0; i<3; i++) master[i] = bombtr[i] + local[i];
00384 return;
00385 }
00386 const Double_t *rot = GetRotationMatrix();
00387 for (i=0; i<3; i++) {
00388 master[i] = bombtr[i]
00389 + local[0]*rot[3*i]
00390 + local[1]*rot[3*i+1]
00391 + local[2]*rot[3*i+2];
00392 }
00393 }
00394
00395
00396 void TGeoMatrix::MasterToLocal(const Double_t *master, Double_t *local) const
00397 {
00398
00399 if (IsIdentity()) {
00400 memcpy(local, master, kN3);
00401 return;
00402 }
00403 const Double_t *tr = GetTranslation();
00404 Double_t mt0 = master[0]-tr[0];
00405 Double_t mt1 = master[1]-tr[1];
00406 Double_t mt2 = master[2]-tr[2];
00407 if (!IsRotation()) {
00408 local[0] = mt0;
00409 local[1] = mt1;
00410 local[2] = mt2;
00411 return;
00412 }
00413 const Double_t *rot = GetRotationMatrix();
00414 local[0] = mt0*rot[0] + mt1*rot[3] + mt2*rot[6];
00415 local[1] = mt0*rot[1] + mt1*rot[4] + mt2*rot[7];
00416 local[2] = mt0*rot[2] + mt1*rot[5] + mt2*rot[8];
00417 }
00418
00419
00420 void TGeoMatrix::MasterToLocalVect(const Double_t *master, Double_t *local) const
00421 {
00422
00423 if (!IsRotation()) {
00424 memcpy(local, master, kN3);
00425 return;
00426 }
00427 const Double_t *rot = GetRotationMatrix();
00428 for (Int_t i=0; i<3; i++) {
00429 local[i] = master[0]*rot[i]
00430 + master[1]*rot[i+3]
00431 + master[2]*rot[i+6];
00432 }
00433 }
00434
00435
00436 void TGeoMatrix::MasterToLocalBomb(const Double_t *master, Double_t *local) const
00437 {
00438
00439 if (IsIdentity()) {
00440 memcpy(local, master, kN3);
00441 return;
00442 }
00443 const Double_t *tr = GetTranslation();
00444 Double_t bombtr[3];
00445 Int_t i;
00446 gGeoManager->UnbombTranslation(tr, &bombtr[0]);
00447 if (!IsRotation()) {
00448 for (i=0; i<3; i++) local[i] = master[i]-bombtr[i];
00449 return;
00450 }
00451 const Double_t *rot = GetRotationMatrix();
00452 for (i=0; i<3; i++) {
00453 local[i] = (master[0]-bombtr[0])*rot[i]
00454 + (master[1]-bombtr[1])*rot[i+3]
00455 + (master[2]-bombtr[2])*rot[i+6];
00456 }
00457 }
00458
00459
00460 void TGeoMatrix::Normalize(Double_t *vect)
00461 {
00462
00463 Double_t normfactor = vect[0]*vect[0] + vect[1]*vect[1] + vect[2]*vect[2];
00464 if (normfactor <= 1E-10) return;
00465 normfactor = 1./TMath::Sqrt(normfactor);
00466 vect[0] *= normfactor;
00467 vect[1] *= normfactor;
00468 vect[2] *= normfactor;
00469 }
00470
00471
00472 void TGeoMatrix::Print(Option_t *) const
00473 {
00474
00475 const Double_t *rot = GetRotationMatrix();
00476 const Double_t *tr = GetTranslation();
00477 printf("matrix %s - tr=%d rot=%d refl=%d scl=%d\n", GetName(),(Int_t)IsTranslation(),
00478 (Int_t)IsRotation(), (Int_t)IsReflection(), (Int_t)IsScale());
00479 printf("%10.6f%12.6f%12.6f Tx = %10.6f\n", rot[0], rot[1], rot[2], tr[0]);
00480 printf("%10.6f%12.6f%12.6f Ty = %10.6f\n", rot[3], rot[4], rot[5], tr[1]);
00481 printf("%10.6f%12.6f%12.6f Tz = %10.6f\n", rot[6], rot[7], rot[8], tr[2]);
00482 if (IsScale()) {
00483 const Double_t *scl = GetScale();
00484 printf("Sx=%10.6fSy=%12.6fSz=%12.6f\n", scl[0], scl[1], scl[2]);
00485 }
00486 }
00487
00488
00489 void TGeoMatrix::ReflectX(Bool_t, Bool_t)
00490 {
00491
00492 }
00493
00494
00495 void TGeoMatrix::ReflectY(Bool_t, Bool_t)
00496 {
00497
00498 }
00499
00500
00501 void TGeoMatrix::ReflectZ(Bool_t, Bool_t)
00502 {
00503
00504 }
00505
00506
00507 void TGeoMatrix::RegisterYourself()
00508 {
00509
00510 if (!gGeoManager) {
00511 Warning("RegisterYourself", "cannot register without geometry");
00512 return;
00513 }
00514 if (!IsRegistered()) {
00515 gGeoManager->RegisterMatrix(this);
00516 SetBit(kGeoRegistered);
00517 }
00518 }
00519
00520
00521 void TGeoMatrix::SetDefaultName()
00522 {
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532 if (!gGeoManager) return;
00533 if (strlen(GetName())) return;
00534 char type = 'n';
00535 if (IsTranslation()) type = 't';
00536 if (IsRotation()) type = 'r';
00537 if (IsScale()) type = 's';
00538 if (IsCombi()) type = 'c';
00539 if (IsGeneral()) type = 'g';
00540 TObjArray *matrices = gGeoManager->GetListOfMatrices();
00541 Int_t index = 0;
00542 if (matrices) index =matrices->GetEntriesFast() - 1;
00543 TString name = TString::Format("%c%d", type, index);
00544 SetName(name);
00545 }
00546
00547
00548 ClassImp(TGeoTranslation)
00549
00550
00551 TGeoTranslation::TGeoTranslation()
00552 {
00553
00554 for (Int_t i=0; i<3; i++) fTranslation[i] = 0;
00555 }
00556
00557
00558 TGeoTranslation::TGeoTranslation(const TGeoTranslation &other)
00559 :TGeoMatrix(other)
00560 {
00561
00562 SetTranslation(other);
00563 }
00564
00565
00566 TGeoTranslation::TGeoTranslation(const TGeoMatrix &other)
00567 :TGeoMatrix(other)
00568 {
00569
00570 SetTranslation(other);
00571 }
00572
00573
00574 TGeoTranslation::TGeoTranslation(Double_t dx, Double_t dy, Double_t dz)
00575 :TGeoMatrix("")
00576 {
00577
00578 if (dx || dy || dz) SetBit(kGeoTranslation);
00579 SetTranslation(dx, dy, dz);
00580 }
00581
00582
00583 TGeoTranslation::TGeoTranslation(const char *name, Double_t dx, Double_t dy, Double_t dz)
00584 :TGeoMatrix(name)
00585 {
00586
00587 if (dx || dy || dz) SetBit(kGeoTranslation);
00588 SetTranslation(dx, dy, dz);
00589 }
00590
00591
00592 TGeoTranslation& TGeoTranslation::operator = (const TGeoMatrix &matrix)
00593 {
00594
00595 if (&matrix == this) return *this;
00596 TGeoMatrix::operator=(matrix);
00597 SetTranslation(matrix);
00598 return *this;
00599 }
00600
00601
00602 TGeoMatrix& TGeoTranslation::Inverse() const
00603 {
00604
00605 static TGeoHMatrix h;
00606 h = *this;
00607 Double_t tr[3];
00608 tr[0] = -fTranslation[0];
00609 tr[1] = -fTranslation[1];
00610 tr[2] = -fTranslation[2];
00611 h.SetTranslation(tr);
00612 return h;
00613 }
00614
00615
00616 void TGeoTranslation::Add(const TGeoTranslation *other)
00617 {
00618
00619 const Double_t *trans = other->GetTranslation();
00620 for (Int_t i=0; i<3; i++)
00621 fTranslation[i] += trans[i];
00622 }
00623
00624
00625 TGeoMatrix *TGeoTranslation::MakeClone() const
00626 {
00627
00628 TGeoMatrix *matrix = new TGeoTranslation(*this);
00629 return matrix;
00630 }
00631
00632
00633 void TGeoTranslation::RotateX(Double_t )
00634 {
00635
00636 Warning("RotateX", "Not implemented. Use TGeoCombiTrans instead");
00637 }
00638
00639
00640 void TGeoTranslation::RotateY(Double_t )
00641 {
00642
00643 Warning("RotateY", "Not implemented. Use TGeoCombiTrans instead");
00644 }
00645
00646
00647 void TGeoTranslation::RotateZ(Double_t )
00648 {
00649
00650 Warning("RotateZ", "Not implemented. Use TGeoCombiTrans instead");
00651 }
00652
00653
00654 void TGeoTranslation::Subtract(const TGeoTranslation *other)
00655 {
00656
00657 const Double_t *trans = other->GetTranslation();
00658 for (Int_t i=0; i<3; i++)
00659 fTranslation[i] -= trans[i];
00660 }
00661
00662
00663 void TGeoTranslation::SetTranslation(Double_t dx, Double_t dy, Double_t dz)
00664 {
00665
00666 fTranslation[0] = dx;
00667 fTranslation[1] = dy;
00668 fTranslation[2] = dz;
00669 if (dx || dy || dz) SetBit(kGeoTranslation);
00670 else ResetBit(kGeoTranslation);
00671 }
00672
00673
00674 void TGeoTranslation::SetTranslation(const TGeoMatrix &other)
00675 {
00676
00677 SetBit(kGeoTranslation, other.IsTranslation());
00678 const Double_t *transl = other.GetTranslation();
00679 memcpy(fTranslation, transl, kN3);
00680 }
00681
00682
00683 void TGeoTranslation::LocalToMaster(const Double_t *local, Double_t *master) const
00684 {
00685
00686 const Double_t *tr = GetTranslation();
00687 for (Int_t i=0; i<3; i++)
00688 master[i] = tr[i] + local[i];
00689 }
00690
00691
00692 void TGeoTranslation::LocalToMasterVect(const Double_t *local, Double_t *master) const
00693 {
00694
00695 memcpy(master, local, kN3);
00696 }
00697
00698
00699 void TGeoTranslation::LocalToMasterBomb(const Double_t *local, Double_t *master) const
00700 {
00701
00702 const Double_t *tr = GetTranslation();
00703 Double_t bombtr[3];
00704 gGeoManager->BombTranslation(tr, &bombtr[0]);
00705 for (Int_t i=0; i<3; i++)
00706 master[i] = bombtr[i] + local[i];
00707 }
00708
00709
00710 void TGeoTranslation::MasterToLocal(const Double_t *master, Double_t *local) const
00711 {
00712
00713 const Double_t *tr = GetTranslation();
00714 for (Int_t i=0; i<3; i++)
00715 local[i] = master[i]-tr[i];
00716 }
00717
00718
00719 void TGeoTranslation::MasterToLocalVect(const Double_t *master, Double_t *local) const
00720 {
00721
00722 memcpy(local, master, kN3);
00723 }
00724
00725
00726 void TGeoTranslation::MasterToLocalBomb(const Double_t *master, Double_t *local) const
00727 {
00728
00729 const Double_t *tr = GetTranslation();
00730 Double_t bombtr[3];
00731 gGeoManager->UnbombTranslation(tr, &bombtr[0]);
00732 for (Int_t i=0; i<3; i++)
00733 local[i] = master[i]-bombtr[i];
00734 }
00735
00736
00737 void TGeoTranslation::SavePrimitive(ostream &out, Option_t * )
00738 {
00739
00740 if (TestBit(kGeoSavePrimitive)) return;
00741 out << " // Translation: " << GetName() << endl;
00742 out << " dx = " << fTranslation[0] << ";" << endl;
00743 out << " dy = " << fTranslation[1] << ";" << endl;
00744 out << " dz = " << fTranslation[2] << ";" << endl;
00745 out << " TGeoTranslation *" << GetPointerName() << " = new TGeoTranslation(\"" << GetName() << "\",dx,dy,dz);" << endl;
00746 TObject::SetBit(kGeoSavePrimitive);
00747 }
00748
00749
00750
00751 ClassImp(TGeoRotation)
00752
00753
00754 TGeoRotation::TGeoRotation()
00755 {
00756
00757 for (Int_t i=0; i<9; i++) {
00758 if (i%4) fRotationMatrix[i] = 0;
00759 else fRotationMatrix[i] = 1.0;
00760 }
00761 }
00762
00763
00764 TGeoRotation::TGeoRotation(const TGeoRotation &other)
00765 :TGeoMatrix(other)
00766 {
00767
00768 SetRotation(other);
00769 }
00770
00771
00772 TGeoRotation::TGeoRotation(const TGeoMatrix &other)
00773 :TGeoMatrix(other)
00774 {
00775
00776 SetRotation(other);
00777 }
00778
00779
00780 TGeoRotation::TGeoRotation(const char *name)
00781 :TGeoMatrix(name)
00782 {
00783
00784 for (Int_t i=0; i<9; i++) {
00785 if (i%4) fRotationMatrix[i] = 0;
00786 else fRotationMatrix[i] = 1.0;
00787 }
00788 }
00789
00790
00791 TGeoRotation::TGeoRotation(const char *name, Double_t phi, Double_t theta, Double_t psi)
00792 :TGeoMatrix(name)
00793 {
00794
00795
00796
00797
00798 SetAngles(phi, theta, psi);
00799 }
00800
00801
00802 TGeoRotation::TGeoRotation(const char *name, Double_t theta1, Double_t phi1, Double_t theta2, Double_t phi2,
00803 Double_t theta3, Double_t phi3)
00804 :TGeoMatrix(name)
00805 {
00806
00807
00808
00809
00810
00811
00812 SetAngles(theta1, phi1, theta2, phi2, theta3, phi3);
00813 }
00814
00815
00816 TGeoRotation& TGeoRotation::operator = (const TGeoMatrix &other)
00817 {
00818
00819 if (&other == this) return *this;
00820 TGeoMatrix::operator=(other);
00821 SetRotation(other);
00822 return *this;
00823 }
00824
00825
00826 TGeoMatrix& TGeoRotation::Inverse() const
00827 {
00828
00829 static TGeoHMatrix h;
00830 h = *this;
00831 Double_t newrot[9];
00832 newrot[0] = fRotationMatrix[0];
00833 newrot[1] = fRotationMatrix[3];
00834 newrot[2] = fRotationMatrix[6];
00835 newrot[3] = fRotationMatrix[1];
00836 newrot[4] = fRotationMatrix[4];
00837 newrot[5] = fRotationMatrix[7];
00838 newrot[6] = fRotationMatrix[2];
00839 newrot[7] = fRotationMatrix[5];
00840 newrot[8] = fRotationMatrix[8];
00841 h.SetRotation(newrot);
00842 return h;
00843 }
00844
00845
00846 Bool_t TGeoRotation::IsValid() const
00847 {
00848
00849 const Double_t *r = fRotationMatrix;
00850 Double_t cij;
00851 for (Int_t i=0; i<2; i++) {
00852 for (Int_t j=i+1; j<3; j++) {
00853
00854 cij = TMath::Abs(r[i]*r[j]+r[i+3]*r[j+3]+r[i+6]*r[j+6]);
00855 if (cij>1E-4) return kFALSE;
00856
00857 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]);
00858 if (cij>1E-4) return kFALSE;
00859 }
00860 }
00861 return kTRUE;
00862 }
00863
00864
00865 void TGeoRotation::Clear(Option_t *)
00866 {
00867
00868 memcpy(fRotationMatrix,kIdentityMatrix,kN9);
00869 ResetBit(kGeoRotation);
00870 }
00871
00872
00873 void TGeoRotation::FastRotZ(Double_t *sincos)
00874 {
00875
00876 fRotationMatrix[0] = sincos[1];
00877 fRotationMatrix[1] = -sincos[0];
00878 fRotationMatrix[3] = sincos[0];
00879 fRotationMatrix[4] = sincos[1];
00880 SetBit(kGeoRotation);
00881 }
00882
00883
00884 Double_t TGeoRotation::GetPhiRotation(Bool_t fixX) const
00885 {
00886
00887
00888
00889
00890 Double_t phi;
00891 if (fixX) phi = 180.*TMath::ATan2(-fRotationMatrix[1],fRotationMatrix[4])/TMath::Pi();
00892 else phi = 180.*TMath::ATan2(fRotationMatrix[3], fRotationMatrix[0])/TMath::Pi();
00893 return phi;
00894 }
00895
00896
00897 void TGeoRotation::LocalToMaster(const Double_t *local, Double_t *master) const
00898 {
00899
00900 const Double_t *rot = GetRotationMatrix();
00901 for (Int_t i=0; i<3; i++) {
00902 master[i] = local[0]*rot[3*i]
00903 + local[1]*rot[3*i+1]
00904 + local[2]*rot[3*i+2];
00905 }
00906 }
00907
00908
00909 void TGeoRotation::MasterToLocal(const Double_t *master, Double_t *local) const
00910 {
00911
00912 const Double_t *rot = GetRotationMatrix();
00913 for (Int_t i=0; i<3; i++) {
00914 local[i] = master[0]*rot[i]
00915 + master[1]*rot[i+3]
00916 + master[2]*rot[i+6];
00917 }
00918 }
00919
00920
00921 TGeoMatrix *TGeoRotation::MakeClone() const
00922 {
00923
00924 TGeoMatrix *matrix = new TGeoRotation(*this);
00925 return matrix;
00926 }
00927
00928
00929 void TGeoRotation::RotateX(Double_t angle)
00930 {
00931
00932 SetBit(kGeoRotation);
00933 Double_t phi = angle*TMath::DegToRad();
00934 Double_t c = TMath::Cos(phi);
00935 Double_t s = TMath::Sin(phi);
00936 Double_t v[9];
00937 v[0] = fRotationMatrix[0];
00938 v[1] = fRotationMatrix[1];
00939 v[2] = fRotationMatrix[2];
00940 v[3] = c*fRotationMatrix[3]-s*fRotationMatrix[6];
00941 v[4] = c*fRotationMatrix[4]-s*fRotationMatrix[7];
00942 v[5] = c*fRotationMatrix[5]-s*fRotationMatrix[8];
00943 v[6] = s*fRotationMatrix[3]+c*fRotationMatrix[6];
00944 v[7] = s*fRotationMatrix[4]+c*fRotationMatrix[7];
00945 v[8] = s*fRotationMatrix[5]+c*fRotationMatrix[8];
00946
00947 memcpy(fRotationMatrix, v, kN9);
00948 }
00949
00950
00951 void TGeoRotation::RotateY(Double_t angle)
00952 {
00953
00954 SetBit(kGeoRotation);
00955 Double_t phi = angle*TMath::DegToRad();
00956 Double_t c = TMath::Cos(phi);
00957 Double_t s = TMath::Sin(phi);
00958 Double_t v[9];
00959 v[0] = c*fRotationMatrix[0]+s*fRotationMatrix[6];
00960 v[1] = c*fRotationMatrix[1]+s*fRotationMatrix[7];
00961 v[2] = c*fRotationMatrix[2]+s*fRotationMatrix[8];
00962 v[3] = fRotationMatrix[3];
00963 v[4] = fRotationMatrix[4];
00964 v[5] = fRotationMatrix[5];
00965 v[6] = -s*fRotationMatrix[0]+c*fRotationMatrix[6];
00966 v[7] = -s*fRotationMatrix[1]+c*fRotationMatrix[7];
00967 v[8] = -s*fRotationMatrix[2]+c*fRotationMatrix[8];
00968
00969 memcpy(fRotationMatrix, v, kN9);
00970 }
00971
00972
00973 void TGeoRotation::RotateZ(Double_t angle)
00974 {
00975
00976 SetBit(kGeoRotation);
00977 Double_t phi = angle*TMath::DegToRad();
00978 Double_t c = TMath::Cos(phi);
00979 Double_t s = TMath::Sin(phi);
00980 Double_t v[9];
00981 v[0] = c*fRotationMatrix[0]-s*fRotationMatrix[3];
00982 v[1] = c*fRotationMatrix[1]-s*fRotationMatrix[4];
00983 v[2] = c*fRotationMatrix[2]-s*fRotationMatrix[5];
00984 v[3] = s*fRotationMatrix[0]+c*fRotationMatrix[3];
00985 v[4] = s*fRotationMatrix[1]+c*fRotationMatrix[4];
00986 v[5] = s*fRotationMatrix[2]+c*fRotationMatrix[5];
00987 v[6] = fRotationMatrix[6];
00988 v[7] = fRotationMatrix[7];
00989 v[8] = fRotationMatrix[8];
00990
00991 memcpy(&fRotationMatrix[0],v,kN9);
00992 }
00993
00994
00995 void TGeoRotation::ReflectX(Bool_t leftside, Bool_t)
00996 {
00997
00998 if (leftside) {
00999 fRotationMatrix[0]=-fRotationMatrix[0];
01000 fRotationMatrix[1]=-fRotationMatrix[1];
01001 fRotationMatrix[2]=-fRotationMatrix[2];
01002 } else {
01003 fRotationMatrix[0]=-fRotationMatrix[0];
01004 fRotationMatrix[3]=-fRotationMatrix[3];
01005 fRotationMatrix[6]=-fRotationMatrix[6];
01006 }
01007 SetBit(kGeoRotation);
01008 SetBit(kGeoReflection, !IsReflection());
01009 }
01010
01011
01012 void TGeoRotation::ReflectY(Bool_t leftside, Bool_t)
01013 {
01014
01015 if (leftside) {
01016 fRotationMatrix[3]=-fRotationMatrix[3];
01017 fRotationMatrix[4]=-fRotationMatrix[4];
01018 fRotationMatrix[5]=-fRotationMatrix[5];
01019 } else {
01020 fRotationMatrix[1]=-fRotationMatrix[1];
01021 fRotationMatrix[4]=-fRotationMatrix[4];
01022 fRotationMatrix[7]=-fRotationMatrix[7];
01023 }
01024 SetBit(kGeoRotation);
01025 SetBit(kGeoReflection, !IsReflection());
01026 }
01027
01028
01029 void TGeoRotation::ReflectZ(Bool_t leftside, Bool_t)
01030 {
01031
01032 if (leftside) {
01033 fRotationMatrix[6]=-fRotationMatrix[6];
01034 fRotationMatrix[7]=-fRotationMatrix[7];
01035 fRotationMatrix[8]=-fRotationMatrix[8];
01036 } else {
01037 fRotationMatrix[2]=-fRotationMatrix[2];
01038 fRotationMatrix[5]=-fRotationMatrix[5];
01039 fRotationMatrix[8]=-fRotationMatrix[8];
01040 }
01041 SetBit(kGeoRotation);
01042 SetBit(kGeoReflection, !IsReflection());
01043 }
01044
01045
01046 void TGeoRotation::SavePrimitive(ostream &out, Option_t * )
01047 {
01048
01049 if (TestBit(kGeoSavePrimitive)) return;
01050 out << " // Rotation: " << GetName() << endl;
01051 Double_t th1,ph1,th2,ph2,th3,ph3;
01052 GetAngles(th1,ph1,th2,ph2,th3,ph3);
01053 out << " thx = " << th1 << "; phx = " << ph1 << ";" << endl;
01054 out << " thy = " << th2 << "; phy = " << ph2 << ";" << endl;
01055 out << " thz = " << th3 << "; phz = " << ph3 << ";" << endl;
01056 out << " TGeoRotation *" << GetPointerName() << " = new TGeoRotation(\"" << GetName() << "\",thx,phx,thy,phy,thz,phz);" << endl;
01057 TObject::SetBit(kGeoSavePrimitive);
01058 }
01059
01060
01061 void TGeoRotation::SetRotation(const TGeoMatrix &other)
01062 {
01063
01064 SetBit(kGeoRotation, other.IsRotation());
01065 const Double_t *rot = other.GetRotationMatrix();
01066 SetMatrix(rot);
01067 }
01068
01069
01070 void TGeoRotation::SetAngles(Double_t phi, Double_t theta, Double_t psi)
01071 {
01072
01073 Double_t degrad = TMath::Pi()/180.;
01074 Double_t sinphi = TMath::Sin(degrad*phi);
01075 Double_t cosphi = TMath::Cos(degrad*phi);
01076 Double_t sinthe = TMath::Sin(degrad*theta);
01077 Double_t costhe = TMath::Cos(degrad*theta);
01078 Double_t sinpsi = TMath::Sin(degrad*psi);
01079 Double_t cospsi = TMath::Cos(degrad*psi);
01080
01081 fRotationMatrix[0] = cospsi*cosphi - costhe*sinphi*sinpsi;
01082 fRotationMatrix[1] = -sinpsi*cosphi - costhe*sinphi*cospsi;
01083 fRotationMatrix[2] = sinthe*sinphi;
01084 fRotationMatrix[3] = cospsi*sinphi + costhe*cosphi*sinpsi;
01085 fRotationMatrix[4] = -sinpsi*sinphi + costhe*cosphi*cospsi;
01086 fRotationMatrix[5] = -sinthe*cosphi;
01087 fRotationMatrix[6] = sinpsi*sinthe;
01088 fRotationMatrix[7] = cospsi*sinthe;
01089 fRotationMatrix[8] = costhe;
01090
01091 if (!IsValid()) Error("SetAngles", "invalid rotation (Euler angles : phi=%f theta=%f psi=%f)",phi,theta,psi);
01092 CheckMatrix();
01093 }
01094
01095
01096 void TGeoRotation::SetAngles(Double_t theta1, Double_t phi1, Double_t theta2, Double_t phi2,
01097 Double_t theta3, Double_t phi3)
01098 {
01099
01100 Double_t degrad = TMath::Pi()/180.;
01101 fRotationMatrix[0] = TMath::Cos(degrad*phi1)*TMath::Sin(degrad*theta1);
01102 fRotationMatrix[3] = TMath::Sin(degrad*phi1)*TMath::Sin(degrad*theta1);
01103 fRotationMatrix[6] = TMath::Cos(degrad*theta1);
01104 fRotationMatrix[1] = TMath::Cos(degrad*phi2)*TMath::Sin(degrad*theta2);
01105 fRotationMatrix[4] = TMath::Sin(degrad*phi2)*TMath::Sin(degrad*theta2);
01106 fRotationMatrix[7] = TMath::Cos(degrad*theta2);
01107 fRotationMatrix[2] = TMath::Cos(degrad*phi3)*TMath::Sin(degrad*theta3);
01108 fRotationMatrix[5] = TMath::Sin(degrad*phi3)*TMath::Sin(degrad*theta3);
01109 fRotationMatrix[8] = TMath::Cos(degrad*theta3);
01110
01111 for (Int_t i=0; i<9; i++) {
01112 if (TMath::Abs(fRotationMatrix[i])<1E-15) fRotationMatrix[i] = 0;
01113 if (TMath::Abs(fRotationMatrix[i]-1)<1E-15) fRotationMatrix[i] = 1;
01114 if (TMath::Abs(fRotationMatrix[i]+1)<1E-15) fRotationMatrix[i] = -1;
01115 }
01116 if (!IsValid()) Error("SetAngles", "invalid rotation (G3 angles, th1=%f phi1=%f, th2=%f ph2=%f, th3=%f phi3=%f)",
01117 theta1,phi1,theta2,phi2,theta3,phi3);
01118 CheckMatrix();
01119 }
01120
01121
01122 void TGeoRotation::GetAngles(Double_t &theta1, Double_t &phi1, Double_t &theta2, Double_t &phi2,
01123 Double_t &theta3, Double_t &phi3) const
01124 {
01125
01126 Double_t raddeg = 180./TMath::Pi();
01127 theta1 = raddeg*TMath::ACos(fRotationMatrix[6]);
01128 theta2 = raddeg*TMath::ACos(fRotationMatrix[7]);
01129 theta3 = raddeg*TMath::ACos(fRotationMatrix[8]);
01130 if (TMath::Abs(fRotationMatrix[0])<1E-6 && TMath::Abs(fRotationMatrix[3])<1E-6) phi1=0.;
01131 else phi1 = raddeg*TMath::ATan2(fRotationMatrix[3],fRotationMatrix[0]);
01132 if (phi1<0) phi1+=360.;
01133 if (TMath::Abs(fRotationMatrix[1])<1E-6 && TMath::Abs(fRotationMatrix[4])<1E-6) phi2=0.;
01134 else phi2 = raddeg*TMath::ATan2(fRotationMatrix[4],fRotationMatrix[1]);
01135 if (phi2<0) phi2+=360.;
01136 if (TMath::Abs(fRotationMatrix[2])<1E-6 && TMath::Abs(fRotationMatrix[5])<1E-6) phi3=0.;
01137 else phi3 = raddeg*TMath::ATan2(fRotationMatrix[5],fRotationMatrix[2]);
01138 if (phi3<0) phi3+=360.;
01139 }
01140
01141
01142 void TGeoRotation::GetAngles(Double_t &phi, Double_t &theta, Double_t &psi) const
01143 {
01144
01145 const Double_t *m = fRotationMatrix;
01146
01147 if (TMath::Abs(1.-TMath::Abs(m[8]))<1.e-9) {
01148 theta = TMath::ACos(m[8])*TMath::RadToDeg();
01149 phi = TMath::ATan2(-m[8]*m[1],m[0])*TMath::RadToDeg();
01150 psi = 0.;
01151 return;
01152 }
01153
01154 phi = TMath::ATan2(m[2],-m[5]);
01155 Double_t sphi = TMath::Sin(phi);
01156 if (TMath::Abs(sphi)<1.e-9) theta = -TMath::ASin(m[5]/TMath::Cos(phi))*TMath::RadToDeg();
01157 else theta = TMath::ASin(m[2]/sphi)*TMath::RadToDeg();
01158 phi *= TMath::RadToDeg();
01159 psi = TMath::ATan2(m[6],m[7])*TMath::RadToDeg();
01160 }
01161
01162
01163 Double_t TGeoRotation::Determinant() const
01164 {
01165
01166 Double_t
01167 det = fRotationMatrix[0]*fRotationMatrix[4]*fRotationMatrix[8] +
01168 fRotationMatrix[3]*fRotationMatrix[7]*fRotationMatrix[2] +
01169 fRotationMatrix[6]*fRotationMatrix[1]*fRotationMatrix[5] -
01170 fRotationMatrix[2]*fRotationMatrix[4]*fRotationMatrix[6] -
01171 fRotationMatrix[5]*fRotationMatrix[7]*fRotationMatrix[0] -
01172 fRotationMatrix[8]*fRotationMatrix[1]*fRotationMatrix[3];
01173 return det;
01174 }
01175
01176
01177 void TGeoRotation::CheckMatrix()
01178 {
01179
01180
01181 if (Determinant() < 0) SetBit(kGeoReflection);
01182 Double_t dd = fRotationMatrix[0] + fRotationMatrix[4] + fRotationMatrix[8] - 3.;
01183 if (TMath::Abs(dd) < 1.E-12) ResetBit(kGeoRotation);
01184 else SetBit(kGeoRotation);
01185 }
01186
01187
01188 void TGeoRotation::GetInverse(Double_t *invmat) const
01189 {
01190
01191 if (!invmat) {
01192 Error("GetInverse", "no place to store the inverse matrix");
01193 return;
01194 }
01195 for (Int_t i=0; i<3; i++) {
01196 for (Int_t j=0; j<3; j++) {
01197 invmat[3*i+j] = fRotationMatrix[3*j+i];
01198 }
01199 }
01200 }
01201
01202
01203 void TGeoRotation::MultiplyBy(TGeoRotation *rot, Bool_t after)
01204 {
01205
01206
01207
01208 const Double_t *matleft, *matright;
01209 SetBit(kGeoRotation);
01210 Double_t newmat[9] = {0};
01211 if (after) {
01212 matleft = &fRotationMatrix[0];
01213 matright = rot->GetRotationMatrix();
01214 } else {
01215 matleft = rot->GetRotationMatrix();
01216 matright = &fRotationMatrix[0];
01217 }
01218 for (Int_t i=0; i<3; i++) {
01219 for (Int_t j=0; j<3; j++) {
01220 for (Int_t k=0; k<3; k++) {
01221 newmat[3*i+j] += matleft[3*i+k] * matright[3*k+j];
01222 }
01223 }
01224 }
01225 memcpy(&fRotationMatrix[0], &newmat[0], kN9);
01226 }
01227
01228
01229 ClassImp(TGeoScale)
01230
01231
01232 TGeoScale::TGeoScale()
01233 {
01234
01235 SetBit(kGeoScale);
01236 for (Int_t i=0; i<3; i++) fScale[i] = 1.;
01237 }
01238
01239
01240 TGeoScale::TGeoScale(const TGeoScale &other)
01241 :TGeoMatrix(other)
01242 {
01243
01244 SetBit(kGeoScale);
01245 const Double_t *scl = other.GetScale();
01246 memcpy(fScale, scl, kN3);
01247 if (fScale[0]*fScale[1]*fScale[2]<0) SetBit(kGeoReflection);
01248 else SetBit(kGeoReflection, kFALSE);
01249 }
01250
01251
01252 TGeoScale::TGeoScale(Double_t sx, Double_t sy, Double_t sz)
01253 :TGeoMatrix("")
01254 {
01255
01256 SetBit(kGeoScale);
01257 SetScale(sx, sy, sz);
01258 }
01259
01260
01261 TGeoScale::TGeoScale(const char *name, Double_t sx, Double_t sy, Double_t sz)
01262 :TGeoMatrix(name)
01263 {
01264
01265 SetBit(kGeoScale);
01266 SetScale(sx, sy, sz);
01267 }
01268
01269
01270 TGeoScale::~TGeoScale()
01271 {
01272
01273 }
01274
01275
01276 TGeoMatrix& TGeoScale::Inverse() const
01277 {
01278
01279 static TGeoHMatrix h;
01280 h = *this;
01281 Double_t scale[3];
01282 scale[0] = 1./fScale[0];
01283 scale[1] = 1./fScale[1];
01284 scale[2] = 1./fScale[2];
01285 h.SetScale(scale);
01286 return h;
01287 }
01288
01289
01290 void TGeoScale::SetScale(Double_t sx, Double_t sy, Double_t sz)
01291 {
01292
01293 if (TMath::Abs(sx*sy*sz) < 1.E-10) {
01294 Error("SetScale", "Invalid scale %f, %f, %f for transformation %s",sx,sy,sx,GetName());
01295 return;
01296 }
01297 fScale[0] = sx;
01298 fScale[1] = sy;
01299 fScale[2] = sz;
01300 if (sx*sy*sz<0) SetBit(kGeoReflection);
01301 else SetBit(kGeoReflection, kFALSE);
01302 }
01303
01304
01305 void TGeoScale::LocalToMaster(const Double_t *local, Double_t *master) const
01306 {
01307
01308 master[0] = local[0]*fScale[0];
01309 master[1] = local[1]*fScale[1];
01310 master[2] = local[2]*fScale[2];
01311 }
01312
01313
01314 Double_t TGeoScale::LocalToMaster(Double_t dist, const Double_t *dir) const
01315 {
01316
01317
01318
01319 Double_t scale;
01320 if (!dir) {
01321 scale = TMath::Abs(fScale[0]);
01322 if (TMath::Abs(fScale[1])<scale) scale = TMath::Abs(fScale[1]);
01323 if (TMath::Abs(fScale[2])<scale) scale = TMath::Abs(fScale[2]);
01324 } else {
01325 scale = fScale[0]*fScale[0]*dir[0]*dir[0] +
01326 fScale[1]*fScale[1]*dir[1]*dir[1] +
01327 fScale[2]*fScale[2]*dir[2]*dir[2];
01328 scale = TMath::Sqrt(scale);
01329 }
01330 return scale*dist;
01331 }
01332
01333
01334 TGeoMatrix *TGeoScale::MakeClone() const
01335 {
01336
01337 TGeoMatrix *matrix = new TGeoScale(*this);
01338 return matrix;
01339 }
01340
01341
01342 void TGeoScale::MasterToLocal(const Double_t *master, Double_t *local) const
01343 {
01344
01345 local[0] = master[0]/fScale[0];
01346 local[1] = master[1]/fScale[1];
01347 local[2] = master[2]/fScale[2];
01348 }
01349
01350
01351 Double_t TGeoScale::MasterToLocal(Double_t dist, const Double_t *dir) const
01352 {
01353
01354
01355
01356 Double_t scale;
01357 if (!dir) {
01358 scale = TMath::Abs(fScale[0]);
01359 if (TMath::Abs(fScale[1])>scale) scale = TMath::Abs(fScale[1]);
01360 if (TMath::Abs(fScale[2])>scale) scale = TMath::Abs(fScale[2]);
01361 scale = 1./scale;
01362 } else {
01363 scale = (dir[0]*dir[0])/(fScale[0]*fScale[0]) +
01364 (dir[1]*dir[1])/(fScale[1]*fScale[1]) +
01365 (dir[2]*dir[2])/(fScale[2]*fScale[2]);
01366 scale = TMath::Sqrt(scale);
01367 }
01368 return scale*dist;
01369 }
01370
01371
01372
01373 ClassImp(TGeoCombiTrans)
01374
01375
01376 TGeoCombiTrans::TGeoCombiTrans()
01377 {
01378
01379 for (Int_t i=0; i<3; i++) fTranslation[i] = 0.0;
01380 fRotation = 0;
01381 }
01382
01383
01384 TGeoCombiTrans::TGeoCombiTrans(const TGeoCombiTrans &other)
01385 :TGeoMatrix(other)
01386 {
01387
01388 Int_t i;
01389 if (other.IsTranslation()) {
01390 const Double_t *trans = other.GetTranslation();
01391 memcpy(fTranslation, trans, kN3);
01392 } else {
01393 for (i=0; i<3; i++) fTranslation[i] = 0.0;
01394 }
01395 if (other.IsRotation()) {
01396 const TGeoRotation rot = *other.GetRotation();
01397 fRotation = new TGeoRotation(rot);
01398 SetBit(kGeoMatrixOwned);
01399 }
01400 else fRotation = 0;
01401 }
01402
01403
01404 TGeoCombiTrans::TGeoCombiTrans(const TGeoMatrix &other)
01405 :TGeoMatrix(other)
01406 {
01407
01408 Int_t i;
01409 if (other.IsTranslation()) {
01410 SetBit(kGeoTranslation);
01411 memcpy(fTranslation,other.GetTranslation(),kN3);
01412 } else {
01413 for (i=0; i<3; i++) fTranslation[i] = 0.0;
01414 }
01415 if (other.IsRotation()) {
01416 SetBit(kGeoRotation);
01417 SetBit(kGeoMatrixOwned);
01418 fRotation = new TGeoRotation(other);
01419 }
01420 else fRotation = 0;
01421 }
01422
01423
01424 TGeoCombiTrans::TGeoCombiTrans(const TGeoTranslation &tr, const TGeoRotation &rot)
01425 {
01426
01427 if (tr.IsTranslation()) {
01428 SetBit(kGeoTranslation);
01429 const Double_t *trans = tr.GetTranslation();
01430 memcpy(fTranslation, trans, kN3);
01431 } else {
01432 for (Int_t i=0; i<3; i++) fTranslation[i] = 0.0;
01433 }
01434 if (rot.IsRotation()) {
01435 SetBit(kGeoRotation);
01436 SetBit(kGeoMatrixOwned);
01437 fRotation = new TGeoRotation(rot);
01438 SetBit(kGeoReflection, rot.TestBit(kGeoReflection));
01439 }
01440 else fRotation = 0;
01441 }
01442
01443
01444 TGeoCombiTrans::TGeoCombiTrans(const char *name)
01445 :TGeoMatrix(name)
01446 {
01447
01448 for (Int_t i=0; i<3; i++) fTranslation[i] = 0.0;
01449 fRotation = 0;
01450 }
01451
01452
01453 TGeoCombiTrans::TGeoCombiTrans(Double_t dx, Double_t dy, Double_t dz, TGeoRotation *rot)
01454 :TGeoMatrix("")
01455 {
01456
01457 SetTranslation(dx, dy, dz);
01458 fRotation = 0;
01459 SetRotation(rot);
01460 }
01461
01462
01463 TGeoCombiTrans::TGeoCombiTrans(const char *name, Double_t dx, Double_t dy, Double_t dz, TGeoRotation *rot)
01464 :TGeoMatrix(name)
01465 {
01466
01467 SetTranslation(dx, dy, dz);
01468 fRotation = 0;
01469 SetRotation(rot);
01470 }
01471
01472
01473 TGeoCombiTrans &TGeoCombiTrans::operator=(const TGeoMatrix &matrix)
01474 {
01475
01476 if (&matrix == this) return *this;
01477 Clear();
01478 TGeoMatrix::operator=(matrix);
01479
01480 if (matrix.IsTranslation()) {
01481 SetBit(kGeoTranslation);
01482 memcpy(fTranslation,matrix.GetTranslation(),kN3);
01483 }
01484 if (matrix.IsRotation()) {
01485 SetBit(kGeoRotation);
01486 if (!fRotation) {
01487 fRotation = new TGeoRotation();
01488 SetBit(kGeoMatrixOwned);
01489 } else {
01490 if (!TestBit(kGeoMatrixOwned)) {
01491 fRotation = new TGeoRotation();
01492 SetBit(kGeoMatrixOwned);
01493 }
01494 }
01495 fRotation->SetMatrix(matrix.GetRotationMatrix());
01496 fRotation->SetBit(kGeoReflection, matrix.TestBit(kGeoReflection));
01497 fRotation->SetBit(kGeoRotation);
01498 } else {
01499 if (fRotation && TestBit(kGeoMatrixOwned)) delete fRotation;
01500 ResetBit(kGeoMatrixOwned);
01501 fRotation = 0;
01502 }
01503 return *this;
01504 }
01505
01506
01507 TGeoCombiTrans::~TGeoCombiTrans()
01508 {
01509
01510 if (fRotation) {
01511 if(TestBit(TGeoMatrix::kGeoMatrixOwned) && !fRotation->IsRegistered()) delete fRotation;
01512 }
01513 }
01514
01515
01516 void TGeoCombiTrans::Clear(Option_t *)
01517 {
01518
01519 if (IsTranslation()) {
01520 ResetBit(kGeoTranslation);
01521 memset(fTranslation, 0, kN3);
01522 }
01523 if (fRotation) {
01524 if (TestBit(kGeoMatrixOwned)) delete fRotation;
01525 fRotation = 0;
01526 }
01527 ResetBit(kGeoRotation);
01528 ResetBit(kGeoReflection);
01529 ResetBit(kGeoMatrixOwned);
01530 }
01531
01532
01533 TGeoMatrix& TGeoCombiTrans::Inverse() const
01534 {
01535
01536 static TGeoHMatrix h;
01537 h = *this;
01538 Bool_t is_tr = IsTranslation();
01539 Bool_t is_rot = IsRotation();
01540 Double_t tr[3];
01541 Double_t newrot[9];
01542 const Double_t *rot = GetRotationMatrix();
01543 tr[0] = -fTranslation[0]*rot[0] - fTranslation[1]*rot[3] - fTranslation[2]*rot[6];
01544 tr[1] = -fTranslation[0]*rot[1] - fTranslation[1]*rot[4] - fTranslation[2]*rot[7];
01545 tr[2] = -fTranslation[0]*rot[2] - fTranslation[1]*rot[5] - fTranslation[2]*rot[8];
01546 h.SetTranslation(tr);
01547 newrot[0] = rot[0];
01548 newrot[1] = rot[3];
01549 newrot[2] = rot[6];
01550 newrot[3] = rot[1];
01551 newrot[4] = rot[4];
01552 newrot[5] = rot[7];
01553 newrot[6] = rot[2];
01554 newrot[7] = rot[5];
01555 newrot[8] = rot[8];
01556 h.SetRotation(newrot);
01557 h.SetBit(kGeoTranslation,is_tr);
01558 h.SetBit(kGeoRotation,is_rot);
01559 return h;
01560 }
01561
01562
01563 TGeoMatrix *TGeoCombiTrans::MakeClone() const
01564 {
01565
01566 TGeoMatrix *matrix = new TGeoCombiTrans(*this);
01567 return matrix;
01568 }
01569
01570
01571 void TGeoCombiTrans::RegisterYourself()
01572 {
01573
01574 TGeoMatrix::RegisterYourself();
01575 if (fRotation && fRotation->IsRotation()) fRotation->RegisterYourself();
01576 }
01577
01578
01579 void TGeoCombiTrans::RotateX(Double_t angle)
01580 {
01581
01582 if (!fRotation || !TestBit(kGeoMatrixOwned)) {
01583 if (fRotation) fRotation = new TGeoRotation(*fRotation);
01584 else fRotation = new TGeoRotation();
01585 SetBit(kGeoMatrixOwned);
01586 }
01587 SetBit(kGeoRotation);
01588 const Double_t *rot = fRotation->GetRotationMatrix();
01589 Double_t phi = angle*TMath::DegToRad();
01590 Double_t c = TMath::Cos(phi);
01591 Double_t s = TMath::Sin(phi);
01592 Double_t v[9];
01593 v[0] = rot[0];
01594 v[1] = rot[1];
01595 v[2] = rot[2];
01596 v[3] = c*rot[3]-s*rot[6];
01597 v[4] = c*rot[4]-s*rot[7];
01598 v[5] = c*rot[5]-s*rot[8];
01599 v[6] = s*rot[3]+c*rot[6];
01600 v[7] = s*rot[4]+c*rot[7];
01601 v[8] = s*rot[5]+c*rot[8];
01602 fRotation->SetMatrix(v);
01603 fRotation->SetBit(kGeoRotation);
01604 if (!IsTranslation()) return;
01605 v[0] = fTranslation[0];
01606 v[1] = c*fTranslation[1]-s*fTranslation[2];
01607 v[2] = s*fTranslation[1]+c*fTranslation[2];
01608 memcpy(fTranslation,v,kN3);
01609 }
01610
01611
01612 void TGeoCombiTrans::RotateY(Double_t angle)
01613 {
01614
01615 if (!fRotation || !TestBit(kGeoMatrixOwned)) {
01616 if (fRotation) fRotation = new TGeoRotation(*fRotation);
01617 else fRotation = new TGeoRotation();
01618 SetBit(kGeoMatrixOwned);
01619 }
01620 SetBit(kGeoRotation);
01621 const Double_t *rot = fRotation->GetRotationMatrix();
01622 Double_t phi = angle*TMath::DegToRad();
01623 Double_t c = TMath::Cos(phi);
01624 Double_t s = TMath::Sin(phi);
01625 Double_t v[9];
01626 v[0] = c*rot[0]+s*rot[6];
01627 v[1] = c*rot[1]+s*rot[7];
01628 v[2] = c*rot[2]+s*rot[8];
01629 v[3] = rot[3];
01630 v[4] = rot[4];
01631 v[5] = rot[5];
01632 v[6] = -s*rot[0]+c*rot[6];
01633 v[7] = -s*rot[1]+c*rot[7];
01634 v[8] = -s*rot[2]+c*rot[8];
01635 fRotation->SetMatrix(v);
01636 fRotation->SetBit(kGeoRotation);
01637 if (!IsTranslation()) return;
01638 v[0] = c*fTranslation[0]+s*fTranslation[2];
01639 v[1] = fTranslation[1];
01640 v[2] = -s*fTranslation[0]+c*fTranslation[2];
01641 memcpy(fTranslation,v,kN3);
01642 }
01643
01644
01645 void TGeoCombiTrans::RotateZ(Double_t angle)
01646 {
01647
01648 if (!fRotation || !TestBit(kGeoMatrixOwned)) {
01649 if (fRotation) fRotation = new TGeoRotation(*fRotation);
01650 else fRotation = new TGeoRotation();
01651 SetBit(kGeoMatrixOwned);
01652 }
01653 SetBit(kGeoRotation);
01654 const Double_t *rot = fRotation->GetRotationMatrix();
01655 Double_t phi = angle*TMath::DegToRad();
01656 Double_t c = TMath::Cos(phi);
01657 Double_t s = TMath::Sin(phi);
01658 Double_t v[9];
01659 v[0] = c*rot[0]-s*rot[3];
01660 v[1] = c*rot[1]-s*rot[4];
01661 v[2] = c*rot[2]-s*rot[5];
01662 v[3] = s*rot[0]+c*rot[3];
01663 v[4] = s*rot[1]+c*rot[4];
01664 v[5] = s*rot[2]+c*rot[5];
01665 v[6] = rot[6];
01666 v[7] = rot[7];
01667 v[8] = rot[8];
01668 fRotation->SetMatrix(v);
01669 fRotation->SetBit(kGeoRotation);
01670 if (!IsTranslation()) return;
01671 v[0] = c*fTranslation[0]-s*fTranslation[1];
01672 v[1] = s*fTranslation[0]+c*fTranslation[1];
01673 v[2] = fTranslation[2];
01674 memcpy(fTranslation,v,kN3);
01675 }
01676
01677
01678 void TGeoCombiTrans::ReflectX(Bool_t leftside, Bool_t rotonly)
01679 {
01680
01681 if (leftside && !rotonly) fTranslation[0] = -fTranslation[0];
01682 if (!fRotation || !TestBit(kGeoMatrixOwned)) {
01683 if (fRotation) fRotation = new TGeoRotation(*fRotation);
01684 else fRotation = new TGeoRotation();
01685 SetBit(kGeoMatrixOwned);
01686 }
01687 SetBit(kGeoRotation);
01688 fRotation->ReflectX(leftside);
01689 SetBit(kGeoReflection, !IsReflection());
01690 }
01691
01692
01693 void TGeoCombiTrans::ReflectY(Bool_t leftside, Bool_t rotonly)
01694 {
01695
01696 if (leftside && !rotonly) fTranslation[1] = -fTranslation[1];
01697 if (!fRotation || !TestBit(kGeoMatrixOwned)) {
01698 if (fRotation) fRotation = new TGeoRotation(*fRotation);
01699 else fRotation = new TGeoRotation();
01700 SetBit(kGeoMatrixOwned);
01701 }
01702 SetBit(kGeoRotation);
01703 fRotation->ReflectY(leftside);
01704 SetBit(kGeoReflection, !IsReflection());
01705 }
01706
01707
01708 void TGeoCombiTrans::ReflectZ(Bool_t leftside, Bool_t rotonly)
01709 {
01710
01711 if (leftside && !rotonly) fTranslation[2] = -fTranslation[2];
01712 if (!fRotation || !TestBit(kGeoMatrixOwned)) {
01713 if (fRotation) fRotation = new TGeoRotation(*fRotation);
01714 else fRotation = new TGeoRotation();
01715 SetBit(kGeoMatrixOwned);
01716 }
01717 SetBit(kGeoRotation);
01718 fRotation->ReflectZ(leftside);
01719 SetBit(kGeoReflection, !IsReflection());
01720 }
01721
01722
01723 void TGeoCombiTrans::SavePrimitive(ostream &out, Option_t *option )
01724 {
01725
01726 if (TestBit(kGeoSavePrimitive)) return;
01727 out << " // Combi transformation: " << GetName() << endl;
01728 out << " dx = " << fTranslation[0] << ";" << endl;
01729 out << " dy = " << fTranslation[1] << ";" << endl;
01730 out << " dz = " << fTranslation[2] << ";" << endl;
01731 if (fRotation && fRotation->IsRotation()) {
01732 fRotation->SavePrimitive(out,option);
01733 out << " " << GetPointerName() << " = new TGeoCombiTrans(\"" << GetName() << "\", dx,dy,dz,";
01734 out << fRotation->GetPointerName() << ");" << endl;
01735 } else {
01736 out << " " << GetPointerName() << " = new TGeoCombiTrans(\"" << GetName() << "\");" << endl;
01737 out << " " << GetPointerName() << "->SetTranslation(dx,dy,dz);" << endl;
01738 }
01739 TObject::SetBit(kGeoSavePrimitive);
01740 }
01741
01742
01743 void TGeoCombiTrans::SetRotation(const TGeoRotation *rot)
01744 {
01745
01746 if (fRotation && TestBit(kGeoMatrixOwned)) delete fRotation;
01747 fRotation = 0;
01748 ResetBit(TGeoMatrix::kGeoMatrixOwned);
01749 ResetBit(kGeoRotation);
01750 ResetBit(kGeoReflection);
01751 if (!rot) return;
01752 if (!rot->IsRotation()) return;
01753
01754 SetBit(kGeoRotation);
01755 SetBit(kGeoReflection, rot->TestBit(kGeoReflection));
01756 TGeoRotation *rr = (TGeoRotation*)rot;
01757 fRotation = rr;
01758 }
01759
01760
01761 void TGeoCombiTrans::SetRotation(const TGeoRotation &rot)
01762 {
01763
01764 if (fRotation && TestBit(kGeoMatrixOwned)) delete fRotation;
01765 fRotation = 0;
01766 if (!rot.IsRotation()) {
01767 ResetBit(kGeoRotation);
01768 ResetBit(kGeoReflection);
01769 ResetBit(TGeoMatrix::kGeoMatrixOwned);
01770 return;
01771 }
01772
01773 SetBit(kGeoRotation);
01774 SetBit(kGeoReflection, rot.TestBit(kGeoReflection));
01775 fRotation = new TGeoRotation(rot);
01776 SetBit(kGeoMatrixOwned);
01777 }
01778
01779
01780 void TGeoCombiTrans::SetTranslation(const TGeoTranslation &tr)
01781 {
01782
01783 if (tr.IsTranslation()) {
01784 SetBit(kGeoTranslation);
01785 const Double_t *trans = tr.GetTranslation();
01786 memcpy(fTranslation, trans, kN3);
01787 } else {
01788 if (!IsTranslation()) return;
01789 memset(fTranslation, 0, kN3);
01790 ResetBit(kGeoTranslation);
01791 }
01792 }
01793
01794
01795 void TGeoCombiTrans::SetTranslation(Double_t dx, Double_t dy, Double_t dz)
01796 {
01797
01798 fTranslation[0] = dx;
01799 fTranslation[1] = dy;
01800 fTranslation[2] = dz;
01801 if (fTranslation[0] || fTranslation[1] || fTranslation[2]) SetBit(kGeoTranslation);
01802 else ResetBit(kGeoTranslation);
01803 }
01804
01805
01806 void TGeoCombiTrans::SetTranslation(Double_t *vect)
01807 {
01808
01809 fTranslation[0] = vect[0];
01810 fTranslation[1] = vect[1];
01811 fTranslation[2] = vect[2];
01812 if (fTranslation[0] || fTranslation[1] || fTranslation[2]) SetBit(kGeoTranslation);
01813 else ResetBit(kGeoTranslation);
01814 }
01815
01816
01817 const Double_t *TGeoCombiTrans::GetRotationMatrix() const
01818 {
01819
01820 if (!fRotation) return kIdentityMatrix;
01821 return fRotation->GetRotationMatrix();
01822 }
01823
01824
01825 ClassImp(TGeoGenTrans)
01826
01827
01828 TGeoGenTrans::TGeoGenTrans()
01829 {
01830
01831 SetBit(kGeoGenTrans);
01832 for (Int_t i=0; i<3; i++) fTranslation[i] = 0.0;
01833 for (Int_t j=0; j<3; j++) fScale[j] = 1.0;
01834 fRotation = 0;
01835 }
01836
01837
01838 TGeoGenTrans::TGeoGenTrans(const char *name)
01839 :TGeoCombiTrans(name)
01840 {
01841
01842 SetBit(kGeoGenTrans);
01843 for (Int_t i=0; i<3; i++) fTranslation[i] = 0.0;
01844 for (Int_t j=0; j<3; j++) fScale[j] = 1.0;
01845 fRotation = 0;
01846 }
01847
01848
01849 TGeoGenTrans::TGeoGenTrans(Double_t dx, Double_t dy, Double_t dz,
01850 Double_t sx, Double_t sy, Double_t sz, TGeoRotation *rot)
01851 :TGeoCombiTrans("")
01852 {
01853
01854 SetBit(kGeoGenTrans);
01855 SetTranslation(dx, dy, dz);
01856 SetScale(sx, sy, sz);
01857 SetRotation(rot);
01858 }
01859
01860
01861 TGeoGenTrans::TGeoGenTrans(const char *name, Double_t dx, Double_t dy, Double_t dz,
01862 Double_t sx, Double_t sy, Double_t sz, TGeoRotation *rot)
01863 :TGeoCombiTrans(name)
01864 {
01865
01866 SetBit(kGeoGenTrans);
01867 SetTranslation(dx, dy, dz);
01868 SetScale(sx, sy, sz);
01869 SetRotation(rot);
01870 }
01871
01872
01873 TGeoGenTrans::~TGeoGenTrans()
01874 {
01875
01876 }
01877
01878
01879 void TGeoGenTrans::Clear(Option_t *)
01880 {
01881
01882 memset(&fTranslation[0], 0, kN3);
01883 memset(&fScale[0], 0, kN3);
01884 if (fRotation) fRotation->Clear();
01885 }
01886
01887
01888 void TGeoGenTrans::SetScale(Double_t sx, Double_t sy, Double_t sz)
01889 {
01890
01891 fScale[0] = sx;
01892 fScale[1] = sy;
01893 fScale[2] = sz;
01894 if (!(Normalize())) {
01895 Error("ctor", "Invalid scale");
01896 return;
01897 }
01898 }
01899
01900
01901 TGeoMatrix& TGeoGenTrans::Inverse() const
01902 {
01903
01904 Error("Inverse", "not implemented");
01905 static TGeoHMatrix h;
01906 h = *this;
01907 return h;
01908 }
01909
01910
01911 Bool_t TGeoGenTrans::Normalize()
01912 {
01913
01914 Double_t normfactor = fScale[0]*fScale[1]*fScale[2];
01915 if (normfactor <= 1E-5) return kFALSE;
01916 for (Int_t i=0; i<3; i++)
01917 fScale[i] /= normfactor;
01918 return kTRUE;
01919 }
01920
01921
01922 ClassImp(TGeoIdentity)
01923
01924
01925 TGeoIdentity::TGeoIdentity()
01926 {
01927
01928 if (!gGeoIdentity) gGeoIdentity = this;
01929 RegisterYourself();
01930 }
01931
01932
01933 TGeoIdentity::TGeoIdentity(const char *name)
01934 :TGeoMatrix(name)
01935 {
01936
01937 if (!gGeoIdentity) gGeoIdentity = this;
01938 RegisterYourself();
01939 }
01940
01941
01942 TGeoMatrix &TGeoIdentity::Inverse() const
01943 {
01944
01945 return *gGeoIdentity;
01946 }
01947
01948
01949
01950
01951
01952
01953
01954
01955
01956
01957 ClassImp(TGeoHMatrix)
01958
01959
01960 TGeoHMatrix::TGeoHMatrix()
01961 {
01962
01963 memset(&fTranslation[0], 0, kN3);
01964 memcpy(fRotationMatrix,kIdentityMatrix,kN9);
01965 memcpy(fScale,kUnitScale,kN3);
01966 }
01967
01968
01969 TGeoHMatrix::TGeoHMatrix(const char* name)
01970 :TGeoMatrix(name)
01971 {
01972
01973 memset(&fTranslation[0], 0, kN3);
01974 memcpy(fRotationMatrix,kIdentityMatrix,kN9);
01975 memcpy(fScale,kUnitScale,kN3);
01976 }
01977
01978
01979 TGeoHMatrix::TGeoHMatrix(const TGeoMatrix &matrix)
01980 :TGeoMatrix(matrix)
01981 {
01982
01983 if (matrix.IsTranslation()) {
01984 SetBit(kGeoTranslation);
01985 SetTranslation(matrix.GetTranslation());
01986 } else {
01987 memset(&fTranslation[0], 0, kN3);
01988 }
01989 if (matrix.IsRotation()) {
01990 SetBit(kGeoRotation);
01991 memcpy(fRotationMatrix,matrix.GetRotationMatrix(),kN9);
01992 } else {
01993 memcpy(fRotationMatrix,kIdentityMatrix,kN9);
01994 }
01995 if (matrix.IsScale()) {
01996 SetBit(kGeoScale);
01997 memcpy(fScale,matrix.GetScale(),kN3);
01998 } else {
01999 memcpy(fScale,kUnitScale,kN3);
02000 }
02001 }
02002
02003
02004 TGeoHMatrix::~TGeoHMatrix()
02005 {
02006
02007 }
02008
02009
02010 TGeoHMatrix &TGeoHMatrix::operator=(const TGeoMatrix *matrix)
02011 {
02012
02013 if (matrix == this) return *this;
02014 Clear();
02015 if (matrix == 0) return *this;
02016 TGeoMatrix::operator=(*matrix);
02017 if (matrix->IsIdentity()) return *this;
02018 if (matrix->IsTranslation()) {
02019 SetBit(kGeoTranslation);
02020 memcpy(fTranslation,matrix->GetTranslation(),kN3);
02021 }
02022 if (matrix->IsRotation()) {
02023 SetBit(kGeoRotation);
02024 memcpy(fRotationMatrix,matrix->GetRotationMatrix(),kN9);
02025 }
02026 if (matrix->IsScale()) {
02027 SetBit(kGeoScale);
02028 memcpy(fScale,matrix->GetScale(),kN3);
02029 }
02030 return *this;
02031 }
02032
02033
02034 TGeoHMatrix &TGeoHMatrix::operator=(const TGeoMatrix &matrix)
02035 {
02036
02037 if (&matrix == this) return *this;
02038 Clear();
02039 TGeoMatrix::operator=(matrix);
02040 if (matrix.IsIdentity()) return *this;
02041 if (matrix.IsTranslation()) {
02042 SetBit(kGeoTranslation);
02043 memcpy(fTranslation,matrix.GetTranslation(),kN3);
02044 } else {
02045 memcpy(fTranslation,kNullVector,kN3);
02046 }
02047 if (matrix.IsRotation()) {
02048 SetBit(kGeoRotation);
02049 memcpy(fRotationMatrix,matrix.GetRotationMatrix(),kN9);
02050 } else {
02051 memcpy(fRotationMatrix,kIdentityMatrix,kN9);
02052 }
02053 if (matrix.IsScale()) {
02054 SetBit(kGeoScale);
02055 memcpy(fScale,matrix.GetScale(),kN3);
02056 } else {
02057 memcpy(fScale,kUnitScale,kN3);
02058 }
02059 return *this;
02060 }
02061
02062
02063 void TGeoHMatrix::CopyFrom(const TGeoMatrix *other)
02064 {
02065
02066 SetBit(kGeoTranslation, other->IsTranslation());
02067 SetBit(kGeoRotation, other->IsRotation());
02068 SetBit(kGeoReflection, other->IsReflection());
02069 memcpy(fTranslation,other->GetTranslation(),kN3);
02070 memcpy(fRotationMatrix,other->GetRotationMatrix(),kN9);
02071 }
02072
02073
02074 void TGeoHMatrix::Clear(Option_t *)
02075 {
02076
02077 SetBit(kGeoReflection, kFALSE);
02078 if (IsIdentity()) return;
02079 if (IsTranslation()) {
02080 ResetBit(kGeoTranslation);
02081 memcpy(fTranslation,kNullVector,kN3);
02082 }
02083 if (IsRotation()) {
02084 ResetBit(kGeoRotation);
02085 memcpy(fRotationMatrix,kIdentityMatrix,kN9);
02086 }
02087 if (IsScale()) {
02088 ResetBit(kGeoScale);
02089 memcpy(fScale,kUnitScale,kN3);
02090 }
02091 }
02092
02093
02094 TGeoMatrix *TGeoHMatrix::MakeClone() const
02095 {
02096
02097 TGeoMatrix *matrix = new TGeoHMatrix(*this);
02098 return matrix;
02099 }
02100
02101
02102 TGeoMatrix& TGeoHMatrix::Inverse() const
02103 {
02104
02105 static TGeoHMatrix h;
02106 h = *this;
02107 if (IsTranslation()) {
02108 Double_t tr[3];
02109 tr[0] = -fTranslation[0]*fRotationMatrix[0] - fTranslation[1]*fRotationMatrix[3] - fTranslation[2]*fRotationMatrix[6];
02110 tr[1] = -fTranslation[0]*fRotationMatrix[1] - fTranslation[1]*fRotationMatrix[4] - fTranslation[2]*fRotationMatrix[7];
02111 tr[2] = -fTranslation[0]*fRotationMatrix[2] - fTranslation[1]*fRotationMatrix[5] - fTranslation[2]*fRotationMatrix[8];
02112 h.SetTranslation(tr);
02113 }
02114 if (IsRotation()) {
02115 Double_t newrot[9];
02116 newrot[0] = fRotationMatrix[0];
02117 newrot[1] = fRotationMatrix[3];
02118 newrot[2] = fRotationMatrix[6];
02119 newrot[3] = fRotationMatrix[1];
02120 newrot[4] = fRotationMatrix[4];
02121 newrot[5] = fRotationMatrix[7];
02122 newrot[6] = fRotationMatrix[2];
02123 newrot[7] = fRotationMatrix[5];
02124 newrot[8] = fRotationMatrix[8];
02125 h.SetRotation(newrot);
02126 }
02127 if (IsScale()) {
02128 Double_t sc[3];
02129 sc[0] = 1./fScale[0];
02130 sc[1] = 1./fScale[1];
02131 sc[2] = 1./fScale[2];
02132 h.SetScale(sc);
02133 }
02134 return h;
02135 }
02136
02137
02138 Double_t TGeoHMatrix::Determinant() const
02139 {
02140
02141 Double_t
02142 det = fRotationMatrix[0]*fRotationMatrix[4]*fRotationMatrix[8] +
02143 fRotationMatrix[3]*fRotationMatrix[7]*fRotationMatrix[2] +
02144 fRotationMatrix[6]*fRotationMatrix[1]*fRotationMatrix[5] -
02145 fRotationMatrix[2]*fRotationMatrix[4]*fRotationMatrix[6] -
02146 fRotationMatrix[5]*fRotationMatrix[7]*fRotationMatrix[0] -
02147 fRotationMatrix[8]*fRotationMatrix[1]*fRotationMatrix[3];
02148 return det;
02149 }
02150
02151
02152 void TGeoHMatrix::Multiply(const TGeoMatrix *right)
02153 {
02154
02155
02156 if (right->IsIdentity()) return;
02157 const Double_t *r_tra = right->GetTranslation();
02158 const Double_t *r_rot = right->GetRotationMatrix();
02159 const Double_t *r_scl = right->GetScale();
02160 if (IsIdentity()) {
02161 if (right->IsRotation()) {
02162 SetBit(kGeoRotation);
02163 memcpy(fRotationMatrix,r_rot,kN9);
02164 if (right->IsReflection()) SetBit(kGeoReflection, !TestBit(kGeoReflection));
02165 }
02166 if (right->IsScale()) {
02167 SetBit(kGeoScale);
02168 memcpy(fScale,r_scl,kN3);
02169 }
02170 if (right->IsTranslation()) {
02171 SetBit(kGeoTranslation);
02172 memcpy(fTranslation,r_tra,kN3);
02173 }
02174 return;
02175 }
02176 Int_t i, j;
02177 Double_t new_rot[9];
02178
02179 if (right->IsRotation()) {
02180 SetBit(kGeoRotation);
02181 if (right->IsReflection()) SetBit(kGeoReflection, !TestBit(kGeoReflection));
02182 }
02183 if (right->IsScale()) SetBit(kGeoScale);
02184 if (right->IsTranslation()) SetBit(kGeoTranslation);
02185
02186
02187 if (IsTranslation()) {
02188 for (i=0; i<3; i++) {
02189 fTranslation[i] += fRotationMatrix[3*i]*r_tra[0]
02190 + fRotationMatrix[3*i+1]*r_tra[1]
02191 + fRotationMatrix[3*i+2]*r_tra[2];
02192 }
02193 }
02194 if (IsRotation()) {
02195
02196 for (i=0; i<3; i++) {
02197 for (j=0; j<3; j++) {
02198 new_rot[3*i+j] = fRotationMatrix[3*i]*r_rot[j] +
02199 fRotationMatrix[3*i+1]*r_rot[3+j] +
02200 fRotationMatrix[3*i+2]*r_rot[6+j];
02201 }
02202 }
02203 memcpy(fRotationMatrix,new_rot,kN9);
02204 }
02205
02206 if (IsScale()) {
02207 for (i=0; i<3; i++) fScale[i] *= r_scl[i];
02208 }
02209 }
02210
02211
02212 void TGeoHMatrix::MultiplyLeft(const TGeoMatrix *left)
02213 {
02214
02215
02216 if (left == gGeoIdentity) return;
02217 const Double_t *l_tra = left->GetTranslation();
02218 const Double_t *l_rot = left->GetRotationMatrix();
02219 const Double_t *l_scl = left->GetScale();
02220 if (IsIdentity()) {
02221 if (left->IsRotation()) {
02222 if (left->IsReflection()) SetBit(kGeoReflection, !TestBit(kGeoReflection));
02223 SetBit(kGeoRotation);
02224 memcpy(fRotationMatrix,l_rot,kN9);
02225 }
02226 if (left->IsScale()) {
02227 SetBit(kGeoScale);
02228 memcpy(fScale,l_scl,kN3);
02229 }
02230 if (left->IsTranslation()) {
02231 SetBit(kGeoTranslation);
02232 memcpy(fTranslation,l_tra,kN3);
02233 }
02234 return;
02235 }
02236 Int_t i, j;
02237 Double_t new_tra[3];
02238 Double_t new_rot[9];
02239
02240 if (left->IsRotation()) {
02241 SetBit(kGeoRotation);
02242 if (left->IsReflection()) SetBit(kGeoReflection, !TestBit(kGeoReflection));
02243 }
02244 if (left->IsScale()) SetBit(kGeoScale);
02245 if (left->IsTranslation()) SetBit(kGeoTranslation);
02246
02247
02248 if (IsTranslation()) {
02249 for (i=0; i<3; i++) {
02250 new_tra[i] = l_tra[i]
02251 + l_rot[3*i]* fTranslation[0]
02252 + l_rot[3*i+1]*fTranslation[1]
02253 + l_rot[3*i+2]*fTranslation[2];
02254 }
02255 memcpy(fTranslation,new_tra,kN3);
02256 }
02257 if (IsRotation()) {
02258
02259 for (i=0; i<3; i++) {
02260 for (j=0; j<3; j++) {
02261 new_rot[3*i+j] = l_rot[3*i]*fRotationMatrix[j] +
02262 l_rot[3*i+1]*fRotationMatrix[3+j] +
02263 l_rot[3*i+2]*fRotationMatrix[6+j];
02264 }
02265 }
02266 memcpy(fRotationMatrix,new_rot,kN9);
02267 }
02268
02269 if (IsScale()) {
02270 for (i=0; i<3; i++) fScale[i] *= l_scl[i];
02271 }
02272 }
02273
02274
02275 void TGeoHMatrix::RotateX(Double_t angle)
02276 {
02277
02278 SetBit(kGeoRotation);
02279 Double_t phi = angle*TMath::DegToRad();
02280 Double_t c = TMath::Cos(phi);
02281 Double_t s = TMath::Sin(phi);
02282 Double_t v[9];
02283 v[0] = fRotationMatrix[0];
02284 v[1] = fRotationMatrix[1];
02285 v[2] = fRotationMatrix[2];
02286 v[3] = c*fRotationMatrix[3]-s*fRotationMatrix[6];
02287 v[4] = c*fRotationMatrix[4]-s*fRotationMatrix[7];
02288 v[5] = c*fRotationMatrix[5]-s*fRotationMatrix[8];
02289 v[6] = s*fRotationMatrix[3]+c*fRotationMatrix[6];
02290 v[7] = s*fRotationMatrix[4]+c*fRotationMatrix[7];
02291 v[8] = s*fRotationMatrix[5]+c*fRotationMatrix[8];
02292 memcpy(fRotationMatrix, v, kN9);
02293
02294 v[0] = fTranslation[0];
02295 v[1] = c*fTranslation[1]-s*fTranslation[2];
02296 v[2] = s*fTranslation[1]+c*fTranslation[2];
02297 memcpy(fTranslation,v,kN3);
02298 }
02299
02300
02301 void TGeoHMatrix::RotateY(Double_t angle)
02302 {
02303
02304 SetBit(kGeoRotation);
02305 Double_t phi = angle*TMath::DegToRad();
02306 Double_t c = TMath::Cos(phi);
02307 Double_t s = TMath::Sin(phi);
02308 Double_t v[9];
02309 v[0] = c*fRotationMatrix[0]+s*fRotationMatrix[6];
02310 v[1] = c*fRotationMatrix[1]+s*fRotationMatrix[7];
02311 v[2] = c*fRotationMatrix[2]+s*fRotationMatrix[8];
02312 v[3] = fRotationMatrix[3];
02313 v[4] = fRotationMatrix[4];
02314 v[5] = fRotationMatrix[5];
02315 v[6] = -s*fRotationMatrix[0]+c*fRotationMatrix[6];
02316 v[7] = -s*fRotationMatrix[1]+c*fRotationMatrix[7];
02317 v[8] = -s*fRotationMatrix[2]+c*fRotationMatrix[8];
02318 memcpy(fRotationMatrix, v, kN9);
02319
02320 v[0] = c*fTranslation[0]+s*fTranslation[2];
02321 v[1] = fTranslation[1];
02322 v[2] = -s*fTranslation[0]+c*fTranslation[2];
02323 memcpy(fTranslation,v,kN3);
02324 }
02325
02326
02327 void TGeoHMatrix::RotateZ(Double_t angle)
02328 {
02329
02330 SetBit(kGeoRotation);
02331 Double_t phi = angle*TMath::DegToRad();
02332 Double_t c = TMath::Cos(phi);
02333 Double_t s = TMath::Sin(phi);
02334 Double_t v[9];
02335 v[0] = c*fRotationMatrix[0]-s*fRotationMatrix[3];
02336 v[1] = c*fRotationMatrix[1]-s*fRotationMatrix[4];
02337 v[2] = c*fRotationMatrix[2]-s*fRotationMatrix[5];
02338 v[3] = s*fRotationMatrix[0]+c*fRotationMatrix[3];
02339 v[4] = s*fRotationMatrix[1]+c*fRotationMatrix[4];
02340 v[5] = s*fRotationMatrix[2]+c*fRotationMatrix[5];
02341 v[6] = fRotationMatrix[6];
02342 v[7] = fRotationMatrix[7];
02343 v[8] = fRotationMatrix[8];
02344 memcpy(&fRotationMatrix[0],v,kN9);
02345
02346 v[0] = c*fTranslation[0]-s*fTranslation[1];
02347 v[1] = s*fTranslation[0]+c*fTranslation[1];
02348 v[2] = fTranslation[2];
02349 memcpy(fTranslation,v,kN3);
02350 }
02351
02352
02353 void TGeoHMatrix::ReflectX(Bool_t leftside, Bool_t rotonly)
02354 {
02355
02356 if (leftside && !rotonly) fTranslation[0] = -fTranslation[0];
02357 if (leftside) {
02358 fRotationMatrix[0]=-fRotationMatrix[0];
02359 fRotationMatrix[1]=-fRotationMatrix[1];
02360 fRotationMatrix[2]=-fRotationMatrix[2];
02361 } else {
02362 fRotationMatrix[0]=-fRotationMatrix[0];
02363 fRotationMatrix[3]=-fRotationMatrix[3];
02364 fRotationMatrix[6]=-fRotationMatrix[6];
02365 }
02366 SetBit(kGeoRotation);
02367 SetBit(kGeoReflection, !IsReflection());
02368 }
02369
02370
02371 void TGeoHMatrix::ReflectY(Bool_t leftside, Bool_t rotonly)
02372 {
02373
02374 if (leftside && !rotonly) fTranslation[1] = -fTranslation[1];
02375 if (leftside) {
02376 fRotationMatrix[3]=-fRotationMatrix[3];
02377 fRotationMatrix[4]=-fRotationMatrix[4];
02378 fRotationMatrix[5]=-fRotationMatrix[5];
02379 } else {
02380 fRotationMatrix[1]=-fRotationMatrix[1];
02381 fRotationMatrix[4]=-fRotationMatrix[4];
02382 fRotationMatrix[7]=-fRotationMatrix[7];
02383 }
02384 SetBit(kGeoRotation);
02385 SetBit(kGeoReflection, !IsReflection());
02386 }
02387
02388
02389 void TGeoHMatrix::ReflectZ(Bool_t leftside, Bool_t rotonly)
02390 {
02391
02392 if (leftside && !rotonly) fTranslation[2] = -fTranslation[2];
02393 if (leftside) {
02394 fRotationMatrix[6]=-fRotationMatrix[6];
02395 fRotationMatrix[7]=-fRotationMatrix[7];
02396 fRotationMatrix[8]=-fRotationMatrix[8];
02397 } else {
02398 fRotationMatrix[2]=-fRotationMatrix[2];
02399 fRotationMatrix[5]=-fRotationMatrix[5];
02400 fRotationMatrix[8]=-fRotationMatrix[8];
02401 }
02402 SetBit(kGeoRotation);
02403 SetBit(kGeoReflection, !IsReflection());
02404 }
02405
02406
02407 void TGeoHMatrix::SavePrimitive(ostream &out, Option_t * )
02408 {
02409
02410 if (TestBit(kGeoSavePrimitive)) return;
02411 const Double_t *tr = fTranslation;
02412 const Double_t *rot = fRotationMatrix;
02413 out << " // HMatrix: " << GetName() << endl;
02414 out << " tr[0] = " << tr[0] << "; " << "tr[1] = " << tr[1] << "; " << "tr[2] = " << tr[2] << ";" << endl;
02415 out << " rot[0] =" << rot[0] << "; " << "rot[1] = " << rot[1] << "; " << "rot[2] = " << rot[2] << ";" << endl;
02416 out << " rot[3] =" << rot[3] << "; " << "rot[4] = " << rot[4] << "; " << "rot[5] = " << rot[5] << ";" << endl;
02417 out << " rot[6] =" << rot[6] << "; " << "rot[7] = " << rot[7] << "; " << "rot[8] = " << rot[8] << ";" << endl;
02418 char *name = GetPointerName();
02419 out << " TGeoHMatrix *" << name << " = new TGeoHMatrix(\"" << GetName() << "\");" << endl;
02420 out << " " << name << "->SetTranslation(tr);" << endl;
02421 out << " " << name << "->SetRotation(rot);" << endl;
02422 if (IsTranslation()) out << " " << name << "->SetBit(TGeoMatrix::kGeoTranslation);" << endl;
02423 if (IsRotation()) out << " " << name << "->SetBit(TGeoMatrix::kGeoRotation);" << endl;
02424 if (IsReflection()) out << " " << name << "->SetBit(TGeoMatrix::kGeoReflection);" << endl;
02425 TObject::SetBit(kGeoSavePrimitive);
02426 }