/home/bes3soft/bes3soft/Boss/7.0.2/dist/7.0.2/EventDisplay/BesVisLib/BesVisLib-00-04-04/src/BesTView.cxx

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

Generated on Tue Nov 29 23:12:04 2016 for BOSS_7.0.2 by  doxygen 1.4.7