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