TView3D.cxx

Go to the documentation of this file.
00001 // @(#)root/g3d:$Id: TView3D.cxx 23852 2008-05-14 15:01:22Z brun $
00002 // Author: Rene Brun, Nenad Buncic, Evgueni Tcherniaev, Olivier Couet   18/08/95
00003 
00004 /*************************************************************************
00005  * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
00006  * All rights reserved.                                                  *
00007  *                                                                       *
00008  * For the licensing terms see $ROOTSYS/LICENSE.                         *
00009  * For the list of contributors see $ROOTSYS/README/CREDITS.             *
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 // Remove when TView3Der3DPad fix in ExecuteRotateView() is removed
00024 #include "TVirtualViewer3D.h"
00025 
00026 ClassImp(TView3D)
00027 
00028 //const Int_t kPerspective = BIT(14);
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 /* Begin_Html
00037 <center><h2>The 3D view class</h2></center>
00038 This package was originally written by Evgueni Tcherniaev from IHEP/Protvino.
00039 <p>
00040 The original Fortran implementation was adapted to HIGZ/PAW by Olivier Couet and
00041 Evgueni Tcherniaev.
00042 <p>
00043 This View class is a subset of the original system. It has been converted to a
00044 C++ class  by Rene Brun.
00045 <p>
00046 TView3D creates a 3-D view in the current pad. In this 3D view Lego and Surface
00047 plots can be drawn and also 3D polyline and markers. Most of the time a TView3D
00048 is created automatically when a 3D object needs to be painted in a pad (for
00049 instance a Lego or a Surface plot).
00050 <p>
00051 In some case a TView3D should be explicitly. For instance to paint a 3D simple
00052 scene composed of simple objects like polylines and polymarkers.
00053 The following macro gives an example:
00054 End_Html
00055 Begin_Macro(source)
00056 {
00057    cV3D = new TCanvas("cV3D","PolyLine3D & PolyMarker3D Window",200,10,500,500);
00058 
00059    // Creating a view
00060    TView3D *view = TView::CreateView(1);
00061    view->SetRange(5,5,5,25,25,25);
00062 
00063    // Create a first PolyLine3D
00064    TPolyLine3D *pl3d1 = new TPolyLine3D(5);
00065    pl3d1->SetPoint(0, 10, 10, 10);
00066    pl3d1->SetPoint(1, 15, 15, 10);
00067    pl3d1->SetPoint(2, 20, 15, 15);
00068    pl3d1->SetPoint(3, 20, 20, 20);
00069    pl3d1->SetPoint(4, 10, 10, 20);
00070 
00071    // Create a first PolyMarker3D
00072    TPolyMarker3D *pm3d1 = new TPolyMarker3D(12);
00073    pm3d1->SetPoint(0, 10, 10, 10);
00074    pm3d1->SetPoint(1, 11, 15, 11);
00075    pm3d1->SetPoint(2, 12, 15, 9);
00076    pm3d1->SetPoint(3, 13, 17, 20);
00077    pm3d1->SetPoint(4, 14, 16, 15);
00078    pm3d1->SetPoint(5, 15, 20, 15);
00079    pm3d1->SetPoint(6, 16, 18, 10);
00080    pm3d1->SetPoint(7, 17, 15, 10);
00081    pm3d1->SetPoint(8, 18, 22, 15);
00082    pm3d1->SetPoint(9, 19, 28, 25);
00083    pm3d1->SetPoint(10, 20, 12, 15);
00084    pm3d1->SetPoint(11, 21, 12, 15);
00085    pm3d1->SetMarkerSize(2);
00086    pm3d1->SetMarkerColor(4);
00087    pm3d1->SetMarkerStyle(2);
00088 
00089    // Draw
00090    pl3d1->Draw();
00091    pm3d1->Draw();
00092 }
00093 End_Macro
00094 
00095 Begin_Html
00096 Several coordinate systems are available:
00097 <ul>
00098 <li> Cartesian
00099 <li> Polar
00100 <li> Cylindrical
00101 <li> Spherical
00102 <li> PseudoRapidity/Phi
00103 </ul>
00104 End_Html */
00105 
00106 
00107 //______________________________________________________________________________
00108 TView3D::TView3D() :TView()
00109 {
00110    // Default constructor
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    // TView3D constructor
00142    //
00143    //  Creates a 3-D view in the current pad
00144    //  rmin[3], rmax[3] are the limits of the object depending on
00145    //  the selected coordinate system
00146    //
00147    //  Before drawing a 3-D object in a pad, a 3-D view must be created.
00148    //  Note that a view is automatically created when drawing legos or surfaces.
00149    //
00150    //  The coordinate system is selected via system:
00151    //   system = 1  Cartesian
00152    //   system = 2  Polar
00153    //   system = 3  Cylindrical
00154    //   system = 4  Spherical
00155    //   system = 5  PseudoRapidity/Phi
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    // By default pad range in 3-D view is (-1,-1,1,1), so ...
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    // Copy constructor.
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    // Assignment operator.
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    // TView3D default destructor.
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    // Define axis vertices*.
00293    //
00294    //    Input  ANG     - angle between X and Y axis
00295    //
00296    //    Output: AV(3,8) - axis vertixes
00297    //            IX1     - 1st point of X-axis
00298    //            IX2     - 2nd point of X-axis
00299    //            IY1     - 1st point of Y-axis
00300    //            IY2     - 2nd point of Y-axis
00301    //            IZ1     - 1st point of Z-axis
00302    //            IZ2     - 2nd point of Z-axis
00303    //
00304    /*
00305                      8                        6
00306                     / \                      /|\
00307                  5 /   \ 7                5 / | \ 7
00308                   |\   /|                  |  |  |
00309       THETA < 90  | \6/ |     THETA > 90   | /2\ |
00310       (Top view)  |  |  |   (Bottom view)  |/   \|
00311                  1 \ | /3                 1 \   /3
00312                     \|/                      \ /
00313                      2                        4
00314    */
00315 
00316    // Local variables
00317    Double_t cosa, sina;
00318    Int_t i, k;
00319    Double_t p[8]        /* was [2][4] */;
00320    Int_t i1, i2, i3, i4, ix, iy;
00321    ix = 0;
00322 
00323    // Parameter adjustments
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    //*-*-           F I N D   T H E   M O S T   L E F T   P O I N T */
00337    i1 = 1;
00338    if (fTN[0] < 0) i1 = 2;
00339    if (fTN[0]*cosa + fTN[1]*sina < 0) i1 = 5 - i1;
00340 
00341    //*-*-          S E T   O T H E R   P O I N T S */
00342    i2 = i1 % 4 + 1;
00343    i3 = i2 % 4 + 1;
00344    i4 = i3 % 4 + 1;
00345 
00346    //*-*-          S E T   A X I S   V E R T I X E S */
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    //*-*-          S E T   A X I S
00363 
00364    if (av[4] == av[7]) ix = 2;
00365    if (av[5] == av[8]) ix = 1;
00366    iy = 3 - ix;
00367    //*-*-          X - A X I S
00368    ix1 = ix;
00369    if (av[ix*3 + 1] > av[(ix + 1)*3 + 1])      ix1 = ix + 1;
00370    ix2 = (ix << 1) - ix1 + 1;
00371    //*-*-          Y - A X I S
00372    iy1 = iy;
00373    if (av[iy*3 + 2] > av[(iy + 1)*3 + 2])      iy1 = iy + 1;
00374    iy2 = (iy << 1) - iy1 + 1;
00375    //*-*-          Z - A X I S
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    // Define perspective view.
00427    //
00428    // Compute transformation matrix from world coordinates
00429    // to normalised coordinates (-1 to +1)
00430    //   Input :
00431    //      theta, phi - spherical angles giving the direction of projection
00432    //      psi - screen rotation angle
00433    //      cov[3] - center of view
00434    //      dview - distance from COV to COP (center of projection)
00435    //      umin, umax, vmin, vmax - view window in projection plane
00436    //      dproj - distance from COP to projection plane
00437    //      bcut, fcut - backward/forward range w.r.t projection plane (fcut<=0)
00438    //   Output :
00439    //      nper[16] - normalizing transformation
00440    // compute tr+rot to get COV in origin, view vector parallel to -Z axis, up
00441    // vector parallel to Y.
00442    /*
00443                          ^Yv   UP ^  proj. plane
00444                         |        |   /|
00445                        |        |  /  |
00446                       |   dproj  /  x--- center of window (COW)
00447                  COV |----------|--x--|------------> Zv
00448                               /           | VRP'z
00449                        /   --->      |  /
00450                 /     VPN       |/
00451                Xv
00452    */
00453    //   1 - translate COP to origin of MARS : Tper = T(-copx, -copy, -copz)
00454    //   2 - rotate VPN : R = Rz(-psi)*Rx(-theta)*Rz(-phi) (inverse Euler)
00455    //   3 - left-handed screen reference to right-handed one of MARS : Trl
00456    //
00457    //   T12 = Tper*R*Trl
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;      // contains Trl
00484    t12[11] =  0;
00485 
00486    // translate with -COP (before rotation):
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    // translate with (0, 0, -dview) after rotation
00493 
00494    t12[14] -= fDview;
00495 
00496    // reflection on Z :
00497    t12[2]  *= -1;
00498    t12[6]  *= -1;
00499    t12[10] *= -1;
00500    t12[14] *= -1;
00501 
00502    // Now we shear the center of window from (0.5*(umin+umax), 0.5*(vmin+vmax), dproj)
00503    //                                     to (0, 0, dproj)
00504 
00505    Double_t a2 = -fUVcoord[0]/fDproj;   // shear coef. on x
00506    Double_t b2 = -fUVcoord[1]/fDproj;   // shear coef. on y
00507 
00508    //               | 1  0  0  0 |
00509    //  SHz(a2,b2) = | 0  1  0  0 |
00510    //               | a2 b2 1  0 |
00511    //               | 0  0  0  1 |
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    // Scale so that the view volume becomes the canonical one
00534    //
00535    // Sper = (2/(umax-umin), 2/(vmax-vmin), 1/dproj
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    // Define view direction (in spherical coordinates)
00564    //
00565    //              Compute transformation matrix from world coordinates
00566    //              to normalised coordinates (-1 to +1)
00567    //
00568    //    Input: S(3)    - scale factors
00569    //           C(3)    - centre of scope
00570    //           COSPHI  - longitude COS
00571    //           SINPHI  - longitude SIN
00572    //           COSTHE  - latitude COS (angle between +Z and view direc.)
00573    //           SINTHE  - latitude SIN
00574    //           COSPSI  - screen plane rotation angle COS
00575    //           SINPSI  - screen plane rotation angle SIN
00576 
00577    if (IsPerspective()) {
00578       DefinePerspectiveView();
00579       return;
00580    }
00581    Int_t i, k;
00582    Double_t tran[16]   /* was [4][4] */, rota[16]      /* was [4][4] */;
00583    Double_t c1, c2, c3, s1, s2, s3, scalex, scaley, scalez;
00584 
00585    // Parameter adjustments
00586    tback -= 5;
00587    tnorm -= 5;
00588 
00589    scalex = s[0];
00590    scaley = s[1];
00591    scalez = s[2];
00592 
00593    //*-*-        S E T   T R A N S L A T I O N   M A T R I X
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    //*-*-        S E T    R O T A T I O N   M A T R I X
00615    //    ( C(PSI) S(PSI) 0)   (1      0          0 )   ( C(90+PHI) S(90+PHI) 0)
00616    //    (-S(PSI) C(PSI) 0) * (0  C(THETA) S(THETA)) * (-S(90+PHI) C(90+PHI) 0)
00617    //    (   0      0    1)   (0 -S(THETA) C(THETA))   (     0           0   1)
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    //*-*-        F I N D   T R A N S F O R M A T I O N   M A T R I X
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    //*-*-        S E T   B A C K   T R A N S L A T I O N   M A T R I X
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    //*-*-        F I N D   B A C K   T R A N S F O R M A T I O N
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    // Draw the outline of a cube while rotaing a 3-d object in the pad.
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    // Execute action corresponding to one event.
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    // Execute action corresponding to one event.
00697    //
00698    //  This member function is called when a object is clicked with the locator
00699    //
00700    //  If Left button clicked in the object area, while the button is kept down
00701    //  the cube representing the surrounding frame for the corresponding
00702    //  new latitude and longitude position is drawn.
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    // All coordinates transformation are from absolute to relative
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       // remember position of the cube
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       // if outline isn't set, make it look like a cube
00749       if(!fOutline)
00750          SetOutlineToCube();
00751       break;
00752 
00753    case kButton1Motion:
00754    {
00755       // draw the surrounding frame for the current mouse position
00756       // first: Erase old frame
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       // Temporary fix for 2D drawing problems on pad. fOutline contains
00786       // a TPolyLine3D object for the rotation box. This will be painted
00787       // through a newly created TView3Der3DPad instance, which is left
00788       // behind on pad. This remaining creates 2D drawing problems.
00789       //
00790       // This is a TEMPORARY fix - will be removed when proper multiple viewers
00791       // on pad problems are resolved.
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       // End fix
00800 
00801       // Recompute new view matrix and redraw
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       // Set line color, style and width
00809       gVirtualX->SetLineColor(-1);
00810       gVirtualX->SetLineStyle(-1);
00811       gVirtualX->SetLineWidth(-1);
00812       break;
00813    }
00814 
00815    // set back to default transformation mode
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    // Find Z component of NORMAL in normalized coordinates.
00824    //
00825    //    Input: X - X-component of NORMAL
00826    //           Y - Y-component of NORMAL
00827    //           Z - Z-component of NORMAL
00828    //
00829    //    Output: ZN - Z-component of NORMAL in normalized coordinates
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    // Find critical PHI sectors.
00840    //
00841    //    Input: IOPT    - options: 1 - from BACK to FRONT 'BF'
00842    //                              2 - from FRONT to BACK 'FB'
00843    //           KPHI    - number of phi sectors
00844    //           APHI(*) - PHI separators (modified internally)
00845    //
00846    //    Output: IPHI1  - initial sector
00847    //            IPHI2  - final sector
00848 
00849    Int_t iphi[2], i, k;
00850    Double_t dphi;
00851    Double_t x1, x2, z1, z2, phi1, phi2;
00852 
00853    // Parameter adjustments
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    //*-*-       F I N D   C R I T I C A L   S E C T O R S
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    //*-*-       F I N D   O R D E R   O F   C R I T I C A L   S E C T O R S
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    // Find critical THETA sectors for given PHI sector.
00903    //
00904    //    Input: IOPT        - options: 1 - from BACK to FRONT 'BF'
00905    //                                  2 - from FRONT to BACK 'FB'
00906    //           PHI         - PHI sector
00907    //           KTH         - number of THETA sectors
00908    //           ATH(*)      - THETA separators (modified internally)
00909    //
00910    //    Output: ITH1  - initial sector
00911    //            ITH2  - final sector
00912 
00913    Int_t i, k, ith[2];
00914    Double_t z1, z2, cosphi, sinphi, tncons, th1, th2, dth;
00915 
00916    // Parameter adjustments
00917    --ath;
00918 
00919    // Function Body
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    //*-*-       F I N D   C R I T I C A L   S E C T O R S
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    //*-*-       F I N D   O R D E R   O F   C R I T I C A L   S E C T O R S
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    // Find centre of a MIN-MAX scope and scale factors
00969    //
00970    //    Output: SCALE(3)  - scale factors
00971    //            CENTER(3) - centre
00972    //            IREP      - reply (-1 if error in min-max)
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    // Return distance to axis from point px,py.
00989    //
00990    //  Algorithm:
00991    /*
00992        A(x1,y1)         P                             B(x2,y2)
00993        ------------------------------------------------ 
00994                         I
00995                         I
00996                         I
00997                         I
00998                        M(x,y)
00999    */
01000    //  Let us call  a = distance AM     A=a**2
01001    //               b = distance BM     B=b**2
01002    //               c = distance AB     C=c**2
01003    //               d = distance PM     D=d**2
01004    //               u = distance AP     U=u**2
01005    //               v = distance BP     V=v**2     c = u + v
01006    //
01007    //  D = A - U
01008    //  D = B - V  = B -(c-u)**2
01009    //     ==> u = (A -B +C)/2c
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; // only implemented for Cartesian coordinates
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    // Get maximum view extent.
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    // Get Range function.
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    // Get Range function.
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    // Get current window extent.
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    // Check if point is clipped in perspective view.
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    // Transfer point from normalized to world coordinates.
01111    //
01112    //    Input: PN(3) - point in world coordinate system
01113    //           PW(3) - point in normalized coordinate system
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    // Transfer point from normalized to world coordinates.
01125    //
01126    //    Input: PN(3) - point in world coordinate system
01127    //           PW(3) - point in normalized coordinate system
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    // Transfer vector of NORMAL from word to normalized coodinates.
01139    //
01140    //    Input: PW(3) - vector of NORMAL in word coordinate system
01141    //           PN(3) - vector of NORMAL in normalized coordinate system
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    // Transfer vector of NORMAL from word to normalized coodinates.
01167    //
01168    //    Input: PW(3) - vector of NORMAL in word coordinate system
01169    //           PN(3) - vector of NORMAL in normalized coordinate system
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    // Set the correct window size for lego and surface plots.
01195    //
01196    //  Set the correct window size for lego and surface plots.
01197    //  And draw the background if necessary.
01198    //
01199    //    Input parameters:
01200    //
01201    //   RBACK : Background colour
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    //*-*- Compute x,y range
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    // Range() could change the size of the pad pixmap and therefore should
01229    // be called before the other paint routines
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    //*-*-             Draw the background if necessary
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    // Store axis coordinates in the NDC system.
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    // Set default viewing window.
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    // widh in pixels
01307    fUpix = gPad->GetWw()*gPad->GetAbsWNDC();
01308 
01309    // height in pixels
01310    fVpix = gPad->GetWh()*gPad->GetAbsHNDC();
01311    du = 0.5*screen_factor*fDproj;
01312    dv = du*fVpix/fUpix;   // keep aspect ratio
01313    SetWindow(0, 0, du, dv);
01314 }
01315 
01316 
01317 //______________________________________________________________________________
01318 void TView3D::SetOutlineToCube()
01319 {
01320    // This is a function which creates default outline.
01321    //
01322    //      x = fRmin[0]        X = fRmax[0]
01323    //      y = fRmin[1]        Y = fRmax[1]
01324    //      z = fRmin[2]        Z = fRmax[2]
01325    /*
01326    
01327                (x,Y,Z) +---------+ (X,Y,Z)
01328                       /         /|
01329                      /         / |
01330                     /         /  |
01331            (x,y,Z) +---------+   |
01332                    |         |   + (X,Y,z)
01333                    |         |  /
01334                    |         | /
01335                    |         |/
01336                    +---------+
01337                 (x,y,z)   (X,y,z)
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    // Set the parallel option (default).
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    // Set perspective option.
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    // Set Range function.
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    // Set 3-D View range.
01392    //
01393    // Input:  x0, y0, z0 are minimum coordinates
01394    //         x1, y1, z1 are maximum coordinates
01395    //
01396    //         flag values are: 0 (set always) <- default
01397    //                          1 (shrink view)
01398    //                          2 (expand view)
01399    //
01400 
01401    Double_t rmax[3], rmin[3];
01402 
01403    switch (flag) {
01404       case 2:                     // expand view
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:                     // shrink view
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    // Set viewing window.
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    //set view parameters
01449 
01450    ResetView(longitude, latitude, psi, irep);
01451 }
01452 
01453 
01454 //______________________________________________________________________________
01455 void TView3D::ResizePad()
01456 {
01457    // Recompute window for perspective view
01458 
01459    if (!IsPerspective()) return;
01460    Double_t upix = fUpix;
01461    Double_t vpix = fVpix;
01462 
01463    // widh in pixels
01464    fUpix = gPad->GetWw()*gPad->GetAbsWNDC();
01465 
01466    // height in pixels
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    // Set view direction (in spherical coordinates).
01481    //
01482    //    Input  PHI     - longitude
01483    //           THETA   - latitude (angle between +Z and view direction)
01484    //           PSI     - rotation in screen plane
01485    //
01486    //    Output: IREP   - reply (-1 if error in min-max)
01487    //
01488    //    Errors: error in min-max scope
01489 
01490    Double_t scale[3],  centre[3];
01491    Double_t c1, c2, c3, s1, s2, s3;
01492 
01493    //*-*-        F I N D   C E N T E R   O F   S C O P E   A N D
01494    //*-*-        S C A L E   F A C T O R S
01495    FindScope(scale, centre, irep);
01496    if (irep < 0) {
01497       Error("ResetView", "Error in min-max scope");
01498       return;
01499    }
01500 
01501    //*-*-        S E T   T R A N S F O R M A T I O N   M A T R I C E S
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    // Transfer point from world to normalized coordinates.
01528    //
01529    //    Input: PW(3) - point in world coordinate system
01530    //           PN(3) - point in normalized coordinate system
01531 
01532    // perspective view
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    // parallel view
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    // Transfer point from world to normalized coordinates.
01556    //
01557    //    Input: PW(3) - point in world coordinate system
01558    //           PN(3) - point in normalized coordinate system
01559 
01560    // perspective view
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    // parallel view
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    // Force the current pad to be updated
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    // API to rotate view and adjust the pad provided it the current one.
01599 
01600    Int_t iret;
01601    Double_t p = phi;
01602    Double_t t = theta;
01603    SetView(p, t, 0, iret);
01604 
01605    // Adjust current pad too
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    // Set to side view.
01621 
01622    RotateView(0,90.0,pad);
01623 }
01624 
01625 
01626 //______________________________________________________________________________
01627 void TView3D::FrontView(TVirtualPad *pad)
01628 {
01629    // Set to front view.
01630 
01631    RotateView(270.0,90.0,pad);
01632 }
01633 
01634 
01635 //______________________________________________________________________________
01636 void TView3D::TopView(TVirtualPad *pad)
01637 {
01638    // Set to top view.
01639 
01640    RotateView(270.0,0.0,pad);
01641 }
01642 
01643 
01644 //______________________________________________________________________________
01645 void TView3D::ToggleRulers(TVirtualPad *pad)
01646 {
01647    // Turn on /off 3D axis
01648 
01649    TAxis3D::ToggleRulers(pad);
01650 }
01651 
01652 
01653 //______________________________________________________________________________
01654 void TView3D::ToggleZoom(TVirtualPad *pad)
01655 {
01656    // Turn on /off the interactive option to
01657    //  Zoom / Move / Change attributes of 3D axis correspond this view
01658 
01659    TAxis3D::ToggleZoom(pad);
01660 }
01661 
01662 
01663 //______________________________________________________________________________
01664 void TView3D::AdjustScales(TVirtualPad *pad)
01665 {
01666    // Adjust all sides of view in respect of the biggest one
01667 
01668    Double_t min[3],max[3];
01669    GetRange(min,max);
01670    int i;
01671    Double_t maxSide = 0;
01672    // Find the largest side
01673    for (i=0;i<3; i++) maxSide = TMath::Max(maxSide,max[i]-min[i]);
01674    //Adjust scales:
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    // Move view into the center of the scene
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    // unZOOM this view
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    // ZOOM this view
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       // Find center
01720       Double_t c = (max[i]+min[i])/2;
01721       // Find a new size
01722       Double_t s = (max[i]-min[i])/(2*zoomFactor);
01723       // Set a new size
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    // Move focus to a different box position and extent in nsteps. Perform rotation
01737    // with dlat,dlong,dpsi at each step.
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    // 'a' increase  scale factor (clip cube borders)
01793    // 's' decrease  scale factor (clip cube borders)
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    // Move view window :
01839    // l,L - left
01840    // h,H - right
01841    // u,U - down
01842    // i,I - up
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    // Zoom in.
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    // Zoom out.
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    // Stream an object of class TView3D.
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       //====process old versions before automatic schema evolution
01930       //unfortunately we forgot to increment the TView3D version number
01931       //when the class was upgraded to double precision in version 2.25.
01932       //we are forced to use the file version number to recognize old files.
01933       if (R__b.GetParent() && R__b.GetVersionOwner() < 22500) { //old version in single precision
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       //====end of old versions
01981 
01982    } else {
01983       R__b.WriteClassBuffer(TView3D::Class(),this);
01984    }
01985 }
01986 
01987 //      Shortcuts for menus
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 

Generated on Tue Jul 5 14:16:41 2011 for ROOT_528-00b_version by  doxygen 1.5.1