00001
00002
00003
00004
00005
00006
00007
00008
00009
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
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044 TPCON::TPCON()
00045 {
00046
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
00065
00066
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
00102 }
00103
00104
00105 TPCON& TPCON::operator=(const TPCON& pc)
00106 {
00107
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
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;
00134 fCoTab = new Double_t [n];
00135 if (!fCoTab ) return;
00136
00137 if (fSiTab)
00138 delete [] fSiTab;
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
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
00173
00174
00175
00176
00177
00178
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
00192
00193
00194
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
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
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
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
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
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
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
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
00307
00308 static TBuffer3D buffer(TBuffer3DTypes::kGeneric);
00309
00310 TShape::FillBuffer3D(buffer, reqSections);
00311
00312
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
00329 SetPoints(buffer.fPnts);
00330 if (!buffer.fLocalFrame) {
00331 TransformPoints(buffer.fPnts, buffer.NbPnts());
00332 }
00333
00334
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
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
00360
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
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
00386 for (i = 0; i < (fNz-1); i++) {
00387
00388
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
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
00405
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
00420
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 }