TPCON.cxx

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

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