1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
7 * Permission to use, copy, modify and distribute this software and its *
8 * documentation strictly for non-commercial purposes is hereby granted *
9 * without fee, provided that the above copyright notice appears in all *
10 * copies and that both the copyright notice and this permission notice *
11 * appear in the supporting documentation. The authors make no claims *
12 * about the suitability of this software for any purpose. It is *
13 * provided "as is" without express or implied warranty. *
14 **************************************************************************/
23 // ---------------------------------------------------------------------------
27 // This file is part of the ALICE Geometry Database .
29 // Author: Joana E. Santo
31 // ---------------------------------------------------------------------------
34 #include <TVirtualPad.h>
37 #include <TGLKernelABC.h>
39 #include "AliGSphere.h"
44 AliGSphere::AliGSphere()
46 /* Default Constructor */
47 faX = 1.; // Coeff along Ox
48 faY = 1.; // Coeff along Oy
49 faZ = 1.; // Coeff along Oz
50 fAspectRatio = 1.; // Relation between asumth and grid size (by default 1.0)
51 fCoTab = NULL;// Table of cos(fPhimin) .... cos(Phi)
52 fCoThetaTab = NULL;// Table of sin(gThemin) .... cos(Theta)
54 fNdiv = 0; // number of divisions
55 fNz = 0; // number of sections
56 fPhimax = 0.; // maximum phi
57 fPhimin = 0.; // minimum phi
58 fRmax = 0.; // maximum radius
59 fRmin = 0.; // minimum radius
60 fSiTab = NULL;// Table of sin(fPhimin) .... sin(Phi)
61 fThemax = 0.; // maximum theta
62 fThemin = 0.; // minimum theta
66 // ---------------------------------------------------------------------------
68 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)
71 faX = 1.; // Coeff along Ox
72 faY = 1.; // Coeff along Oy
73 faZ = 1.; // Coeff along Oz
74 fAspectRatio = 1.; // Relation between asumth and grid size (by default 1.0)
75 fCoTab = NULL; // Table of cos(fPhimin) .... cos(Phi)
76 fCoThetaTab = NULL; // Table of sin(gThemin) .... cos(Theta)
77 fNdiv = 0; // number of divisions
78 fNz = 0; // number of sections
79 fPhimax = phimax;// maximum phi
80 fPhimin = phimin;// minimum phi
81 fRmax = rmax; // maximum radius
82 fRmin = rmin; // minimum radius
83 fSiTab = NULL; // Table of sin(fPhimin) .... sin(Phi)
84 fThemax = themax;// maximum theta
85 fThemin = themin;// minimum theta
87 SetNumberOfDivisions (20);
90 // ---------------------------------------------------------------------------
92 AliGSphere::AliGSphere(AliGSphere *sphere)
94 /* Copy Constructor */
95 faX = 1.; // Coeff along Ox
96 faY = 1.; // Coeff along Oy
97 faZ = 1.; // Coeff along Oz
98 fAspectRatio = 1.; // Relation between asumth and grid size (by default 1.0)
99 fColor = sphere->fColor;
100 fCoTab = NULL; // Table of cos(fPhimin) .... cos(Phi)
101 fCoThetaTab = NULL; // Table of sin(gThemin) .... cos(Theta)
102 fNdiv = 0; // number of divisions
103 fNz = 0; // number of sections
104 fPhimax = sphere->fPhimax;// maximum phi
105 fPhimin = sphere->fPhimin;// minimum phi
106 fRmax = sphere->fRmax; // maximum radius
107 fRmin = sphere->fRmin; // minimum radius
108 fSiTab = NULL; // Table of sin(fPhimin) .... sin(Phi)
109 fThemax = sphere->fThemax;// maximum theta
110 fThemin = sphere->fThemin;// minimum theta
112 SetNumberOfDivisions (20);
114 // ---------------------------------------------------------------------------
116 AliGSphere::AliGSphere(Text_t *name, Text_t *title, Float_t rmax) : AliGShape(name, title)
118 /* Simplified Constructor */
119 faX = 1.; // Coeff along Ox
120 faY = 1.; // Coeff along Oy
121 faZ = 1.; // Coeff along Oz
122 fAspectRatio = 1.; // Relation between asumth and grid size (by default 1.0)
123 fCoTab = NULL; // Table of cos(fPhimin) .... cos(Phi)
124 fCoThetaTab = NULL; // Table of sin(gThemin) .... cos(Theta)
125 fNdiv = 0; // number of divisions
126 fNz = 0; // number of sections
127 fPhimax = 360.; // maximum phi
128 fPhimin = 0.; // minimum phi
129 fRmax = rmax; // maximum radius
130 fRmin = 0.; // minimum radius
131 fSiTab = NULL; // Table of sin(fPhimin) .... sin(Phi)
132 fThemax = 180.; // maximum theta
133 fThemin = 0.; // minimum theta
135 SetNumberOfDivisions (20);
138 // ---------------------------------------------------------------------------
140 AliGSphere::~AliGSphere() {
142 delete [] fCoThetaTab; // Table of sin(gThemin) .... cos(Theta)
147 // ---------------------------------------------------------------------------
149 void AliGSphere::DrawShape(Option_t *option)
155 //-------------------------------------------------------------------------
157 //void AliGSphere::Draw()
158 void AliGSphere::Draw(Option_t *option)
160 TString opt = option;
164 gPad = new TCanvas("AliGSphere","AliGSphere",0,0,400,300);
165 gPad->Range(0,0,1,1);
166 gPad->SetFillColor(32); // Light Green
167 gPad->SetBorderSize(3);
168 gPad->SetBorderMode(0); // -1 (down) 0 (no) 1 (up)
171 if( !opt.Contains("same") ) {
173 gPad->SetName("AliGSphere");
174 gPad->SetTitle("AliGSphere");
177 gPad->SetName("AliShapes");
178 gPad->SetTitle("AliShapes");
183 TView *view = gPad->GetView();
188 view->SetAutoRange(kTRUE);
190 view->SetAutoRange(kFALSE);
193 // ---------------------------------------------------------------------------
195 void AliGSphere::Paint(Option_t *option)
197 //*-*-*-*-*-*-*-*Paint this 3-D shape with its current attributes*-*-*-*-*-*-*-*
198 //*-* ================================================
200 SetLineColor( GetCol() );
203 const Int_t n = GetNumberOfDivisions()+1;
205 Int_t numpoints = 2*n*nz;
208 if (numpoints <= 0) return;
209 //*-* Allocate memory for points *-*
211 Float_t *points = new Float_t[3*numpoints];
215 if (gPad->GetView3D()) PaintGLPoints(points);
217 //== for (i = 0; i < numpoints; i++)
218 //== gNode->Local2Master(&points[3*i],&points[3*i]);
220 Bool_t specialCase = kFALSE;
222 if (TMath::Abs(TMath::Sin(2*(fPhimax - fPhimin))) <= 0.01) //mark this as a very special case, when
223 specialCase = kTRUE; //we have to draw this PCON like a TUBE
225 X3DBuffer *buff = new X3DBuffer;
227 buff->numPoints = numpoints;
228 buff->numSegs = 4*(nz*n-1+(specialCase == kTRUE));
229 buff->numPolys = 2*(nz*n-1+(specialCase == kTRUE));
232 //*-* Allocate memory for points *-*
234 buff->points = points;
236 Int_t c = ((GetLineColor() % 8) - 1) * 4; // Basic colors: 0, 1, ... 7
239 //*-* Allocate memory for segments *-*
241 Int_t indx, indx2, k;
244 buff->segs = new Int_t[buff->numSegs*3];
247 //inside & outside spheres, number of segments: 2*nz*(n-1)
248 // special case number of segments: 2*nz*n
249 for (i = 0; i < nz*2; i++) {
251 for (j = 1; j < n; j++) {
252 buff->segs[indx++] = c;
253 buff->segs[indx++] = indx2+j-1;
254 buff->segs[indx++] = indx2+j;
257 buff->segs[indx++] = c;
258 buff->segs[indx++] = indx2+j-1;
259 buff->segs[indx++] = indx2;
263 //bottom & top lines, number of segments: 2*n
264 for (i = 0; i < 2; i++) {
265 indx2 = i*(nz-1)*2*n;
266 for (j = 0; j < n; j++) {
267 buff->segs[indx++] = c;
268 buff->segs[indx++] = indx2+j;
269 buff->segs[indx++] = indx2+n+j;
273 //inside & outside spheres, number of segments: 2*(nz-1)*n
274 for (i = 0; i < (nz-1); i++) {
278 for (j = 0; j < n; j++) {
279 buff->segs[indx++] = c+2;
280 buff->segs[indx++] = indx2+j;
281 buff->segs[indx++] = indx2+n*2+j;
285 for (j = 0; j < n; j++) {
286 buff->segs[indx++] = c+3;
287 buff->segs[indx++] = indx2+j;
288 buff->segs[indx++] = indx2+n*2+j;
292 //left & right sections, number of segments: 2*(nz-2)
293 // special case number of segments: 0
294 /*if (!specialCase) {
295 for (i = 1; i < (nz-1); i++) {
296 for (j = 0; j < 2; j++) {
297 buff->segs[indx++] = c;
298 buff->segs[indx++] = 2*i * n + j*(n-1);
299 buff->segs[indx++] = (2*i+1) * n + j*(n-1);
306 Int_t m = n - 1 + (specialCase == kTRUE);
308 //*-* Allocate memory for polygons *-*
312 buff->polys = new Int_t[buff->numPolys*6];
315 //bottom & top, number of polygons: 2*(n-1)
316 // special case number of polygons: 2*n
317 for (i = 0; i < 2; i++) {
318 for (j = 0; j < n-1; j++) {
319 buff->polys[indx++] = c+3;
320 buff->polys[indx++] = 4;
321 buff->polys[indx++] = 2*nz*m+i*n+j;
322 buff->polys[indx++] = i*(nz*2-2)*m+m+j;
323 buff->polys[indx++] = 2*nz*m+i*n+j+1;
324 buff->polys[indx++] = i*(nz*2-2)*m+j;
327 buff->polys[indx++] = c+3;
328 buff->polys[indx++] = 4;
329 buff->polys[indx++] = 2*nz*m+i*n+j;
330 buff->polys[indx++] = i*(nz*2-2)*m+m+j;
331 buff->polys[indx++] = 2*nz*m+i*n;
332 buff->polys[indx++] = i*(nz*2-2)*m+j;
337 //inside & outside, number of polygons: (nz-1)*2*(n-1)
338 for (k = 0; k < (nz-1); k++) {
339 for (i = 0; i < 2; i++) {
340 for (j = 0; j < n-1; j++) {
341 buff->polys[indx++] = c+i;
342 buff->polys[indx++] = 4;
343 buff->polys[indx++] = (2*k+i*1)*m+j;
344 buff->polys[indx++] = nz*2*m+(2*k+i*1+2)*n+j;
345 buff->polys[indx++] = (2*k+i*1+2)*m+j;
346 buff->polys[indx++] = nz*2*m+(2*k+i*1+2)*n+j+1;
349 buff->polys[indx++] = c+i;
350 buff->polys[indx++] = 4;
351 buff->polys[indx++] = (2*k+i*1)*m+j;
352 buff->polys[indx++] = nz*2*m+(2*k+i*1+2)*n+j;
353 buff->polys[indx++] = (2*k+i*1+2)*m+j;
354 buff->polys[indx++] = nz*2*m+(2*k+i*1+2)*n;
359 //left & right sections, number of polygons: 2*(nz-1)
360 // special case number of polygons: 0
361 /*if (!specialCase) {
363 for (k = 0; k < (nz-1); k++) {
364 for (i = 0; i < 2; i++) {
365 buff->polys[indx++] = c+2;
366 buff->polys[indx++] = 4;
367 buff->polys[indx++] = k==0 ? indx2+i*(n-1) : indx2+2*nz*n+2*(k-1)+i;
368 buff->polys[indx++] = indx2+2*(k+1)*n+i*(n-1);
369 buff->polys[indx++] = indx2+2*nz*n+2*k+i;
370 buff->polys[indx++] = indx2+(2*k+3)*n+i*(n-1);
373 buff->polys[indx-8] = indx2+n;
374 buff->polys[indx-2] = indx2+2*n-1;
378 //*-* Paint in the pad
379 //*-* Paint in the pad
380 Bool_t rangeView = strcmp(option,"range")==0 ? kTRUE : kFALSE;
381 PaintShape(buff,rangeView);
384 if (strstr(option, "x3d")) {
385 if(buff && buff->points && buff->segs)
388 gSize3D.numPoints -= buff->numPoints;
389 gSize3D.numSegs -= buff->numSegs;
390 gSize3D.numPolys -= buff->numPolys;
395 if (buff->segs) delete [] buff->segs;
396 if (buff->polys) delete [] buff->polys;
397 if (buff) delete buff;
403 // ---------------------------------------------------------------------------
405 void AliGSphere::SetEllipse(Float_t *factors)
407 if (factors[0] > 0) faX = factors[0];
408 if (factors[1] > 0) faY = factors[1];
409 if (factors[2] > 0) faZ = factors[2];
413 // ---------------------------------------------------------------------------
415 void AliGSphere::SetNumberOfDivisions (Int_t p)
417 if (GetNumberOfDivisions () == p)
420 fNz = Int_t(fAspectRatio*fNdiv*(fThemax - fThemin )/(fPhimax - fPhimin )) + 1;
424 // ---------------------------------------------------------------------------
426 void AliGSphere::SetPoints(Float_t *buff)
428 //*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*Create SPHE points*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
429 //*-* ==================
434 Int_t n = GetNumberOfDivisions()+1;
436 //*-* We've to check whether the table does exist and create it
437 //*-* since fCoTab/fSiTab are not saved with any TShape::Streamer function
438 if (!fCoTab) MakeTableOfCoSin();
441 for (i = 0; i < fNz+1; i++)
443 z = fRmin * fCoThetaTab[i]; // fSinPhiTab[i];
444 Float_t sithet = TMath::Sqrt(TMath::Abs(1-fCoThetaTab[i]*fCoThetaTab[i]));
445 Float_t zi = fRmin*sithet;
446 for (j = 0; j < n; j++)
448 buff[indx++] = zi * fCoTab[j];
449 buff[indx++] = zi * fSiTab[j];
452 z = fRmax * fCoThetaTab[i];
454 for (j = 0; j < n; j++)
456 buff[indx++] = zi * fCoTab[j];
457 buff[indx++] = zi * fSiTab[j];
464 // ---------------------------------------------------------------------------
466 void AliGSphere::MakeTableOfCoSin()
468 const Double_t PI = TMath::ATan(1) * 4.0;
469 const Double_t ragrad = PI/180.0;
471 Float_t dphi = fPhimax - fPhimin;
472 while (dphi > 360) dphi -= 360;
474 Float_t dtet = fThemax - fThemin;
475 while (dtet > 180) dtet -= 180;
478 Int_t n = GetNumberOfDivisions () + 1;
480 delete [] fCoTab; // Delete the old tab if any
481 fCoTab = new Double_t [n];
482 if (!fCoTab ) return;
485 delete [] fSiTab; // Delete the old tab if any
486 fSiTab = new Double_t [n];
487 if (!fSiTab ) return;
489 Double_t range = Double_t(dphi * ragrad);
490 Double_t phi1 = Double_t(fPhimin * ragrad);
491 Double_t angstep = range/(n-1);
494 for (j = 0; j < n; j++)
496 ph = phi1 + j*angstep;
497 fCoTab[j] = TMath::Cos(ph);
498 fSiTab[j] = TMath::Sin(ph);
504 delete [] fCoThetaTab; // Delete the old tab if any
505 fCoThetaTab = new Double_t [n];
506 if (!fCoThetaTab ) return;
508 range = Double_t(dtet * ragrad);
509 phi1 = Double_t(fThemin * ragrad);
510 angstep = range/(n-1);
513 for (j = 0; j < n; j++)
515 fCoThetaTab[n-j-1] = TMath::Cos(ph);
521 // ---------------------------------------------------------------------------
523 void AliGSphere::PaintGLPoints(Float_t *vertex)
525 gGLKernel->PaintCone(vertex,-(GetNumberOfDivisions()+1),fNz+1);
528 // ---------------------------------------------------------------------------
530 void AliGSphere::Sizeof3D() const
532 //*-*-*-*-*-*-*Return total X3D size of this shape with its attributes*-*-*-*-*-*
533 //*-* =======================================================
535 cout << " Entra en AliGSphere::Sizeof3D() " << endl;
539 n = GetNumberOfDivisions()+1;
542 //cout << " n = " << n << " y nz = " << nz << endl;
544 Bool_t specialCase = kFALSE;
546 if (TMath::Abs(TMath::Sin(2*(fPhimax - fPhimin))) <= 0.01) //mark this as a very special case, when
547 specialCase = kTRUE; //we have to draw this PCON like a TUBE
549 gSize3D.numPoints += 2*n*nz;
550 gSize3D.numSegs += 4*(nz*n-1+(specialCase == kTRUE));
551 gSize3D.numPolys += 2*(nz*n-1+(specialCase == kTRUE));
554 // ---------------------------------------------------------------------------
556 void AliGSphere::Streamer(TBuffer &R__b)
558 // Stream an object of class AliGSphere.
560 if (R__b.IsReading()) {
561 Version_t R__v = R__b.ReadVersion(); if (R__v) { }
562 AliGShape::Streamer(R__b);
563 R__b >> fAspectRatio;
564 R__b.ReadArray(fCoTab); //
565 R__b.ReadArray(fCoThetaTab); //
568 R__b.ReadArray(fSiTab); //
579 R__b.WriteVersion(AliGSphere::IsA());
580 AliGShape::Streamer(R__b);
581 R__b << fAspectRatio;
582 R__b.WriteArray(fCoTab, GetNumberOfDivisions()+1); //
583 R__b.WriteArray(fCoThetaTab, fNz+1); //
586 R__b.WriteArray(fSiTab, GetNumberOfDivisions()+1); //
599 // ---------------------------------------------------------------------------