4 // ---------------------------------------------------------------------------
8 // This file is part of the ALICE Geometry Database .
10 // Author: Joana E. Santo
12 // ---------------------------------------------------------------------------
15 #include <TVirtualPad.h>
18 #include <TGLKernelABC.h>
20 #include "AliGSphere.h"
25 AliGSphere::AliGSphere()
27 /* Default Constructor */
28 faX = 1.; // Coeff along Ox
29 faY = 1.; // Coeff along Oy
30 faZ = 1.; // Coeff along Oz
31 fAspectRatio = 1.; // Relation between asumth and grid size (by default 1.0)
32 fCoTab = NULL;// Table of cos(fPhimin) .... cos(Phi)
33 fCoThetaTab = NULL;// Table of sin(gThemin) .... cos(Theta)
35 fNdiv = 0; // number of divisions
36 fNz = 0; // number of sections
37 fPhimax = 0.; // maximum phi
38 fPhimin = 0.; // minimum phi
39 fRmax = 0.; // maximum radius
40 fRmin = 0.; // minimum radius
41 fSiTab = NULL;// Table of sin(fPhimin) .... sin(Phi)
42 fThemax = 0.; // maximum theta
43 fThemin = 0.; // minimum theta
47 // ---------------------------------------------------------------------------
49 AliGSphere::AliGSphere(Text_t *name, Text_t *title, Float_t rmin, Float_t rmax, Float_t themin, Float_t themax, Float_t phimin, Float_t phimax) : AliGShape(name, title)
52 faX = 1.; // Coeff along Ox
53 faY = 1.; // Coeff along Oy
54 faZ = 1.; // Coeff along Oz
55 fAspectRatio = 1.; // Relation between asumth and grid size (by default 1.0)
56 fCoTab = NULL; // Table of cos(fPhimin) .... cos(Phi)
57 fCoThetaTab = NULL; // Table of sin(gThemin) .... cos(Theta)
58 fNdiv = 0; // number of divisions
59 fNz = 0; // number of sections
60 fPhimax = phimax;// maximum phi
61 fPhimin = phimin;// minimum phi
62 fRmax = rmax; // maximum radius
63 fRmin = rmin; // minimum radius
64 fSiTab = NULL; // Table of sin(fPhimin) .... sin(Phi)
65 fThemax = themax;// maximum theta
66 fThemin = themin;// minimum theta
68 SetNumberOfDivisions (20);
71 // ---------------------------------------------------------------------------
73 AliGSphere::AliGSphere(AliGSphere *sphere)
75 /* Copy Constructor */
76 faX = 1.; // Coeff along Ox
77 faY = 1.; // Coeff along Oy
78 faZ = 1.; // Coeff along Oz
79 fAspectRatio = 1.; // Relation between asumth and grid size (by default 1.0)
80 fColor = sphere->fColor;
81 fCoTab = NULL; // Table of cos(fPhimin) .... cos(Phi)
82 fCoThetaTab = NULL; // Table of sin(gThemin) .... cos(Theta)
83 fNdiv = 0; // number of divisions
84 fNz = 0; // number of sections
85 fPhimax = sphere->fPhimax;// maximum phi
86 fPhimin = sphere->fPhimin;// minimum phi
87 fRmax = sphere->fRmax; // maximum radius
88 fRmin = sphere->fRmin; // minimum radius
89 fSiTab = NULL; // Table of sin(fPhimin) .... sin(Phi)
90 fThemax = sphere->fThemax;// maximum theta
91 fThemin = sphere->fThemin;// minimum theta
93 SetNumberOfDivisions (20);
95 // ---------------------------------------------------------------------------
97 AliGSphere::AliGSphere(Text_t *name, Text_t *title, Float_t rmax) : AliGShape(name, title)
99 /* Simplified Constructor */
100 faX = 1.; // Coeff along Ox
101 faY = 1.; // Coeff along Oy
102 faZ = 1.; // Coeff along Oz
103 fAspectRatio = 1.; // Relation between asumth and grid size (by default 1.0)
104 fCoTab = NULL; // Table of cos(fPhimin) .... cos(Phi)
105 fCoThetaTab = NULL; // Table of sin(gThemin) .... cos(Theta)
106 fNdiv = 0; // number of divisions
107 fNz = 0; // number of sections
108 fPhimax = 360.; // maximum phi
109 fPhimin = 0.; // minimum phi
110 fRmax = rmax; // maximum radius
111 fRmin = 0.; // minimum radius
112 fSiTab = NULL; // Table of sin(fPhimin) .... sin(Phi)
113 fThemax = 180.; // maximum theta
114 fThemin = 0.; // minimum theta
116 SetNumberOfDivisions (20);
119 // ---------------------------------------------------------------------------
121 AliGSphere::~AliGSphere() {
123 delete [] fCoThetaTab; // Table of sin(gThemin) .... cos(Theta)
128 // ---------------------------------------------------------------------------
130 void AliGSphere::DrawShape(Option_t *option)
136 //-------------------------------------------------------------------------
138 //void AliGSphere::Draw()
139 void AliGSphere::Draw(Option_t *option)
141 TString opt = option;
145 gPad = new TCanvas("AliGSphere","AliGSphere",0,0,400,300);
146 gPad->Range(0,0,1,1);
147 gPad->SetFillColor(32); // Light Green
148 gPad->SetBorderSize(3);
149 gPad->SetBorderMode(0); // -1 (down) 0 (no) 1 (up)
152 if( !opt.Contains("same") ) {
154 gPad->SetName("AliGSphere");
155 gPad->SetTitle("AliGSphere");
158 gPad->SetName("AliShapes");
159 gPad->SetTitle("AliShapes");
164 TView *view = gPad->GetView();
169 view->SetAutoRange(kTRUE);
171 view->SetAutoRange(kFALSE);
174 // ---------------------------------------------------------------------------
176 void AliGSphere::Paint(Option_t *option)
178 //*-*-*-*-*-*-*-*Paint this 3-D shape with its current attributes*-*-*-*-*-*-*-*
179 //*-* ================================================
181 SetLineColor( GetCol() );
184 const Int_t n = GetNumberOfDivisions()+1;
186 Int_t numpoints = 2*n*nz;
189 if (numpoints <= 0) return;
190 //*-* Allocate memory for points *-*
192 Float_t *points = new Float_t[3*numpoints];
196 if (gPad->GetView3D()) PaintGLPoints(points);
198 //== for (i = 0; i < numpoints; i++)
199 //== gNode->Local2Master(&points[3*i],&points[3*i]);
201 Bool_t specialCase = kFALSE;
203 if (TMath::Abs(TMath::Sin(2*(fPhimax - fPhimin))) <= 0.01) //mark this as a very special case, when
204 specialCase = kTRUE; //we have to draw this PCON like a TUBE
206 X3DBuffer *buff = new X3DBuffer;
208 buff->numPoints = numpoints;
209 buff->numSegs = 4*(nz*n-1+(specialCase == kTRUE));
210 buff->numPolys = 2*(nz*n-1+(specialCase == kTRUE));
213 //*-* Allocate memory for points *-*
215 buff->points = points;
217 Int_t c = ((GetLineColor() % 8) - 1) * 4; // Basic colors: 0, 1, ... 7
220 //*-* Allocate memory for segments *-*
222 Int_t indx, indx2, k;
225 buff->segs = new Int_t[buff->numSegs*3];
228 //inside & outside spheres, number of segments: 2*nz*(n-1)
229 // special case number of segments: 2*nz*n
230 for (i = 0; i < nz*2; i++) {
232 for (j = 1; j < n; j++) {
233 buff->segs[indx++] = c;
234 buff->segs[indx++] = indx2+j-1;
235 buff->segs[indx++] = indx2+j;
238 buff->segs[indx++] = c;
239 buff->segs[indx++] = indx2+j-1;
240 buff->segs[indx++] = indx2;
244 //bottom & top lines, number of segments: 2*n
245 for (i = 0; i < 2; i++) {
246 indx2 = i*(nz-1)*2*n;
247 for (j = 0; j < n; j++) {
248 buff->segs[indx++] = c;
249 buff->segs[indx++] = indx2+j;
250 buff->segs[indx++] = indx2+n+j;
254 //inside & outside spheres, number of segments: 2*(nz-1)*n
255 for (i = 0; i < (nz-1); i++) {
259 for (j = 0; j < n; j++) {
260 buff->segs[indx++] = c+2;
261 buff->segs[indx++] = indx2+j;
262 buff->segs[indx++] = indx2+n*2+j;
266 for (j = 0; j < n; j++) {
267 buff->segs[indx++] = c+3;
268 buff->segs[indx++] = indx2+j;
269 buff->segs[indx++] = indx2+n*2+j;
273 //left & right sections, number of segments: 2*(nz-2)
274 // special case number of segments: 0
275 /*if (!specialCase) {
276 for (i = 1; i < (nz-1); i++) {
277 for (j = 0; j < 2; j++) {
278 buff->segs[indx++] = c;
279 buff->segs[indx++] = 2*i * n + j*(n-1);
280 buff->segs[indx++] = (2*i+1) * n + j*(n-1);
287 Int_t m = n - 1 + (specialCase == kTRUE);
289 //*-* Allocate memory for polygons *-*
293 buff->polys = new Int_t[buff->numPolys*6];
296 //bottom & top, number of polygons: 2*(n-1)
297 // special case number of polygons: 2*n
298 for (i = 0; i < 2; i++) {
299 for (j = 0; j < n-1; j++) {
300 buff->polys[indx++] = c+3;
301 buff->polys[indx++] = 4;
302 buff->polys[indx++] = 2*nz*m+i*n+j;
303 buff->polys[indx++] = i*(nz*2-2)*m+m+j;
304 buff->polys[indx++] = 2*nz*m+i*n+j+1;
305 buff->polys[indx++] = i*(nz*2-2)*m+j;
308 buff->polys[indx++] = c+3;
309 buff->polys[indx++] = 4;
310 buff->polys[indx++] = 2*nz*m+i*n+j;
311 buff->polys[indx++] = i*(nz*2-2)*m+m+j;
312 buff->polys[indx++] = 2*nz*m+i*n;
313 buff->polys[indx++] = i*(nz*2-2)*m+j;
318 //inside & outside, number of polygons: (nz-1)*2*(n-1)
319 for (k = 0; k < (nz-1); k++) {
320 for (i = 0; i < 2; i++) {
321 for (j = 0; j < n-1; j++) {
322 buff->polys[indx++] = c+i;
323 buff->polys[indx++] = 4;
324 buff->polys[indx++] = (2*k+i*1)*m+j;
325 buff->polys[indx++] = nz*2*m+(2*k+i*1+2)*n+j;
326 buff->polys[indx++] = (2*k+i*1+2)*m+j;
327 buff->polys[indx++] = nz*2*m+(2*k+i*1+2)*n+j+1;
330 buff->polys[indx++] = c+i;
331 buff->polys[indx++] = 4;
332 buff->polys[indx++] = (2*k+i*1)*m+j;
333 buff->polys[indx++] = nz*2*m+(2*k+i*1+2)*n+j;
334 buff->polys[indx++] = (2*k+i*1+2)*m+j;
335 buff->polys[indx++] = nz*2*m+(2*k+i*1+2)*n;
340 //left & right sections, number of polygons: 2*(nz-1)
341 // special case number of polygons: 0
342 /*if (!specialCase) {
344 for (k = 0; k < (nz-1); k++) {
345 for (i = 0; i < 2; i++) {
346 buff->polys[indx++] = c+2;
347 buff->polys[indx++] = 4;
348 buff->polys[indx++] = k==0 ? indx2+i*(n-1) : indx2+2*nz*n+2*(k-1)+i;
349 buff->polys[indx++] = indx2+2*(k+1)*n+i*(n-1);
350 buff->polys[indx++] = indx2+2*nz*n+2*k+i;
351 buff->polys[indx++] = indx2+(2*k+3)*n+i*(n-1);
354 buff->polys[indx-8] = indx2+n;
355 buff->polys[indx-2] = indx2+2*n-1;
359 //*-* Paint in the pad
360 //*-* Paint in the pad
361 Bool_t rangeView = strcmp(option,"range")==0 ? kTRUE : kFALSE;
362 PaintShape(buff,rangeView);
365 if (strstr(option, "x3d")) {
366 if(buff && buff->points && buff->segs)
369 gSize3D.numPoints -= buff->numPoints;
370 gSize3D.numSegs -= buff->numSegs;
371 gSize3D.numPolys -= buff->numPolys;
376 if (buff->segs) delete [] buff->segs;
377 if (buff->polys) delete [] buff->polys;
378 if (buff) delete buff;
384 // ---------------------------------------------------------------------------
386 void AliGSphere::SetEllipse(Float_t *factors)
388 if (factors[0] > 0) faX = factors[0];
389 if (factors[1] > 0) faY = factors[1];
390 if (factors[2] > 0) faZ = factors[2];
394 // ---------------------------------------------------------------------------
396 void AliGSphere::SetNumberOfDivisions (Int_t p)
398 if (GetNumberOfDivisions () == p)
401 fNz = Int_t(fAspectRatio*fNdiv*(fThemax - fThemin )/(fPhimax - fPhimin )) + 1;
405 // ---------------------------------------------------------------------------
407 void AliGSphere::SetPoints(Float_t *buff)
409 //*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*Create SPHE points*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
410 //*-* ==================
415 Int_t n = GetNumberOfDivisions()+1;
417 //*-* We've to check whether the table does exist and create it
418 //*-* since fCoTab/fSiTab are not saved with any TShape::Streamer function
419 if (!fCoTab) MakeTableOfCoSin();
422 for (i = 0; i < fNz+1; i++)
424 z = fRmin * fCoThetaTab[i]; // fSinPhiTab[i];
425 Float_t sithet = TMath::Sqrt(TMath::Abs(1-fCoThetaTab[i]*fCoThetaTab[i]));
426 Float_t zi = fRmin*sithet;
427 for (j = 0; j < n; j++)
429 buff[indx++] = zi * fCoTab[j];
430 buff[indx++] = zi * fSiTab[j];
433 z = fRmax * fCoThetaTab[i];
435 for (j = 0; j < n; j++)
437 buff[indx++] = zi * fCoTab[j];
438 buff[indx++] = zi * fSiTab[j];
445 // ---------------------------------------------------------------------------
447 void AliGSphere::MakeTableOfCoSin()
449 const Double_t PI = TMath::ATan(1) * 4.0;
450 const Double_t ragrad = PI/180.0;
452 Float_t dphi = fPhimax - fPhimin;
453 while (dphi > 360) dphi -= 360;
455 Float_t dtet = fThemax - fThemin;
456 while (dtet > 180) dtet -= 180;
459 Int_t n = GetNumberOfDivisions () + 1;
461 delete [] fCoTab; // Delete the old tab if any
462 fCoTab = new Double_t [n];
463 if (!fCoTab ) return;
466 delete [] fSiTab; // Delete the old tab if any
467 fSiTab = new Double_t [n];
468 if (!fSiTab ) return;
470 Double_t range = Double_t(dphi * ragrad);
471 Double_t phi1 = Double_t(fPhimin * ragrad);
472 Double_t angstep = range/(n-1);
475 for (j = 0; j < n; j++)
477 ph = phi1 + j*angstep;
478 fCoTab[j] = TMath::Cos(ph);
479 fSiTab[j] = TMath::Sin(ph);
485 delete [] fCoThetaTab; // Delete the old tab if any
486 fCoThetaTab = new Double_t [n];
487 if (!fCoThetaTab ) return;
489 range = Double_t(dtet * ragrad);
490 phi1 = Double_t(fThemin * ragrad);
491 angstep = range/(n-1);
494 for (j = 0; j < n; j++)
496 fCoThetaTab[n-j-1] = TMath::Cos(ph);
502 // ---------------------------------------------------------------------------
504 void AliGSphere::PaintGLPoints(Float_t *vertex)
506 gGLKernel->PaintCone(vertex,-(GetNumberOfDivisions()+1),fNz+1);
509 // ---------------------------------------------------------------------------
511 void AliGSphere::Sizeof3D() const
513 //*-*-*-*-*-*-*Return total X3D size of this shape with its attributes*-*-*-*-*-*
514 //*-* =======================================================
516 cout << " Entra en AliGSphere::Sizeof3D() " << endl;
520 n = GetNumberOfDivisions()+1;
523 //cout << " n = " << n << " y nz = " << nz << endl;
525 Bool_t specialCase = kFALSE;
527 if (TMath::Abs(TMath::Sin(2*(fPhimax - fPhimin))) <= 0.01) //mark this as a very special case, when
528 specialCase = kTRUE; //we have to draw this PCON like a TUBE
530 gSize3D.numPoints += 2*n*nz;
531 gSize3D.numSegs += 4*(nz*n-1+(specialCase == kTRUE));
532 gSize3D.numPolys += 2*(nz*n-1+(specialCase == kTRUE));
535 // ---------------------------------------------------------------------------
537 void AliGSphere::Streamer(TBuffer &R__b)
539 // Stream an object of class AliGSphere.
541 if (R__b.IsReading()) {
542 Version_t R__v = R__b.ReadVersion(); if (R__v) { }
543 AliGShape::Streamer(R__b);
544 R__b >> fAspectRatio;
545 R__b.ReadArray(fCoTab); //
546 R__b.ReadArray(fCoThetaTab); //
549 R__b.ReadArray(fSiTab); //
560 R__b.WriteVersion(AliGSphere::IsA());
561 AliGShape::Streamer(R__b);
562 R__b << fAspectRatio;
563 R__b.WriteArray(fCoTab, GetNumberOfDivisions()+1); //
564 R__b.WriteArray(fCoThetaTab, fNz+1); //
567 R__b.WriteArray(fSiTab, GetNumberOfDivisions()+1); //
580 // ---------------------------------------------------------------------------