TSPHE.cxx

Go to the documentation of this file.
00001 // @(#)root/g3d:$Id: TSPHE.cxx 31635 2009-12-08 10:35:17Z couet $
00002 // Author: Rene Brun   13/06/97
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 "TSPHE.h"
00013 #include "TNode.h"
00014 #include "TVirtualPad.h"
00015 #include "TBuffer3D.h"
00016 #include "TBuffer3DTypes.h"
00017 #include "TGeometry.h"
00018 #include "TClass.h"
00019 #include "TMath.h"
00020 
00021 ClassImp(TSPHE)
00022 
00023 
00024 //______________________________________________________________________________
00025 // Begin_Html <P ALIGN=CENTER> <IMG SRC="gif/sphe.gif"> </P> End_Html
00026 // SPHE is a Sphere. It has 9 parameters:
00027 //
00028 //     - name       name of the shape
00029 //     - title      shape's title
00030 //     - material  (see TMaterial)
00031 //     - rmin       minimum radius
00032 //     - rmax       maximum radius
00033 //     - themin     theta min
00034 //     - themax     theta max
00035 //     - phimin     phi min
00036 //     - phimax     phi max
00037 
00038 // ROOT color indx = max(i-i0,j-j0);
00039 
00040 
00041 //______________________________________________________________________________
00042 TSPHE::TSPHE()
00043 {
00044    // SPHE shape default constructor
00045 
00046    fRmin       = 0;
00047    fRmax       = 0;
00048    fThemin     = 0;
00049    fThemax     = 0;
00050    fPhimin     = 0;
00051    fPhimax     = 0;
00052    fSiTab      = 0;
00053    fCoTab      = 0;
00054    fCoThetaTab = 0;
00055    fNdiv       = 0;
00056    fAspectRatio=1.0;
00057    faX = faY = faZ = 1.0;      // Coeff along Ox
00058    fNz = 0;
00059 }
00060 
00061 
00062 //______________________________________________________________________________
00063 TSPHE::TSPHE(const char *name, const char *title, const char *material, Float_t rmin, Float_t rmax, Float_t themin,
00064              Float_t themax, Float_t phimin, Float_t phimax)
00065      : TShape(name, title,material)
00066 {
00067    // SPHE shape normal constructor
00068 
00069    fRmin   = rmin;
00070    fRmax   = rmax;
00071    fThemin = themin;
00072    fThemax = themax;
00073    fPhimin = phimin;
00074    fPhimax = phimax;
00075 
00076    fSiTab      = 0;
00077    fCoTab      = 0;
00078    fCoThetaTab = 0;
00079    fNdiv       = 0;
00080 
00081    fAspectRatio=1.0;
00082    faX = faY = faZ = 1.0;      // Coeff along Ox
00083 
00084    SetNumberOfDivisions (20);
00085 }
00086 
00087 
00088 //______________________________________________________________________________
00089 TSPHE::TSPHE(const char *name, const char *title, const char *material, Float_t rmax)
00090      : TShape(name, title,material)
00091 {
00092    // SPHE shape "simplified" constructor
00093 
00094    fRmin   = 0;
00095    fRmax   = rmax;
00096    fThemin = 0;
00097    fThemax = 180;
00098    fPhimin = 0;
00099    fPhimax = 360;
00100 
00101    fSiTab      = 0;
00102    fCoTab      = 0;
00103    fCoThetaTab = 0;
00104    fNdiv       = 0;
00105 
00106    fAspectRatio=1.0;
00107    faX = faY = faZ = 1.0;      // Coeff along Ox
00108 
00109    SetNumberOfDivisions (20);
00110 }
00111 
00112 
00113 //______________________________________________________________________________
00114 TSPHE::~TSPHE()
00115 {
00116    // SPHE shape default destructor
00117 
00118    if (fCoThetaTab) delete [] fCoThetaTab;
00119    if (fSiTab) delete [] fSiTab;
00120    if (fCoTab) delete [] fCoTab;
00121 
00122    fCoTab = 0;
00123    fSiTab = 0;
00124    fCoThetaTab=0;
00125 }
00126 
00127 
00128 //______________________________________________________________________________
00129 Int_t TSPHE::DistancetoPrimitive(Int_t px, Int_t py)
00130 {
00131    // Compute distance from point px,py to a PSPHE
00132    //
00133    // Compute the closest distance of approach from point px,py to each
00134    // computed outline point of the PSPHE (stolen from PCON).
00135 
00136    Int_t n = GetNumberOfDivisions()+1;
00137    Int_t numPoints = 2*n*(fNz+1);
00138    return ShapeDistancetoPrimitive(numPoints,px,py);
00139 }
00140 
00141 
00142 //______________________________________________________________________________
00143 void TSPHE::SetEllipse(const Float_t *factors)
00144 {
00145    // Set ellipse.
00146 
00147    if (factors[0] > 0) faX = factors[0];
00148    if (factors[1] > 0) faY = factors[1];
00149    if (factors[2] > 0) faZ = factors[2];
00150 }
00151 
00152 
00153 //______________________________________________________________________________
00154 void TSPHE::SetNumberOfDivisions (Int_t p)
00155 {
00156    // Set number of divisions.
00157 
00158    if (GetNumberOfDivisions () == p) return;
00159    fNdiv=p;
00160    fNz = Int_t(fAspectRatio*fNdiv*(fThemax - fThemin )/(fPhimax - fPhimin )) + 1;
00161    MakeTableOfCoSin();
00162 }
00163 
00164 
00165 //______________________________________________________________________________
00166 void TSPHE::SetPoints(Double_t *points) const
00167 {
00168    // Create SPHE points
00169 
00170    Int_t i, j, n;
00171    Int_t indx = 0;
00172 
00173    n = GetNumberOfDivisions()+1;
00174 
00175    if (points) {
00176       if (!fCoTab)   MakeTableOfCoSin();
00177       Float_t z;
00178       for (i = 0; i < fNz+1; i++) {
00179          z = fRmin * fCoThetaTab[i]; // fSinPhiTab[i];
00180          Float_t sithet = TMath::Sqrt(TMath::Abs(1-fCoThetaTab[i]*fCoThetaTab[i]));
00181          Float_t zi = fRmin*sithet;
00182          for (j = 0; j < n; j++) {
00183             points[indx++] = faX*zi * fCoTab[j];
00184             points[indx++] = faY*zi * fSiTab[j];
00185             points[indx++] = faZ*z;
00186          }
00187          z = fRmax * fCoThetaTab[i];
00188          zi = fRmax*sithet;
00189          for (j = 0; j < n; j++) {
00190             points[indx++] = faX*zi * fCoTab[j];
00191             points[indx++] = faY*zi * fSiTab[j];
00192             points[indx++] = faZ*z;
00193          }
00194       }
00195    }
00196 }
00197 
00198 
00199 //______________________________________________________________________________
00200 void TSPHE::Sizeof3D() const
00201 {
00202    // Return total X3D needed by TNode::ls (when called with option "x")
00203 
00204    Int_t n;
00205 
00206    n = GetNumberOfDivisions()+1;
00207    Int_t nz = fNz+1;
00208    Bool_t specialCase = kFALSE;
00209 
00210    if (TMath::Abs(TMath::Sin(2*(fPhimax - fPhimin))) <= 0.01)  //mark this as a very special case, when
00211          specialCase = kTRUE;                                  //we have to draw this PCON like a TUBE
00212 
00213    gSize3D.numPoints += 2*n*nz;
00214    gSize3D.numSegs   += 4*(nz*n-1+(specialCase == kTRUE));
00215    gSize3D.numPolys  += 2*(nz*n-1+(specialCase == kTRUE));
00216 }
00217 
00218 
00219 //______________________________________________________________________________
00220 void TSPHE::MakeTableOfCoSin() const
00221 {
00222    // Make table of sine and cosine.
00223 
00224    const Double_t pi  = TMath::ATan(1) * 4.0;
00225    const Double_t ragrad  = pi/180.0;
00226 
00227    Float_t dphi = fPhimax - fPhimin;
00228    while (dphi > 360) dphi -= 360;
00229 
00230    Float_t dtet = fThemax - fThemin;
00231    while (dtet > 180) dtet -= 180;
00232 
00233    Int_t j;
00234    Int_t n = GetNumberOfDivisions () + 1;
00235    if (fCoTab)
00236       delete [] fCoTab; // Delete the old tab if any
00237    fCoTab = new Double_t [n];
00238    if (!fCoTab ) return;
00239 
00240    if (fSiTab)
00241       delete [] fSiTab; // Delete the old tab if any
00242    fSiTab = new Double_t [n];
00243    if (!fSiTab ) return;
00244 
00245    Double_t range   = Double_t(dphi * ragrad);
00246    Double_t phi1    = Double_t(fPhimin  * ragrad);
00247    Double_t angstep = range/(n-1);
00248 
00249    Double_t ph = phi1;
00250    for (j = 0; j < n; j++)
00251    {
00252       ph = phi1 + j*angstep;
00253       fCoTab[j] = TMath::Cos(ph);
00254       fSiTab[j] = TMath::Sin(ph);
00255    }
00256 
00257    n  = fNz + 1;
00258 
00259    if (fCoThetaTab)
00260       delete [] fCoThetaTab; // Delete the old tab if any
00261    fCoThetaTab = new Double_t [n];
00262    if (!fCoThetaTab ) return;
00263 
00264    range   = Double_t(dtet * ragrad);
00265    phi1    = Double_t(fThemin  * ragrad);
00266    angstep = range/(n-1);
00267 
00268    ph = phi1;
00269    for (j = 0; j < n; j++)
00270    {
00271       fCoThetaTab[n-j-1] = TMath::Cos(ph);
00272       ph += angstep;
00273    }
00274 
00275 }
00276 
00277 
00278 //______________________________________________________________________________
00279 void TSPHE::Streamer(TBuffer &b)
00280 {
00281    // Stream a class object
00282 
00283    if (b.IsReading()) {
00284       UInt_t R__s, R__c;
00285       Version_t R__v = b.ReadVersion(&R__s, &R__c);
00286       if (R__v > 2) {
00287          b.ReadClassBuffer(TSPHE::Class(), this, R__v, R__s, R__c);
00288          Int_t ndiv = fNdiv;
00289          fNdiv = 0;
00290          SetNumberOfDivisions (ndiv);
00291          return;
00292       }
00293       //====process old versions before automatic schema evolution
00294       TShape::Streamer(b);
00295       b >> fRmin;    // minimum radius
00296       b >> fRmax;    // maximum radius
00297       b >> fThemin;  // minimum theta
00298       b >> fThemax;  // maximum theta
00299       b >> fPhimin;  // minimum phi
00300       b >> fPhimax;  // maximum phi
00301       Int_t tNdiv;   // XXX added by RvdE XXX (fNdiv is set by SetNumberOfDivisions)
00302       b >> tNdiv;
00303       if (R__v > 1) {
00304          b >> faX;
00305          b >> faY;
00306          b >> faZ;
00307       }
00308       SetNumberOfDivisions (tNdiv); // XXX added by RvdE
00309       b.CheckByteCount(R__s, R__c, TSPHE::IsA());
00310       //====end of old versions
00311       
00312    } else {
00313       b.WriteClassBuffer(TSPHE::Class(),this);
00314    }
00315 }
00316 
00317 
00318 //______________________________________________________________________________
00319 const TBuffer3D & TSPHE::GetBuffer3D(Int_t reqSections) const
00320 {
00321    // Get buffer 3d.
00322 
00323    static TBuffer3D buffer(TBuffer3DTypes::kGeneric);
00324 
00325    TShape::FillBuffer3D(buffer, reqSections);
00326 
00327    // Needed by kRawSizes / kRaw
00328    const Int_t n = GetNumberOfDivisions()+1;
00329    const Int_t nz = fNz+1;
00330    Bool_t specialCase = (TMath::Abs(TMath::Sin(2*(fPhimax - fPhimin))) <= 0.01);
00331 
00332    if (reqSections & TBuffer3D::kRawSizes) {
00333       Int_t nbPnts = 2*n*nz;
00334       Int_t nbSegs = 4*(nz*n-1+(specialCase == kTRUE));
00335       Int_t nbPols = 2*(nz*n-1+(specialCase == kTRUE));
00336       if (buffer.SetRawSizes(nbPnts, 3*nbPnts, nbSegs, 3*nbSegs, nbPols, 6*nbPols)) {
00337          buffer.SetSectionsValid(TBuffer3D::kRawSizes);
00338       }
00339    }
00340    if ((reqSections & TBuffer3D::kRaw) && buffer.SectionsValid(TBuffer3D::kRawSizes)) {
00341       // Points
00342       SetPoints(buffer.fPnts);
00343       if (!buffer.fLocalFrame) {
00344          TransformPoints(buffer.fPnts, buffer.NbPnts());
00345       }
00346 
00347       Int_t c = GetBasicColor();
00348 
00349       // Segments
00350       Int_t indx = 0;
00351       Int_t indx2 = 0;
00352       Int_t i, j, k;
00353       //inside & outside spheres, number of segments: 2*nz*(n-1)
00354       //             special case number of segments: 2*nz*n
00355       for (i = 0; i < nz*2; i++) {
00356          indx2 = i*n;
00357          for (j = 1; j < n; j++) {
00358             buffer.fSegs[indx++] = c;
00359             buffer.fSegs[indx++] = indx2+j-1;
00360             buffer.fSegs[indx++] = indx2+j;
00361          }
00362          if (specialCase) {
00363             buffer.fSegs[indx++] = c;
00364             buffer.fSegs[indx++] = indx2+j-1;
00365             buffer.fSegs[indx++] = indx2;
00366          }
00367       }
00368 
00369       //bottom & top lines, number of segments: 2*n
00370       for (i = 0; i < 2; i++) {
00371          indx2 = i*(nz-1)*2*n;
00372          for (j = 0; j < n; j++) {
00373             buffer.fSegs[indx++] = c;
00374             buffer.fSegs[indx++] = indx2+j;
00375             buffer.fSegs[indx++] = indx2+n+j;
00376          }
00377       }
00378 
00379       //inside & outside spheres, number of segments: 2*(nz-1)*n
00380       for (i = 0; i < (nz-1); i++) {
00381 
00382          //inside sphere
00383          indx2 = i*n*2;
00384          for (j = 0; j < n; j++) {
00385             buffer.fSegs[indx++] = c+2;
00386             buffer.fSegs[indx++] = indx2+j;
00387             buffer.fSegs[indx++] = indx2+n*2+j;
00388          }
00389          //outside sphere
00390          indx2 = i*n*2+n;
00391          for (j = 0; j < n; j++) {
00392             buffer.fSegs[indx++] = c+3;
00393             buffer.fSegs[indx++] = indx2+j;
00394             buffer.fSegs[indx++] = indx2+n*2+j;
00395          }
00396       }
00397 
00398       //left & right sections, number of segments: 2*(nz-2)
00399       //          special case number of segments: 0
00400       if (!specialCase) {
00401          for (i = 1; i < (nz-1); i++) {
00402             for (j = 0; j < 2; j++) {
00403                buffer.fSegs[indx++] = c;
00404                buffer.fSegs[indx++] =  2*i    * n + j*(n-1);
00405                buffer.fSegs[indx++] = (2*i+1) * n + j*(n-1);
00406             }
00407          }
00408       }
00409 
00410       // Polygons
00411       Int_t m = n - 1 + (specialCase == kTRUE);
00412       indx = 0;
00413 
00414       //bottom & top, number of polygons: 2*(n-1)
00415       // special case number of polygons: 2*n
00416       for (j = 0; j < n-1; j++) {
00417          buffer.fPols[indx++] = c+3;
00418          buffer.fPols[indx++] = 4;
00419          buffer.fPols[indx++] = 2*nz*m+j;
00420          buffer.fPols[indx++] = m+j;
00421          buffer.fPols[indx++] = 2*nz*m+j+1;
00422          buffer.fPols[indx++] = j;
00423       }
00424       for (j = 0; j < n-1; j++) {
00425          buffer.fPols[indx++] = c+3;
00426          buffer.fPols[indx++] = 4;
00427          buffer.fPols[indx++] = 2*nz*m+n+j;
00428          buffer.fPols[indx++] = (nz*2-2)*m+j;
00429          buffer.fPols[indx++] = 2*nz*m+n+j+1;
00430          buffer.fPols[indx++] = (nz*2-2)*m+m+j;
00431       }
00432       if (specialCase) {
00433          buffer.fPols[indx++] = c+3;
00434          buffer.fPols[indx++] = 4;
00435          buffer.fPols[indx++] = 2*nz*m+j;
00436          buffer.fPols[indx++] = m+j;
00437          buffer.fPols[indx++] = 2*nz*m;
00438          buffer.fPols[indx++] = j;
00439          
00440          buffer.fPols[indx++] = c+3;
00441          buffer.fPols[indx++] = 4;
00442          buffer.fPols[indx++] = 2*nz*m+n+j;
00443          buffer.fPols[indx++] = (nz*2-2)*m+j;
00444          buffer.fPols[indx++] = 2*nz*m+n;
00445          buffer.fPols[indx++] = (nz*2-2)*m+m+j;
00446       }
00447 
00448       //inside & outside, number of polygons: (nz-1)*2*(n-1)
00449       for (k = 0; k < (nz-1); k++) {
00450          for (j = 0; j < n-1; j++) {
00451             buffer.fPols[indx++] = c;
00452             buffer.fPols[indx++] = 4;
00453             buffer.fPols[indx++] = 2*k*m+j;
00454             buffer.fPols[indx++] = nz*2*m+(2*k+2)*n+j+1;
00455             buffer.fPols[indx++] = (2*k+2)*m+j;
00456             buffer.fPols[indx++] = nz*2*m+(2*k+2)*n+j;
00457          }
00458          for (j = 0; j < n-1; j++) {
00459             buffer.fPols[indx++] = c+1;
00460             buffer.fPols[indx++] = 4;
00461             buffer.fPols[indx++] = (2*k+1)*m+j;
00462             buffer.fPols[indx++] = nz*2*m+(2*k + 3)*n+j;
00463             buffer.fPols[indx++] = (2*k+ 3)*m+j;
00464             buffer.fPols[indx++] = nz*2*m+(2*k+3)*n+j+1;
00465          }
00466          
00467          if (specialCase) {
00468             buffer.fPols[indx++] = c;
00469             buffer.fPols[indx++] = 4;
00470             buffer.fPols[indx++] = 2*k*m+j;
00471             buffer.fPols[indx++] = nz*2*m+(2*k+2)*n+j;
00472             buffer.fPols[indx++] = (2*k+2)*m+j;
00473             buffer.fPols[indx++] = nz*2*m+(2*k+2)*n;
00474             
00475             buffer.fPols[indx++] = c+1;
00476             buffer.fPols[indx++] = 4;
00477             buffer.fPols[indx++] = (2*k+1)*m+j;
00478             buffer.fPols[indx++] = nz*2*m+(2*k+3)*n+j;
00479             buffer.fPols[indx++] = (2*k+3)*m+j;
00480             buffer.fPols[indx++] = nz*2*m+(2*k+3)*n;
00481          }
00482       }
00483 
00484       //left & right sections, number of polygons: 2*(nz-1)
00485       //          special case number of polygons: 0
00486       if (!specialCase) {
00487          indx2 = nz*2*(n-1);
00488          for (k = 0; k < (nz-1); k++) {
00489             buffer.fPols[indx++] = c+2;
00490             buffer.fPols[indx++] = 4;
00491             buffer.fPols[indx++] = k==0 ? indx2 : indx2+2*nz*n+2*(k-1);
00492             buffer.fPols[indx++] = indx2+2*(k+1)*n;
00493             buffer.fPols[indx++] = indx2+2*nz*n+2*k;
00494             buffer.fPols[indx++] = indx2+(2*k+3)*n;
00495             
00496               buffer.fPols[indx++] = c+2;
00497             buffer.fPols[indx++] = 4;
00498             buffer.fPols[indx++] = k==0 ? indx2+n-1 : indx2+2*nz*n+2*(k-1)+1;
00499             buffer.fPols[indx++] = indx2+(2*k+3)*n+n-1;
00500             buffer.fPols[indx++] = indx2+2*nz*n+2*k+1;
00501             buffer.fPols[indx++] = indx2+2*(k+1)*n+n-1;
00502          }
00503 
00504          buffer.fPols[indx-8] = indx2+n;
00505          buffer.fPols[indx-2] = indx2+2*n-1;
00506       }
00507 
00508       buffer.SetSectionsValid(TBuffer3D::kRaw);
00509    }
00510 
00511    return buffer;
00512 }

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