00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include "TVirtualPad.h"
00014 #include "BesVisLib/BesTView.h"
00015 #include "TAxis3D.h"
00016 #include "TPolyLine3D.h"
00017 #include "TVirtualX.h"
00018 #include "TROOT.h"
00019 #include "TClass.h"
00020 #include "TList.h"
00021
00022 #include "TPluginManager.h"
00023 #include "TMath.h"
00024
00025
00026 #include "TVirtualViewer3D.h"
00027
00028 ClassImp(BesTView)
00029
00030
00031
00032 const Int_t kCARTESIAN = 1;
00033 const Int_t kPOLAR = 2;
00034 const Double_t kRad = 3.14159265358979323846/180.0;
00035
00036
00037
00038
00039 BesTView::BesTView():TView()
00040 {
00041
00042
00043 fSystem = 1;
00044 fOutline = 0;
00045 fDefaultOutline = kFALSE;
00046 fAutoRange = kFALSE;
00047 fChanged = kFALSE;
00048 SetBit(kMustCleanup);
00049 for (Int_t i=0;i<3;i++) {
00050 fX1[i] = fX2[i] = fY1[i] = fY2[i] = fZ1[i] = fZ2[i] = 0;
00051 }
00052 }
00053
00054
00055 BesTView::BesTView(const BesTView& tv)
00056 :TView(tv),
00057 fLatitude(tv.fLatitude),
00058 fLongitude(tv.fLongitude),
00059 fPsi(tv.fPsi),
00060 fDview(tv.fDview),
00061 fDproj(tv.fDproj),
00062 fUpix(tv.fUpix),
00063 fVpix(tv.fVpix),
00064 fSystem(tv.fSystem),
00065 fOutline(tv.fOutline),
00066 fDefaultOutline(tv.fDefaultOutline),
00067 fAutoRange(tv.fAutoRange),
00068 fChanged(tv.fChanged)
00069 {
00070
00071
00072 for (Int_t i=0; i<16; i++) {
00073 fTN[i]=tv.fTN[i];
00074 fTB[i]=tv.fTB[i];
00075 fTnorm[i]=tv.fTnorm[i];
00076 fTback[i]=tv.fTback[i];
00077 }
00078 for(Int_t i=0; i<3; i++) {
00079 fRmax[i]=tv.fRmax[i];
00080 fRmin[i]=tv.fRmin[i];
00081 fX1[i]=tv.fX1[i];
00082 fX2[i]=tv.fX2[i];
00083 fY1[i]=tv.fY1[i];
00084 fY2[i]=tv.fY2[i];
00085 fZ1[i]=tv.fZ1[i];
00086 fZ2[i]=tv.fZ2[i];
00087 }
00088 for(Int_t i=0; i<4; i++)
00089 fUVcoord[i]=tv.fUVcoord[i];
00090 }
00091
00092
00093 BesTView& BesTView::operator=(const BesTView& tv)
00094 {
00095
00096
00097 if (this!=&tv) {
00098 TView::operator=(tv);
00099 fLatitude=tv.fLatitude;
00100 fLongitude=tv.fLongitude;
00101 fPsi=tv.fPsi;
00102 fDview=tv.fDview;
00103 fDproj=tv.fDproj;
00104 fUpix=tv.fUpix;
00105 fVpix=tv.fVpix;
00106 fSystem=tv.fSystem;
00107 fOutline=tv.fOutline;
00108 fDefaultOutline=tv.fDefaultOutline;
00109 fAutoRange=tv.fAutoRange;
00110 fChanged=tv.fChanged;
00111 for(Int_t i=0; i<16; i++) {
00112 fTN[i]=tv.fTN[i];
00113 fTB[i]=tv.fTB[i];
00114 fTnorm[i]=tv.fTnorm[i];
00115 fTback[i]=tv.fTback[i];
00116 }
00117 for(Int_t i=0; i<3; i++) {
00118 fRmax[i]=tv.fRmax[i];
00119 fRmin[i]=tv.fRmin[i];
00120 fX1[i]=tv.fX1[i];
00121 fX2[i]=tv.fX2[i];
00122 fY1[i]=tv.fY1[i];
00123 fY2[i]=tv.fY2[i];
00124 fZ1[i]=tv.fZ1[i];
00125 fZ2[i]=tv.fZ2[i];
00126 }
00127 for(Int_t i=0; i<4; i++)
00128 fUVcoord[i]=tv.fUVcoord[i];
00129 }
00130 return *this;
00131 }
00132
00133
00134 BesTView::~BesTView()
00135 {
00136
00137
00138
00139 if (fOutline) fOutline->Delete();
00140 delete fOutline;
00141 fOutline = 0;
00142 }
00143
00144
00145 BesTView::BesTView(Int_t system)
00146 {
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164 Int_t irep;
00165
00166
00167 if (!gROOT->GetListOfSpecials()->FindObject("R__TVirtualUtil3D")) {
00168 TPluginHandler *h;
00169 if ((h = gROOT->GetPluginManager()->FindHandler("TVirtualUtil3D"))) {
00170 if (h->LoadPlugin() == -1)
00171 return;
00172 h->ExecPlugin(0);
00173 }
00174 }
00175
00176 SetBit(kMustCleanup);
00177
00178 fSystem = system;
00179 fOutline = 0;
00180 fDefaultOutline = kFALSE;
00181 fAutoRange = kFALSE;
00182 fChanged = kFALSE;
00183
00184 if (system == kCARTESIAN || system == kPOLAR || system == 11) fPsi = 0;
00185 else fPsi = 90;
00186
00187
00188 if (gPad) {
00189 gPad->Range(-1, -1, 1, 1);
00190
00191 Int_t i;
00192 for (i = 0; i < 3; fRmin[i] = 0, fRmax[i] = 1, i++);
00193 for (i=0;i<3;i++) {
00194 fX1[i] = fX2[i] = fY1[i] = fY2[i] = fZ1[i] = fZ2[i] = 0;
00195 }
00196
00197 fLongitude = -90 - gPad->GetPhi();
00198 fLatitude = 90 - gPad->GetTheta();
00199 ResetView(fLongitude, fLatitude, fPsi, irep);
00200
00201 gPad->SetView(this);
00202 }
00203 if (system == 11) SetPerspective();
00204 }
00205
00206
00207
00208 BesTView::BesTView(const Float_t *rmin, const Float_t *rmax, Int_t system)
00209 {
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228 Int_t irep;
00229
00230
00231 if (!gROOT->GetListOfSpecials()->FindObject("R__TVirtualUtil3D")) {
00232 TPluginHandler *h;
00233 if ((h = gROOT->GetPluginManager()->FindHandler("TVirtualUtil3D"))) {
00234 if (h->LoadPlugin() == -1)
00235 return;
00236 h->ExecPlugin(0);
00237 }
00238 }
00239
00240 SetBit(kMustCleanup);
00241
00242 fSystem = system;
00243 fOutline = 0;
00244 fDefaultOutline = kFALSE;
00245 fChanged = kFALSE;
00246
00247 if (system == kCARTESIAN || system == kPOLAR || system == 11) fPsi = 0;
00248 else fPsi = 90;
00249
00250
00251 gPad->Range(-1, -1, 1, 1);
00252 fAutoRange = kFALSE;
00253
00254 Int_t i;
00255 for (i = 0; i < 3; fRmin[i] = rmin[i], fRmax[i] = rmax[i], i++);
00256 for (i=0;i<3;i++) {
00257 fX1[i] = fX2[i] = fY1[i] = fY2[i] = fZ1[i] = fZ2[i] = 0;
00258 }
00259
00260 fLongitude = -90 - gPad->GetPhi();
00261 fLatitude = 90 - gPad->GetTheta();
00262 ResetView(fLongitude, fLatitude, fPsi, irep);
00263
00264 if (gPad) gPad->SetView(this);
00265 if (system == 11) SetPerspective();
00266 }
00267
00268
00269
00270 BesTView::BesTView(const Double_t *rmin, const Double_t *rmax, Int_t system)
00271 {
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290 Int_t irep;
00291
00292
00293 if (!gROOT->GetListOfSpecials()->FindObject("R__TVirtualUtil3D")) {
00294 TPluginHandler *h;
00295 if ((h = gROOT->GetPluginManager()->FindHandler("TVirtualUtil3D"))) {
00296 if (h->LoadPlugin() == -1)
00297 return;
00298 h->ExecPlugin(0);
00299 }
00300 }
00301
00302 SetBit(kMustCleanup);
00303
00304 fSystem = system;
00305 fOutline = 0;
00306 fDefaultOutline = kFALSE;
00307 fChanged = kFALSE;
00308
00309 if (system == kCARTESIAN || system == kPOLAR || system == 11) fPsi = 0;
00310 else fPsi = 90;
00311
00312
00313 gPad->Range(-1, -1, 1, 1);
00314 fAutoRange = kFALSE;
00315
00316 Int_t i;
00317 for (i = 0; i < 3; fRmin[i] = rmin[i], fRmax[i] = rmax[i], i++);
00318 for (i=0;i<3;i++) {
00319 fX1[i] = fX2[i] = fY1[i] = fY2[i] = fZ1[i] = fZ2[i] = 0;
00320 }
00321
00322 fLongitude = -90 - gPad->GetPhi();
00323 fLatitude = 90 - gPad->GetTheta();
00324 ResetView(fLongitude, fLatitude, fPsi, irep);
00325
00326 if (gPad) gPad->SetView(this);
00327 if (system == 11) SetPerspective();
00328 }
00329
00330
00331
00332 void BesTView::AxisVertex(Double_t ang, Double_t *av, Int_t &ix1, Int_t &ix2, Int_t &iy1, Int_t &iy2, Int_t &iz1, Int_t &iz2)
00333 {
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359 Double_t cosa, sina;
00360 Int_t i, k;
00361 Double_t p[8] ;
00362 Int_t i1, i2, i3, i4, ix, iy;
00363 ix = 0;
00364
00365
00366 av -= 4;
00367
00368 sina = TMath::Sin(ang*kRad);
00369 cosa = TMath::Cos(ang*kRad);
00370 p[0] = fRmin[0];
00371 p[1] = fRmin[1];
00372 p[2] = fRmax[0];
00373 p[3] = fRmin[1];
00374 p[4] = fRmax[0];
00375 p[5] = fRmax[1];
00376 p[6] = fRmin[0];
00377 p[7] = fRmax[1];
00378
00379 i1 = 1;
00380 if (fTN[0] < 0) i1 = 2;
00381 if (fTN[0]*cosa + fTN[1]*sina < 0) i1 = 5 - i1;
00382
00383
00384 i2 = i1 % 4 + 1;
00385 i3 = i2 % 4 + 1;
00386 i4 = i3 % 4 + 1;
00387
00388
00389
00390 av[4] = p[(i1 << 1) - 2];
00391 av[5] = p[(i1 << 1) - 1];
00392 av[7] = p[(i2 << 1) - 2];
00393 av[8] = p[(i2 << 1) - 1];
00394 av[10] = p[(i3 << 1) - 2];
00395 av[11] = p[(i3 << 1) - 1];
00396 av[13] = p[(i4 << 1) - 2];
00397 av[14] = p[(i4 << 1) - 1];
00398 for (i = 1; i <= 4; ++i) {
00399 av[i*3 + 3] = fRmin[2];
00400 av[i*3 + 13] = av[i*3 + 1];
00401 av[i*3 + 14] = av[i*3 + 2];
00402 av[i*3 + 15] = fRmax[2];
00403 }
00404
00405
00406
00407 if (av[4] == av[7]) ix = 2;
00408 if (av[5] == av[8]) ix = 1;
00409 iy = 3 - ix;
00410
00411 ix1 = ix;
00412 if (av[ix*3 + 1] > av[(ix + 1)*3 + 1]) ix1 = ix + 1;
00413 ix2 = (ix << 1) - ix1 + 1;
00414
00415 iy1 = iy;
00416 if (av[iy*3 + 2] > av[(iy + 1)*3 + 2]) iy1 = iy + 1;
00417 iy2 = (iy << 1) - iy1 + 1;
00418
00419 iz1 = 1;
00420 iz2 = 5;
00421
00422 if (fTN[10] >= 0) return;
00423 k = (ix1 - 1)*3 + ix2;
00424 if (k%2) return;
00425 if (k == 2) {
00426 ix1 = 4;
00427 ix2 = 3;
00428 }
00429 if (k == 4) {
00430 ix1 = 3;
00431 ix2 = 4;
00432 }
00433 if (k == 6) {
00434 ix1 = 1;
00435 ix2 = 4;
00436 }
00437 if (k == 8) {
00438 ix1 = 4;
00439 ix2 = 1;
00440 }
00441
00442 k = (iy1 - 1)*3 + iy2;
00443 if (k%2) return;
00444 if (k == 2) {
00445 iy1 = 4;
00446 iy2 = 3;
00447 return;
00448 }
00449 if (k == 4) {
00450 iy1 = 3;
00451 iy2 = 4;
00452 return;
00453 }
00454 if (k == 6) {
00455 iy1 = 1;
00456 iy2 = 4;
00457 return;
00458 }
00459 if (k == 8) {
00460 iy1 = 4;
00461 iy2 = 1;
00462 }
00463 }
00464
00465
00466 void BesTView::DefinePerspectiveView()
00467 {
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501 Double_t t12[16];
00502 Double_t cov[3];
00503 Int_t i;
00504 for (i=0; i<3; i++) cov[i] = 0.5*(fRmax[i]+fRmin[i]);
00505
00506 Double_t c1 = TMath::Cos(fPsi*kRad);
00507 Double_t s1 = TMath::Sin(fPsi*kRad);
00508 Double_t c2 = TMath::Cos(fLatitude*kRad);
00509 Double_t s2 = TMath::Sin(fLatitude*kRad);
00510 Double_t s3 = TMath::Cos(fLongitude*kRad);
00511 Double_t c3 = -TMath::Sin(fLongitude*kRad);
00512
00513 t12[0] = c1*c3 - s1*c2*s3;
00514 t12[4] = c1*s3 + s1*c2*c3;
00515 t12[8] = s1*s2;
00516 t12[3] = 0;
00517
00518 t12[1] = -s1*c3 - c1*c2*s3;
00519 t12[5] = -s1*s3 + c1*c2*c3;
00520 t12[9] = c1*s2;
00521 t12[7] = 0;
00522
00523 t12[2] = s2*s3;
00524 t12[6] = -s2*c3;
00525 t12[10] = c2;
00526 t12[11] = 0;
00527
00528
00529 t12[12] = -(cov[0]*t12[0]+cov[1]*t12[4]+cov[2]*t12[8]);
00530 t12[13] = -(cov[0]*t12[1]+cov[1]*t12[5]+cov[2]*t12[9]);
00531 t12[14] = -(cov[0]*t12[2]+cov[1]*t12[6]+cov[2]*t12[10]);
00532 t12[15] = 1;
00533
00534
00535
00536 t12[14] -= fDview;
00537
00538
00539 t12[2] *= -1;
00540 t12[6] *= -1;
00541 t12[10] *= -1;
00542 t12[14] *= -1;
00543
00544
00545
00546
00547 Double_t a2 = -fUVcoord[0]/fDproj;
00548 Double_t b2 = -fUVcoord[1]/fDproj;
00549
00550
00551
00552
00553
00554
00555 fTnorm[0] = t12[0] + a2*t12[2];
00556 fTnorm[1] = t12[1] + b2*t12[2];
00557 fTnorm[2] = t12[2];
00558 fTnorm[3] = 0;
00559
00560 fTnorm[4] = t12[4] + a2*t12[6];
00561 fTnorm[5] = t12[5] + b2*t12[6];
00562 fTnorm[6] = t12[6];
00563 fTnorm[7] = 0;
00564
00565 fTnorm[8] = t12[8] + a2*t12[10];
00566 fTnorm[9] = t12[9] + b2*t12[10];
00567 fTnorm[10] = t12[10];
00568 fTnorm[11] = 0;
00569
00570 fTnorm[12] = t12[12] + a2*t12[14];
00571 fTnorm[13] = t12[13] + b2*t12[14];
00572 fTnorm[14] = t12[14];
00573 fTnorm[15] = 1;
00574
00575
00576
00577
00578
00579 Double_t sz = 1./fDproj;
00580 Double_t sx = 1./fUVcoord[2];
00581 Double_t sy = 1./fUVcoord[3];
00582
00583 fTnorm[0] *= sx;
00584 fTnorm[4] *= sx;
00585 fTnorm[8] *= sx;
00586 fTnorm[1] *= sy;
00587 fTnorm[5] *= sy;
00588 fTnorm[9] *= sy;
00589 fTnorm[2] *= sz;
00590 fTnorm[6] *= sz;
00591 fTnorm[10] *= sz;
00592 fTnorm[12] *= sx;
00593 fTnorm[13] *= sy;
00594 fTnorm[14] *= sz;
00595 }
00596
00597
00598
00599
00600 void BesTView::DefineViewDirection(const Double_t *s, const Double_t *c,
00601 Double_t cosphi, Double_t sinphi,
00602 Double_t costhe, Double_t sinthe,
00603 Double_t cospsi, Double_t sinpsi,
00604 Double_t *tnorm, Double_t *tback)
00605 {
00606
00607
00608
00609
00610
00611
00612
00613
00614
00615
00616
00617
00618
00619
00620
00621
00622
00623 if (IsPerspective()) {
00624 DefinePerspectiveView();
00625 return;
00626 }
00627 Int_t i, k;
00628 Double_t tran[16] , rota[16] ;
00629 Double_t c1, c2, c3, s1, s2, s3, scalex, scaley, scalez;
00630
00631
00632 tback -= 5;
00633 tnorm -= 5;
00634
00635 scalex = s[0];
00636 scaley = s[1];
00637 scalez = s[2];
00638
00639
00640
00641 tran[0] = 1 / scalex;
00642 tran[1] = 0;
00643 tran[2] = 0;
00644 tran[3] = -c[0] / scalex;
00645
00646 tran[4] = 0;
00647 tran[5] = 1 / scaley;
00648 tran[6] = 0;
00649 tran[7] = -c[1] / scaley;
00650
00651 tran[8] = 0;
00652 tran[9] = 0;
00653 tran[10] = 1 / scalez;
00654 tran[11] = -c[2] / scalez;
00655
00656 tran[12] = 0;
00657 tran[13] = 0;
00658 tran[14] = 0;
00659 tran[15] = 1;
00660
00661
00662
00663
00664
00665
00666
00667 c1 = cospsi;
00668 s1 = sinpsi;
00669 c2 = costhe;
00670 s2 = sinthe;
00671 c3 = -sinphi;
00672 s3 = cosphi;
00673
00674 rota[0] = c1*c3 - s1*c2*s3;
00675 rota[1] = c1*s3 + s1*c2*c3;
00676 rota[2] = s1*s2;
00677 rota[3] = 0;
00678
00679 rota[4] = -s1*c3 - c1* c2*s3;
00680 rota[5] = -s1*s3 + c1* c2*c3;
00681 rota[6] = c1*s2;
00682 rota[7] = 0;
00683
00684 rota[8] = s2*s3;
00685 rota[9] = -s2*c3;
00686 rota[10] = c2;
00687 rota[11] = 0;
00688
00689 rota[12] = 0;
00690 rota[13] = 0;
00691 rota[14] = 0;
00692 rota[15] = 1;
00693
00694
00695
00696 for (i = 1; i <= 3; ++i) {
00697 for (k = 1; k <= 4; ++k) {
00698 tnorm[k + (i << 2)] = rota[(i << 2) - 4]*tran[k - 1] + rota[(i
00699 << 2) - 3]*tran[k + 3] + rota[(i << 2) - 2]*tran[k +7]
00700 + rota[(i << 2) - 1]*tran[k + 11];
00701 }
00702 }
00703
00704
00705
00706 tran[0] = scalex;
00707 tran[3] = c[0];
00708
00709 tran[5] = scaley;
00710 tran[7] = c[1];
00711
00712 tran[10] = scalez;
00713 tran[11] = c[2];
00714
00715
00716
00717 for (i = 1; i <= 3; ++i) {
00718 for (k = 1; k <= 4; ++k) {
00719 tback[k + (i << 2)] = tran[(i << 2) - 4]*rota[(k << 2) - 4] +
00720 tran[(i << 2) - 3]*rota[(k << 2) - 3] + tran[(i << 2) -2]
00721 *rota[(k << 2) - 2] + tran[(i << 2) - 1]*rota[(k <<2) - 1];
00722 }
00723 }
00724 }
00725
00726
00727
00728 void BesTView::DrawOutlineCube(TList *outline, Double_t *rmin, Double_t *rmax)
00729 {
00730
00731
00732 TPolyLine3D::DrawOutlineCube(outline,rmin,rmax);
00733 }
00734
00735
00736
00737 void BesTView::ExecuteEvent(Int_t event, Int_t px, Int_t py)
00738 {
00739
00740
00741 ExecuteRotateView(event,px,py);
00742 }
00743
00744
00745 void BesTView::ExecuteRotateView(Int_t event, Int_t px, Int_t py)
00746 {
00747
00748
00749
00750
00751
00752
00753
00754
00755
00756 static Int_t system, framewasdrawn;
00757 static Double_t xrange, yrange, xmin, ymin, longitude1, latitude1, longitude2, latitude2;
00758 static Double_t newlatitude, newlongitude, oldlatitude, oldlongitude;
00759 Double_t dlatitude, dlongitude, x, y;
00760 Int_t irep = 0;
00761 Double_t psideg;
00762
00763
00764
00765 if (!gPad->IsEditable()) return;
00766 gPad->AbsCoordinates(kTRUE);
00767
00768 switch (event) {
00769
00770 case kKeyPress :
00771 fChanged = kTRUE;
00772 MoveViewCommand(Char_t(px), py);
00773 break;
00774
00775 case kMouseMotion:
00776 gPad->SetCursor(kRotate);
00777 break;
00778
00779 case kButton1Down:
00780
00781
00782 xmin = gPad->GetX1();
00783 ymin = gPad->GetY1();
00784 xrange = gPad->GetX2() - xmin;
00785 yrange = gPad->GetY2() - ymin;
00786 x = gPad->PixeltoX(px);
00787 y = gPad->PixeltoY(py);
00788 system = GetSystem();
00789 framewasdrawn = 0;
00790 if (system == kCARTESIAN || system == kPOLAR || IsPerspective()) {
00791 longitude1 = 180*(x-xmin)/xrange;
00792 latitude1 = 90*(y-ymin)/yrange;
00793 } else {
00794 latitude1 = 90*(x-xmin)/xrange;
00795 longitude1 = 180*(y-ymin)/yrange;
00796 }
00797 newlongitude = oldlongitude = -90 - gPad->GetPhi();
00798 newlatitude = oldlatitude = 90 - gPad->GetTheta();
00799 psideg = GetPsi();
00800
00801
00802 if(!fOutline)
00803 SetOutlineToCube();
00804 break;
00805
00806 case kButton1Motion:
00807 {
00808
00809
00810 fChanged = kTRUE;
00811 if (framewasdrawn) fOutline->Paint();
00812 framewasdrawn = 1;
00813 x = gPad->PixeltoX(px);
00814 y = gPad->PixeltoY(py);
00815 if (system == kCARTESIAN || system == kPOLAR || IsPerspective()) {
00816 longitude2 = 180*(x-xmin)/xrange;
00817 latitude2 = 90*(y-ymin)/yrange;
00818 } else {
00819 latitude2 = 90*(x-xmin)/xrange;
00820 longitude2 = 180*(y-ymin)/yrange;
00821 }
00822 dlongitude = longitude2 - longitude1;
00823 dlatitude = latitude2 - latitude1;
00824 newlatitude = oldlatitude + dlatitude;
00825 newlongitude = oldlongitude - dlongitude;
00826 psideg = GetPsi();
00827 ResetView(newlongitude, newlatitude, psideg, irep);
00828 fOutline->Paint();
00829
00830 break;
00831 }
00832 case kButton1Up:
00833 if (gROOT->IsEscaped()) {
00834 gROOT->SetEscape(kFALSE);
00835 break;
00836 }
00837
00838
00839
00840
00841
00842
00843
00844
00845 if (gPad) {
00846 TVirtualViewer3D *viewer = gPad->GetViewer3D();
00847 if (viewer && !strcmp(viewer->IsA()->GetName(),"TView3Der3DPad")) {
00848 gPad->ReleaseViewer3D();
00849 delete viewer;
00850 }
00851 }
00852
00853
00854
00855 psideg = GetPsi();
00856 SetView(newlongitude, newlatitude, psideg, irep);
00857 gPad->SetPhi(-90-newlongitude);
00858 gPad->SetTheta(90-newlatitude);
00859 gPad->Modified(kTRUE);
00860
00861
00862 gVirtualX->SetLineColor(-1);
00863 gVirtualX->SetLineStyle(-1);
00864 gVirtualX->SetLineWidth(-1);
00865 break;
00866 }
00867
00868
00869 gPad->AbsCoordinates(kFALSE);
00870 }
00871
00872
00873
00874 void BesTView::FindNormal(Double_t x, Double_t y, Double_t z, Double_t &zn)
00875 {
00876
00877
00878
00879
00880
00881
00882
00883
00884
00885
00886
00887 zn = x*(fTN[1] * fTN[6] - fTN[2] * fTN[5]) + y*(fTN[2] * fTN[4] -
00888 fTN[0] * fTN[6]) + z*(fTN[0] * fTN[5] - fTN[1] * fTN[4]);
00889 }
00890
00891
00892 void BesTView::FindPhiSectors(Int_t iopt, Int_t &kphi, Double_t *aphi, Int_t &iphi1, Int_t &iphi2)
00893 {
00894
00895
00896
00897
00898
00899
00900
00901
00902
00903
00904
00905
00906
00907 Int_t iphi[2], i, k;
00908 Double_t dphi;
00909 Double_t x1, x2, z1, z2, phi1, phi2;
00910
00911
00912 --aphi;
00913
00914 if (aphi[kphi + 1] == aphi[1]) aphi[kphi + 1] += 360;
00915 dphi = TMath::Abs(aphi[kphi + 1] - aphi[1]);
00916 if (dphi != 360) {
00917 aphi[kphi + 2] = (aphi[1] + aphi[kphi + 1]) / (float)2. + 180;
00918 aphi[kphi + 3] = aphi[1] + 360;
00919 kphi += 2;
00920 }
00921
00922
00923
00924 k = 0;
00925 for (i = 1; i <= kphi; ++i) {
00926 phi1 = kRad*aphi[i];
00927 phi2 = kRad*aphi[i + 1];
00928 x1 = fTN[0]*TMath::Cos(phi1) + fTN[1]*TMath::Sin(phi1);
00929 x2 = fTN[0]*TMath::Cos(phi2) + fTN[1]*TMath::Sin(phi2);
00930 if (x1 >= 0 && x2 > 0) continue;
00931 if (x1 <= 0 && x2 < 0) continue;
00932 ++k;
00933 if (k == 3) break;
00934 iphi[k - 1] = i;
00935 }
00936 if (k != 2) {
00937 Error("FindPhiSectors", "something strange: num. of critical sector not equal 2");
00938 iphi1 = 1;
00939 iphi2 = 2;
00940 return;
00941 }
00942
00943
00944
00945 phi1 = kRad*(aphi[iphi[0]] + aphi[iphi[0] + 1]) / (float)2.;
00946 phi2 = kRad*(aphi[iphi[1]] + aphi[iphi[1] + 1]) / (float)2.;
00947 z1 = fTN[8]*TMath::Cos(phi1) + fTN[9]*TMath::Sin(phi1);
00948 z2 = fTN[8]*TMath::Cos(phi2) + fTN[9]*TMath::Sin(phi2);
00949 if ((z1 <= z2 && iopt == 1) || (z1 > z2 && iopt == 2)) {
00950 iphi1 = iphi[0];
00951 iphi2 = iphi[1];
00952 } else {
00953 iphi1 = iphi[1];
00954 iphi2 = iphi[0];
00955 }
00956 }
00957
00958
00959 void BesTView::FindThetaSectors(Int_t iopt, Double_t phi, Int_t &kth, Double_t *ath, Int_t &ith1, Int_t &ith2)
00960 {
00961
00962
00963
00964
00965
00966
00967
00968
00969
00970
00971
00972
00973
00974
00975 Int_t i, k, ith[2];
00976 Double_t z1, z2, cosphi, sinphi, tncons, th1, th2, dth;
00977
00978
00979 --ath;
00980
00981
00982 dth = TMath::Abs(ath[kth + 1] - ath[1]);
00983 if (dth != 360) {
00984 ath[kth + 2] = 0.5*(ath[1] + ath[kth + 1]) + 180;
00985 ath[kth + 3] = ath[1] + 360;
00986 kth += 2;
00987 }
00988
00989
00990
00991 cosphi = TMath::Cos(phi*kRad);
00992 sinphi = TMath::Sin(phi*kRad);
00993 k = 0;
00994 for (i = 1; i <= kth; ++i) {
00995 th1 = kRad*ath[i];
00996 th2 = kRad*ath[i + 1];
00997 FindNormal(TMath::Cos(th1)*cosphi, TMath::Cos(th1)*sinphi, -TMath::Sin(th1), z1);
00998 FindNormal(TMath::Cos(th2)*cosphi, TMath::Cos(th2)*sinphi, -TMath::Sin(th2), z2);
00999 if (z1 >= 0 && z2 > 0) continue;
01000 if (z1 <= 0 && z2 < 0) continue;
01001 ++k;
01002 if (k == 3) break;
01003 ith[k - 1] = i;
01004 }
01005 if (k != 2) {
01006 Error("FindThetaSectors", "Something strange: num. of critical sectors not equal 2");
01007 ith1 = 1;
01008 ith2 = 2;
01009 return;
01010 }
01011
01012
01013
01014 tncons = fTN[8]*TMath::Cos(phi*kRad) + fTN[9]*TMath::Sin(phi*kRad);
01015 th1 = kRad*(ath[ith[0]] + ath[ith[0] + 1]) / (float)2.;
01016 th2 = kRad*(ath[ith[1]] + ath[ith[1] + 1]) / (float)2.;
01017 z1 = tncons*TMath::Sin(th1) + fTN[10]*TMath::Cos(th1);
01018 z2 = tncons*TMath::Sin(th2) + fTN[10]*TMath::Cos(th2);
01019 if ((z1 <= z2 && iopt == 1) || (z1 > z2 && iopt == 2)) {
01020 ith1 = ith[0];
01021 ith2 = ith[1];
01022 } else {
01023 ith1 = ith[1];
01024 ith2 = ith[0];
01025 }
01026 }
01027
01028
01029
01030 void BesTView::FindScope(Double_t *scale, Double_t *center, Int_t &irep)
01031 {
01032
01033
01034
01035
01036
01037
01038
01039
01040
01041 irep = 0;
01042 Double_t sqrt3 = 0.5*TMath::Sqrt(3.0);
01043
01044 for (Int_t i = 0; i < 3; i++) {
01045 if (fRmin[i] >= fRmax[i]) { irep = -1; return;}
01046 scale[i] = sqrt3*(fRmax[i] - fRmin[i]);
01047 center[i] = 0.5*(fRmax[i] + fRmin[i]);
01048 }
01049 }
01050
01051
01052 Int_t BesTView::GetDistancetoAxis(Int_t axis, Int_t px, Int_t py, Double_t &ratio)
01053 {
01054
01055
01056
01057
01058
01059
01060
01061
01062
01063
01064
01065
01066
01067
01068
01069
01070
01071
01072
01073
01074
01075
01076
01077
01078
01079
01080
01081 Double_t x1,y1,x2,y2;
01082 Double_t x = px;
01083 Double_t y = py;
01084 ratio = 0;
01085
01086 if (fSystem != 1) return 9998;
01087 if (axis == 1) {
01088 x1 = gPad->XtoAbsPixel(fX1[0]);
01089 y1 = gPad->YtoAbsPixel(fX1[1]);
01090 x2 = gPad->XtoAbsPixel(fX2[0]);
01091 y2 = gPad->YtoAbsPixel(fX2[1]);
01092 } else if (axis == 2) {
01093 x1 = gPad->XtoAbsPixel(fY1[0]);
01094 y1 = gPad->YtoAbsPixel(fY1[1]);
01095 x2 = gPad->XtoAbsPixel(fY2[0]);
01096 y2 = gPad->YtoAbsPixel(fY2[1]);
01097 } else {
01098 x1 = gPad->XtoAbsPixel(fZ1[0]);
01099 y1 = gPad->YtoAbsPixel(fZ1[1]);
01100 x2 = gPad->XtoAbsPixel(fZ2[0]);
01101 y2 = gPad->YtoAbsPixel(fZ2[1]);
01102 }
01103 Double_t xx1 = x - x1;
01104 Double_t xx2 = x - x2;
01105 Double_t x1x2 = x1 - x2;
01106 Double_t yy1 = y - y1;
01107 Double_t yy2 = y - y2;
01108 Double_t y1y2 = y1 - y2;
01109 Double_t a = xx1*xx1 + yy1*yy1;
01110 Double_t b = xx2*xx2 + yy2*yy2;
01111 Double_t c = x1x2*x1x2 + y1y2*y1y2;
01112 if (c <= 0) return 9999;
01113 Double_t v = TMath::Sqrt(c);
01114 Double_t u = (a - b + c)/(2*v);
01115 Double_t d = TMath::Abs(a - u*u);
01116
01117 Int_t dist = Int_t(TMath::Sqrt(d) - 0.5);
01118 ratio = u/v;
01119 return dist;
01120 }
01121
01122
01123 Double_t BesTView::GetExtent() const
01124 {
01125
01126
01127
01128 Double_t dx = 0.5*(fRmax[0]-fRmin[0]);
01129 Double_t dy = 0.5*(fRmax[1]-fRmin[1]);
01130 Double_t dz = 0.5*(fRmax[2]-fRmin[2]);
01131 Double_t extent = TMath::Sqrt(dx*dx+dy*dy+dz*dz);
01132 return extent;
01133 }
01134
01135
01136
01137 void BesTView::GetRange(Float_t *min, Float_t *max)
01138 {
01139
01140
01141
01142 for (Int_t i = 0; i < 3; max[i] = fRmax[i], min[i] = fRmin[i], i++);
01143 }
01144
01145
01146
01147 void BesTView::GetRange(Double_t *min, Double_t *max)
01148 {
01149
01150
01151 for (Int_t i = 0; i < 3; max[i] = fRmax[i], min[i] = fRmin[i], i++) { }
01152 }
01153
01154
01155 void BesTView::GetWindow(Double_t &u0, Double_t &v0, Double_t &du, Double_t &dv) const
01156 {
01157
01158 u0 = fUVcoord[0];
01159 v0 = fUVcoord[1];
01160 du = fUVcoord[2];
01161 dv = fUVcoord[3];
01162 }
01163
01164
01165 Bool_t BesTView::IsClippedNDC(Double_t *p) const
01166 {
01167
01168
01169
01170 if (TMath::Abs(p[0])>p[2]) return kTRUE;
01171 if (TMath::Abs(p[1])>p[2]) return kTRUE;
01172 return kFALSE;
01173 }
01174
01175
01176 void BesTView::NDCtoWC(const Float_t* pn, Float_t* pw)
01177 {
01178
01179
01180
01181
01182
01183
01184
01185
01186 pw[0] = fTback[0]*pn[0] + fTback[1]*pn[1] + fTback[2]*pn[2] + fTback[3];
01187 pw[1] = fTback[4]*pn[0] + fTback[5]*pn[1] + fTback[6]*pn[2] + fTback[7];
01188 pw[2] = fTback[8]*pn[0] + fTback[9]*pn[1] + fTback[10]*pn[2] + fTback[11];
01189 }
01190
01191
01192 void BesTView::NDCtoWC(const Double_t* pn, Double_t* pw)
01193 {
01194
01195
01196
01197
01198
01199
01200
01201
01202 pw[0] = fTback[0]*pn[0] + fTback[1]*pn[1] + fTback[2]*pn[2] + fTback[3];
01203 pw[1] = fTback[4]*pn[0] + fTback[5]*pn[1] + fTback[6]*pn[2] + fTback[7];
01204 pw[2] = fTback[8]*pn[0] + fTback[9]*pn[1] + fTback[10]*pn[2] + fTback[11];
01205 }
01206
01207
01208 void BesTView::NormalWCtoNDC(const Float_t *pw, Float_t *pn)
01209 {
01210
01211
01212
01213
01214
01215
01216
01217
01218 Double_t x, y, z, a1, a2, a3, b1, b2, b3, c1, c2, c3;
01219
01220 x = pw[0];
01221 y = pw[1];
01222 z = pw[2];
01223 a1 = fTnorm[0];
01224 a2 = fTnorm[1];
01225 a3 = fTnorm[2];
01226 b1 = fTnorm[4];
01227 b2 = fTnorm[5];
01228 b3 = fTnorm[6];
01229 c1 = fTnorm[8];
01230 c2 = fTnorm[9];
01231 c3 = fTnorm[10];
01232 pn[0] = x*(b2*c3 - b3*c2) + y*(b3*c1 - b1*c3) + z*(b1*c2 - b2*c1);
01233 pn[1] = x*(c2*a3 - c3*a2) + y*(c3*a1 - c1*a3) + z*(c1*a2 - c2*a1);
01234 pn[2] = x*(a2*b3 - a3*b2) + y*(a3*b1 - a1*b3) + z*(a1*b2 - a2*b1);
01235 }
01236
01237
01238 void BesTView::NormalWCtoNDC(const Double_t *pw, Double_t *pn)
01239 {
01240
01241
01242
01243
01244
01245
01246
01247
01248 Double_t x, y, z, a1, a2, a3, b1, b2, b3, c1, c2, c3;
01249
01250 x = pw[0];
01251 y = pw[1];
01252 z = pw[2];
01253 a1 = fTnorm[0];
01254 a2 = fTnorm[1];
01255 a3 = fTnorm[2];
01256 b1 = fTnorm[4];
01257 b2 = fTnorm[5];
01258 b3 = fTnorm[6];
01259 c1 = fTnorm[8];
01260 c2 = fTnorm[9];
01261 c3 = fTnorm[10];
01262 pn[0] = x*(b2*c3 - b3*c2) + y*(b3*c1 - b1*c3) + z*(b1*c2 - b2*c1);
01263 pn[1] = x*(c2*a3 - c3*a2) + y*(c3*a1 - c1*a3) + z*(c1*a2 - c2*a1);
01264 pn[2] = x*(a2*b3 - a3*b2) + y*(a3*b1 - a1*b3) + z*(a1*b2 - a2*b1);
01265 }
01266
01267
01268 void BesTView::PadRange(Int_t rback)
01269 {
01270
01271
01272
01273
01274
01275
01276
01277
01278
01279
01280
01281
01282 Int_t i, k;
01283 Double_t x, y, z, r1, r2, r3, xx, yy, smax[2];
01284 Double_t xgraf[6], ygraf[6];
01285
01286 for (i = 1; i <= 2; ++i) {
01287 smax[i - 1] = fTnorm[(i << 2) - 1];
01288 for (k = 1; k <= 3; ++k) {
01289 if (fTnorm[k + (i << 2) - 5] < 0) {
01290 smax[i - 1] += fTnorm[k + (i << 2) - 5]*fRmin[k-1];
01291 } else {
01292 smax[i - 1] += fTnorm[k + (i << 2) - 5]*fRmax[k-1];
01293 }
01294 }
01295 }
01296
01297
01298 Double_t xmin = -smax[0];
01299 Double_t xmax = smax[0];
01300 Double_t ymin = -smax[1];
01301 Double_t ymax = smax[1];
01302 Double_t dx = xmax-xmin;
01303 Double_t dy = ymax-ymin;
01304 Double_t dxr = dx/(1 - gPad->GetLeftMargin() - gPad->GetRightMargin());
01305 Double_t dyr = dy/(1 - gPad->GetBottomMargin() - gPad->GetTopMargin());
01306
01307
01308
01309 gPad->Range(xmin - dxr*gPad->GetLeftMargin(),
01310 ymin - dyr*gPad->GetBottomMargin(),
01311 xmax + dxr*gPad->GetRightMargin(),
01312 ymax + dyr*gPad->GetTopMargin());
01313 gPad->RangeAxis(xmin, ymin, xmax, ymax);
01314
01315
01316
01317 if (rback > 0) {
01318 r1 = -1;
01319 r2 = -1;
01320 r3 = -1;
01321 xgraf[0] = -smax[0];
01322 xgraf[1] = -smax[0];
01323 xgraf[2] = -smax[0];
01324 xgraf[3] = -smax[0];
01325 xgraf[4] = smax[0];
01326 xgraf[5] = smax[0];
01327 ygraf[0] = -smax[1];
01328 ygraf[1] = smax[1];
01329 ygraf[2] = -smax[1];
01330 ygraf[3] = smax[1];
01331 ygraf[5] = smax[1];
01332 ygraf[4] = -smax[1];
01333 for (i = 1; i <= 8; ++i) {
01334 x = 0.5*((1 - r1)*fRmin[0] + (r1 + 1)*fRmax[0]);
01335 y = 0.5*((1 - r2)*fRmin[1] + (r2 + 1)*fRmax[1]);
01336 z = 0.5*((1 - r3)*fRmin[2] + (r3 + 1)*fRmax[2]);
01337 xx = fTnorm[0]*x + fTnorm[1]*y + fTnorm[2]*z + fTnorm[3];
01338 yy = fTnorm[4]*x + fTnorm[5]*y + fTnorm[6]*z + fTnorm[7];
01339 if (TMath::Abs(xx - xgraf[1]) <= 1e-4) {
01340 if (ygraf[1] >= yy) ygraf[1] = yy;
01341 if (ygraf[2] <= yy) ygraf[2] = yy;
01342 }
01343 if (TMath::Abs(xx - xgraf[5]) <= 1e-4) {
01344 if (ygraf[5] >= yy) ygraf[5] = yy;
01345 if (ygraf[4] <= yy) ygraf[4] = yy;
01346 }
01347 if (TMath::Abs(yy - ygraf[0]) <= 1e-4) xgraf[0] = xx;
01348 if (TMath::Abs(yy - ygraf[3]) <= 1e-4) xgraf[3] = xx;
01349 r1 = -r1;
01350 if (i % 2 == 0) r2 = -r2;
01351 if (i >= 4) r3 = 1;
01352 }
01353 gPad->PaintFillArea(6, xgraf, ygraf);
01354 }
01355 }
01356
01357
01358 void BesTView::SetAxisNDC(const Double_t *x1, const Double_t *x2, const Double_t *y1, const Double_t *y2, const Double_t *z1, const Double_t *z2)
01359 {
01360
01361
01362
01363
01364 for (Int_t i=0;i<3;i++) {
01365 fX1[i] = x1[i];
01366 fX2[i] = x2[i];
01367 fY1[i] = y1[i];
01368 fY2[i] = y2[i];
01369 fZ1[i] = z1[i];
01370 fZ2[i] = z2[i];
01371 }
01372 }
01373
01374
01375 void BesTView::SetDefaultWindow()
01376 {
01377
01378 if (!gPad) return;
01379 Double_t screen_factor = 1.;
01380 Double_t du, dv;
01381 Double_t extent = GetExtent();
01382 fDview = 3*extent;
01383 fDproj = 0.5*extent;
01384
01385
01386 fUpix = gPad->GetWw()*gPad->GetAbsWNDC();
01387
01388
01389 fVpix = gPad->GetWh()*gPad->GetAbsHNDC();
01390 du = 0.5*screen_factor*fDproj;
01391 dv = du*fVpix/fUpix;
01392 SetWindow(0, 0, du, dv);
01393 }
01394
01395
01396 void BesTView::SetOutlineToCube()
01397 {
01398
01399
01400
01401
01402
01403
01404
01405
01406
01407
01408
01409
01410
01411
01412
01413
01414
01415
01416
01417
01418
01419
01420
01421
01422 if (!fOutline) {
01423 fDefaultOutline = kTRUE;
01424 fOutline = new TList();
01425 }
01426 DrawOutlineCube((TList*)fOutline,fRmin,fRmax);
01427
01428
01429 }
01430
01431
01432 void BesTView::SetParallel()
01433 {
01434
01435 if (!IsPerspective()) return;
01436 SetBit(kPerspective, kFALSE);
01437 Int_t irep;
01438 ResetView(fLongitude, fLatitude, fPsi, irep);
01439 }
01440
01441
01442 void BesTView::SetPerspective()
01443 {
01444
01445 if (IsPerspective()) return;
01446 SetBit(kPerspective, kTRUE);
01447 Int_t irep;
01448 SetDefaultWindow();
01449 ResetView(fLongitude, fLatitude, fPsi, irep);
01450 }
01451
01452
01453 void BesTView::SetRange(const Double_t *min, const Double_t *max)
01454 {
01455
01456
01457
01458 Int_t irep;
01459 for (Int_t i = 0; i < 3; fRmax[i] = max[i], fRmin[i] = min[i], i++) { }
01460 if (IsPerspective()) SetDefaultWindow();
01461 ResetView(fLongitude, fLatitude, fPsi, irep);
01462 if(irep < 0)
01463 Error("SetRange", "problem setting view");
01464 if(fDefaultOutline) SetOutlineToCube();
01465 }
01466
01467
01468
01469 void BesTView::SetRange(Double_t x0, Double_t y0, Double_t z0, Double_t x1, Double_t y1, Double_t z1, Int_t flag)
01470 {
01471
01472
01473
01474
01475
01476
01477
01478
01479
01480
01481
01482
01483 Double_t rmax[3], rmin[3];
01484
01485 switch (flag) {
01486 case 2:
01487 GetRange(rmin, rmax);
01488 rmin[0] = x0 < rmin[0] ? x0 : rmin[0];
01489 rmin[1] = y0 < rmin[1] ? y0 : rmin[1];
01490 rmin[2] = z0 < rmin[2] ? z0 : rmin[2];
01491 rmax[0] = x1 > rmax[0] ? x1 : rmax[0];
01492 rmax[1] = y1 > rmax[1] ? y1 : rmax[1];
01493 rmax[2] = z1 > rmax[2] ? z1 : rmax[2];
01494 break;
01495
01496 case 1:
01497 GetRange(rmin, rmax);
01498 rmin[0] = x0 > rmin[0] ? x0 : rmin[0];
01499 rmin[1] = y0 > rmin[1] ? y0 : rmin[1];
01500 rmin[2] = z0 > rmin[2] ? z0 : rmin[2];
01501 rmax[0] = x1 < rmax[0] ? x1 : rmax[0];
01502 rmax[1] = y1 < rmax[1] ? y1 : rmax[1];
01503 rmax[2] = z1 < rmax[2] ? z1 : rmax[2];
01504 break;
01505
01506 default:
01507 rmin[0] = x0; rmax[0] = x1;
01508 rmin[1] = y0; rmax[1] = y1;
01509 rmin[2] = z0; rmax[2] = z1;
01510 }
01511 SetRange(rmin, rmax);
01512 }
01513
01514
01515 void BesTView::SetWindow(Double_t u0, Double_t v0, Double_t du, Double_t dv)
01516 {
01517
01518 fUVcoord[0] = u0;
01519 fUVcoord[1] = v0;
01520 fUVcoord[2] = du;
01521 fUVcoord[3] = dv;
01522 }
01523
01524
01525 void BesTView::SetView(Double_t longitude, Double_t latitude, Double_t psi, Int_t &irep)
01526 {
01527
01528
01529 ResetView(longitude, latitude, psi, irep);
01530 }
01531
01532
01533 void BesTView::ResizePad()
01534 {
01535
01536
01537 if (!IsPerspective()) return;
01538 Double_t upix = fUpix;
01539 Double_t vpix = fVpix;
01540
01541 fUpix = gPad->GetWw()*gPad->GetAbsWNDC();
01542
01543 fVpix = gPad->GetWh()*gPad->GetAbsHNDC();
01544 Double_t u0 = fUVcoord[0]*fUpix/upix;
01545 Double_t v0 = fUVcoord[1]*fVpix/vpix;
01546 Double_t du = fUVcoord[2]*fUpix/upix;
01547 Double_t dv = fUVcoord[3]*fVpix/vpix;
01548 SetWindow(u0, v0, du, dv);
01549 DefinePerspectiveView();
01550 }
01551
01552
01553 void BesTView::ResetView(Double_t longitude, Double_t latitude, Double_t psi, Int_t &irep)
01554 {
01555
01556
01557
01558
01559
01560
01561
01562
01563
01564
01565
01566
01567
01568 Double_t scale[3], centre[3];
01569 Double_t c1, c2, c3, s1, s2, s3;
01570
01571
01572
01573
01574 FindScope(scale, centre, irep);
01575 if (irep < 0) {
01576 Error("ResetView", "Error in min-max scope");
01577 return;
01578 }
01579
01580
01581
01582
01583 fLongitude = longitude;
01584 fPsi = psi;
01585 fLatitude = latitude;
01586
01587 if (IsPerspective()) {
01588 DefinePerspectiveView();
01589 return;
01590 }
01591
01592 c1 = TMath::Cos(longitude*kRad);
01593 s1 = TMath::Sin(longitude*kRad);
01594 c2 = TMath::Cos(latitude*kRad);
01595 s2 = TMath::Sin(latitude*kRad);
01596 c3 = TMath::Cos(psi*kRad);
01597 s3 = TMath::Sin(psi*kRad);
01598 DefineViewDirection(scale, centre, c1, s1, c2, s2, c3, s3, fTnorm, fTback);
01599 c3 = 1;
01600 s3 = 0;
01601 DefineViewDirection(scale, centre, c1, s1, c2, s2, c3, s3, fTN, fTB);
01602 }
01603
01604
01605
01606 void BesTView::WCtoNDC(const Float_t *pw, Float_t *pn)
01607 {
01608
01609
01610
01611
01612
01613
01614
01615
01616
01617 if (IsPerspective()) {
01618 for (Int_t i=0; i<3; i++)
01619 pn[i] = pw[0]*fTnorm[i]+pw[1]*fTnorm[i+4]+pw[2]*fTnorm[i+8]+fTnorm[i+12];
01620 if (pn[2]>0) {
01621 pn[0] /= pn[2];
01622 pn[1] /= pn[2];
01623 } else {
01624 pn[0] *= 1000.;
01625 pn[1] *= 1000.;
01626 }
01627 return;
01628 }
01629
01630 pn[0] = fTnorm[0]*pw[0] + fTnorm[1]*pw[1] + fTnorm[2]*pw[2] + fTnorm[3];
01631 pn[1] = fTnorm[4]*pw[0] + fTnorm[5]*pw[1] + fTnorm[6]*pw[2] + fTnorm[7];
01632 pn[2] = fTnorm[8]*pw[0] + fTnorm[9]*pw[1] + fTnorm[10]*pw[2] + fTnorm[11];
01633 }
01634
01635
01636
01637 void BesTView::WCtoNDC(const Double_t *pw, Double_t *pn)
01638 {
01639
01640
01641
01642
01643
01644
01645
01646
01647
01648 if (IsPerspective()) {
01649 for (Int_t i=0; i<3; i++)
01650 pn[i] = pw[0]*fTnorm[i]+pw[1]*fTnorm[i+4]+pw[2]*fTnorm[i+8]+fTnorm[i+12];
01651 if (pn[2]>0) {
01652 pn[0] /= pn[2];
01653 pn[1] /= pn[2];
01654 } else {
01655 pn[0] *= 1000.;
01656 pn[1] *= 1000.;
01657 }
01658 return;
01659 }
01660
01661 pn[0] = fTnorm[0]*pw[0] + fTnorm[1]*pw[1] + fTnorm[2]*pw[2] + fTnorm[3];
01662 pn[1] = fTnorm[4]*pw[0] + fTnorm[5]*pw[1] + fTnorm[6]*pw[2] + fTnorm[7];
01663 pn[2] = fTnorm[8]*pw[0] + fTnorm[9]*pw[1] + fTnorm[10]*pw[2] + fTnorm[11];
01664 }
01665
01666
01667 void BesTView::AdjustPad(TVirtualPad *pad)
01668 {
01669
01670 TVirtualPad *thisPad = pad;
01671 if (!thisPad) thisPad = gPad;
01672 if (thisPad) {
01673 thisPad->Modified();
01674 thisPad->Update();
01675 }
01676 }
01677
01678 void BesTView::RotateView(Double_t phi, Double_t theta, TVirtualPad *pad)
01679 {
01680
01681
01682 Int_t iret;
01683 Double_t p = phi;
01684 Double_t t = theta;
01685 SetView(p, t, 0, iret);
01686
01687
01688 TVirtualPad *thisPad = pad;
01689 if (!thisPad) thisPad = gPad;
01690 if (thisPad) {
01691 thisPad->SetPhi(-90-p);
01692 thisPad->SetTheta(90-t);
01693 thisPad->Modified();
01694 thisPad->Update();
01695 }
01696 }
01697
01698
01699 void BesTView::SideView(TVirtualPad *pad)
01700 {
01701
01702 RotateView(0,90.0,pad);
01703 }
01704
01705 void BesTView::FrontView(TVirtualPad *pad)
01706 {
01707
01708 RotateView(270.0,90.0,pad);
01709 }
01710
01711 void BesTView::TopView(TVirtualPad *pad)
01712 {
01713
01714 RotateView(270.0,0.0,pad);
01715 }
01716
01717 void BesTView::ToggleRulers(TVirtualPad *pad)
01718 {
01719
01720
01721
01722 TAxis3D::ToggleRulers(pad);
01723 }
01724
01725
01726 void BesTView::ToggleZoom(TVirtualPad *pad)
01727 {
01728
01729
01730
01731
01732 TAxis3D::ToggleZoom(pad);
01733 }
01734
01735
01736 void BesTView::AdjustScales(TVirtualPad *pad)
01737 {
01738
01739 Double_t min[3],max[3];
01740 GetRange(min,max);
01741 int i;
01742 Double_t maxSide = 0;
01743
01744 for (i=0;i<3; i++) maxSide = TMath::Max(maxSide,max[i]-min[i]);
01745
01746 for (i=0;i<3; i++) max[i] += maxSide - (max[i]-min[i]);
01747 SetRange(min,max);
01748
01749 AdjustPad(pad);
01750 }
01751
01752
01753 void BesTView::Centered3DImages(TVirtualPad *pad)
01754 {
01755
01756
01757 Double_t min[3],max[3];
01758 GetRange(min,max);
01759 int i;
01760 for (i=0;i<3; i++) {
01761 if (max[i] > 0) min[i] = -max[i];
01762 else max[i] = -min[i];
01763 }
01764 SetRange(min,max);
01765 AdjustPad(pad);
01766 }
01767
01768
01769 void BesTView::UnzoomView(TVirtualPad *pad,Double_t unZoomFactor )
01770 {
01771
01772 if (TMath::Abs(unZoomFactor) < 0.001) return;
01773 ZoomView(pad,1./unZoomFactor);
01774 }
01775
01776
01777 void BesTView::ZoomView(TVirtualPad *pad,Double_t zoomFactor)
01778 {
01779
01780
01781 if (TMath::Abs(zoomFactor) < 0.001) return;
01782 Double_t min[3],max[3];
01783 GetRange(min,max);
01784 int i;
01785 for (i=0;i<3; i++) {
01786
01787 Double_t c = (max[i]+min[i])/2;
01788
01789 Double_t s = (max[i]-min[i])/(2*zoomFactor);
01790
01791 max[i] = c + s;
01792 min[i] = c - s;
01793 }
01794 SetRange(min,max);
01795 AdjustPad(pad);
01796 }
01797
01798 void BesTView::MoveFocus(Double_t *cov, Double_t dx, Double_t dy, Double_t dz, Int_t nsteps,
01799 Double_t dlong, Double_t dlat, Double_t dpsi)
01800 {
01801
01802
01803 if (!IsPerspective()) return;
01804 if (nsteps<1) return;
01805 Double_t fc = 1./Double_t(nsteps);
01806 Double_t oc[3], od[3], dir[3];
01807 dir[0] = 0;
01808 dir[1] = 0;
01809 dir[2] = 1.;
01810 Int_t i, j;
01811 for (i=0; i<3; i++) {
01812 oc[i] = 0.5*(fRmin[i]+fRmax[i]);
01813 od[i] = 0.5*(fRmax[i]-fRmin[i]);
01814 }
01815 Double_t dox = cov[0]-oc[0];
01816 Double_t doy = cov[1]-oc[1];
01817 Double_t doz = cov[2]-oc[2];
01818
01819 Double_t dd = TMath::Sqrt(dox*dox+doy*doy+doz*doz);
01820 if (dd!=0) {;
01821 dir[0] = dox/dd;
01822 dir[1] = doy/dd;
01823 dir[2] = doz/dd;
01824 }
01825 dd *= fc;
01826 dox = fc*(dx-od[0]);
01827 doy = fc*(dy-od[1]);
01828 doz = fc*(dz-od[2]);
01829 for (i=0; i<nsteps; i++) {
01830 oc[0] += dd*dir[0];
01831 oc[1] += dd*dir[1];
01832 oc[2] += dd*dir[2];
01833 od[0] += dox;
01834 od[1] += doy;
01835 od[2] += doz;
01836 for (j=0; j<3; j++) {
01837 fRmin[j] = oc[j]-od[j];
01838 fRmax[j] = oc[j]+od[j];
01839 }
01840 SetDefaultWindow();
01841 fLatitude += dlat;
01842 fLongitude += dlong;
01843 fPsi += dpsi;
01844 DefinePerspectiveView();
01845 if (gPad) {
01846 gPad->Modified();
01847 gPad->Update();
01848 }
01849 }
01850 }
01851
01852
01853 void BesTView::MoveViewCommand(Char_t option, Int_t count)
01854 {
01855
01856
01857
01858
01859 if (count <= 0) count = 1;
01860 switch (option) {
01861 case '+':
01862 ZoomView();
01863 break;
01864 case '-':
01865 UnzoomView();
01866 break;
01867 case 's':
01868 case 'S':
01869 UnzoomView();
01870 break;
01871 case 'a':
01872 case 'A':
01873 ZoomView();
01874 break;
01875 case 'l':
01876 case 'L':
01877 case 'h':
01878 case 'H':
01879 case 'u':
01880 case 'U':
01881 case 'i':
01882 case 'I':
01883 MoveWindow(option);
01884 break;
01885 case 'j':
01886 case 'J':
01887 ZoomIn();
01888 break;
01889 case 'k':
01890 case 'K':
01891 ZoomOut();
01892 break;
01893 default:
01894 break;
01895 }
01896 }
01897
01898
01899 void BesTView::MoveWindow(Char_t option)
01900 {
01901
01902
01903
01904
01905
01906 if (!IsPerspective()) return;
01907 Double_t shiftu = 0.1*fUVcoord[2];
01908 Double_t shiftv = 0.1*fUVcoord[3];
01909 switch (option) {
01910 case 'l':
01911 case 'L':
01912 fUVcoord[0] += shiftu;
01913 break;
01914 case 'h':
01915 case 'H':
01916 fUVcoord[0] -= shiftu;
01917 break;
01918 case 'u':
01919 case 'U':
01920 fUVcoord[1] += shiftv;
01921 break;
01922 case 'i':
01923 case 'I':
01924 fUVcoord[1] -= shiftv;
01925 break;
01926 default:
01927 return;
01928 }
01929 DefinePerspectiveView();
01930 if (gPad) {
01931 gPad->Modified();
01932 gPad->Update();
01933 }
01934 }
01935
01936
01937 void BesTView::ZoomIn()
01938 {
01939
01940 if (!IsPerspective()) return;
01941 Double_t extent = GetExtent();
01942 Double_t fc = 0.1;
01943 if (fDview<extent) {
01944 fDview -= fc*extent;
01945 } else {
01946 fDview /= 1.25;
01947 }
01948 DefinePerspectiveView();
01949 if (gPad) {
01950 gPad->Modified();
01951 gPad->Update();
01952 }
01953 }
01954
01955
01956 void BesTView::ZoomOut()
01957 {
01958
01959 if (!IsPerspective()) return;
01960 Double_t extent = GetExtent();
01961 Double_t fc = 0.1;
01962 if (fDview<extent) {
01963 fDview += fc*extent;
01964 } else {
01965 fDview *= 1.25;
01966 }
01967 DefinePerspectiveView();
01968 if (gPad) {
01969 gPad->Modified();
01970 gPad->Update();
01971 }
01972 }
01973
01974
01975 void BesTView::Streamer(TBuffer &R__b)
01976 {
01977
01978
01979 if (R__b.IsReading()) {
01980 UInt_t R__s, R__c;
01981 Version_t R__v = R__b.ReadVersion(&R__s, &R__c);
01982 if (R__v > 1) {
01983
01984 R__b.ReadClassBuffer(TView::Class(), this, R__v, R__s, R__c);
01985 return;
01986 }
01987
01988
01989
01990
01991 if (R__b.GetParent() && R__b.GetVersionOwner() < 22500) {
01992
01993
01994 TObject::Streamer(R__b);
01995 TAttLine::Streamer(R__b);
01996 Float_t single, sa[12];
01997 Int_t i;
01998 R__b >> fSystem;
01999 R__b >> single; fLatitude = single;
02000 R__b >> single; fLongitude = single;
02001 R__b >> single; fPsi = single;
02002 R__b.ReadStaticArray(sa); for (i=0;i<12;i++) fTN[i] = sa[i];
02003 R__b.ReadStaticArray(sa); for (i=0;i<12;i++) fTB[i] = sa[i];
02004 R__b.ReadStaticArray(sa); for (i=0;i<3;i++) fRmax[i] = sa[i];
02005 R__b.ReadStaticArray(sa); for (i=0;i<3;i++) fRmin[i] = sa[i];
02006 R__b.ReadStaticArray(sa); for (i=0;i<12;i++) fTnorm[i] = sa[i];
02007 R__b.ReadStaticArray(sa); for (i=0;i<12;i++) fTback[i] = sa[i];
02008 R__b.ReadStaticArray(sa); for (i=0;i<3;i++) fX1[i] = sa[i];
02009 R__b.ReadStaticArray(sa); for (i=0;i<3;i++) fX2[i] = sa[i];
02010 R__b.ReadStaticArray(sa); for (i=0;i<3;i++) fY1[i] = sa[i];
02011 R__b.ReadStaticArray(sa); for (i=0;i<3;i++) fY2[i] = sa[i];
02012 R__b.ReadStaticArray(sa); for (i=0;i<3;i++) fZ1[i] = sa[i];
02013 R__b.ReadStaticArray(sa); for (i=0;i<3;i++) fZ2[i] = sa[i];
02014 R__b >> fOutline;
02015 R__b >> fDefaultOutline;
02016 R__b >> fAutoRange;
02017 } else {
02018 TObject::Streamer(R__b);
02019 TAttLine::Streamer(R__b);
02020 R__b >> fLatitude;
02021 R__b >> fLongitude;
02022 R__b >> fPsi;
02023 R__b.ReadStaticArray(fTN);
02024 R__b.ReadStaticArray(fTB);
02025 R__b.ReadStaticArray(fRmax);
02026 R__b.ReadStaticArray(fRmin);
02027 R__b.ReadStaticArray(fTnorm);
02028 R__b.ReadStaticArray(fTback);
02029 R__b.ReadStaticArray(fX1);
02030 R__b.ReadStaticArray(fX2);
02031 R__b.ReadStaticArray(fY1);
02032 R__b.ReadStaticArray(fY2);
02033 R__b.ReadStaticArray(fZ1);
02034 R__b.ReadStaticArray(fZ2);
02035 R__b >> fSystem;
02036 R__b >> fOutline;
02037 R__b >> fDefaultOutline;
02038 R__b >> fAutoRange;
02039 }
02040
02041
02042 } else {
02043 R__b.WriteClassBuffer(TView::Class(),this);
02044
02045 }
02046 }