00001
00002
00003
00004
00005
00006
00007
00008
00009
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
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042 TSPHE::TSPHE()
00043 {
00044
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;
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
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;
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
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;
00108
00109 SetNumberOfDivisions (20);
00110 }
00111
00112
00113
00114 TSPHE::~TSPHE()
00115 {
00116
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
00132
00133
00134
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
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
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
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];
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
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)
00211 specialCase = kTRUE;
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
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;
00237 fCoTab = new Double_t [n];
00238 if (!fCoTab ) return;
00239
00240 if (fSiTab)
00241 delete [] fSiTab;
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;
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
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
00294 TShape::Streamer(b);
00295 b >> fRmin;
00296 b >> fRmax;
00297 b >> fThemin;
00298 b >> fThemax;
00299 b >> fPhimin;
00300 b >> fPhimax;
00301 Int_t tNdiv;
00302 b >> tNdiv;
00303 if (R__v > 1) {
00304 b >> faX;
00305 b >> faY;
00306 b >> faZ;
00307 }
00308 SetNumberOfDivisions (tNdiv);
00309 b.CheckByteCount(R__s, R__c, TSPHE::IsA());
00310
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
00322
00323 static TBuffer3D buffer(TBuffer3DTypes::kGeneric);
00324
00325 TShape::FillBuffer3D(buffer, reqSections);
00326
00327
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
00342 SetPoints(buffer.fPnts);
00343 if (!buffer.fLocalFrame) {
00344 TransformPoints(buffer.fPnts, buffer.NbPnts());
00345 }
00346
00347 Int_t c = GetBasicColor();
00348
00349
00350 Int_t indx = 0;
00351 Int_t indx2 = 0;
00352 Int_t i, j, k;
00353
00354
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
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
00380 for (i = 0; i < (nz-1); i++) {
00381
00382
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
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
00399
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
00411 Int_t m = n - 1 + (specialCase == kTRUE);
00412 indx = 0;
00413
00414
00415
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
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
00485
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 }