ROOT  6.06/09
Reference Guide
TSPHE.cxx
Go to the documentation of this file.
1 // @(#)root/g3d:$Id$
2 // Author: Rene Brun 13/06/97
3 
4 /*************************************************************************
5  * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. *
6  * All rights reserved. *
7  * *
8  * For the licensing terms see $ROOTSYS/LICENSE. *
9  * For the list of contributors see $ROOTSYS/README/CREDITS. *
10  *************************************************************************/
11 
12 #include "TSPHE.h"
13 #include "TNode.h"
14 #include "TVirtualPad.h"
15 #include "TBuffer3D.h"
16 #include "TBuffer3DTypes.h"
17 #include "TGeometry.h"
18 #include "TClass.h"
19 #include "TMath.h"
20 
22 
23 /** \class TSPHE
24 \ingroup g3d
25 A Sphere.
26 
27 It has 9 parameters:
28 
29  - name: name of the shape
30  - title: shape's title
31  - material: (see TMaterial)
32  - rmin: minimum radius
33  - rmax: maximum radius
34  - themin: theta min
35  - themax: theta max
36  - phimin: phi min
37  - phimax: phi max
38 
39 ROOT color indx = max(i-i0,j-j0);
40 */
41 
42 ////////////////////////////////////////////////////////////////////////////////
43 /// SPHE shape default constructor
44 
45 TSPHE::TSPHE()
46 {
47  fRmin = 0;
48  fRmax = 0;
49  fThemin = 0;
50  fThemax = 0;
51  fPhimin = 0;
52  fPhimax = 0;
53  fSiTab = 0;
54  fCoTab = 0;
55  fCoThetaTab = 0;
56  fNdiv = 0;
57  fAspectRatio=1.0;
58  faX = faY = faZ = 1.0; // Coeff along Ox
59  fNz = 0;
60 }
61 
62 ////////////////////////////////////////////////////////////////////////////////
63 /// SPHE shape normal constructor
64 
65 TSPHE::TSPHE(const char *name, const char *title, const char *material, Float_t rmin, Float_t rmax, Float_t themin,
66  Float_t themax, Float_t phimin, Float_t phimax)
67  : TShape(name, title,material)
68 {
69  fRmin = rmin;
70  fRmax = rmax;
71  fThemin = themin;
72  fThemax = themax;
73  fPhimin = phimin;
74  fPhimax = phimax;
75 
76  fSiTab = 0;
77  fCoTab = 0;
78  fCoThetaTab = 0;
79  fNdiv = 0;
80 
81  fAspectRatio=1.0;
82  faX = faY = faZ = 1.0; // Coeff along Ox
83 
85 }
86 
87 ////////////////////////////////////////////////////////////////////////////////
88 /// SPHE shape "simplified" constructor
89 
90 TSPHE::TSPHE(const char *name, const char *title, const char *material, Float_t rmax)
91  : TShape(name, title,material)
92 {
93  fRmin = 0;
94  fRmax = rmax;
95  fThemin = 0;
96  fThemax = 180;
97  fPhimin = 0;
98  fPhimax = 360;
99 
100  fSiTab = 0;
101  fCoTab = 0;
102  fCoThetaTab = 0;
103  fNdiv = 0;
104 
105  fAspectRatio=1.0;
106  faX = faY = faZ = 1.0; // Coeff along Ox
107 
109 }
110 
111 ////////////////////////////////////////////////////////////////////////////////
112 /// SPHE shape default destructor
113 
115 {
116  if (fCoThetaTab) delete [] fCoThetaTab;
117  if (fSiTab) delete [] fSiTab;
118  if (fCoTab) delete [] fCoTab;
119 
120  fCoTab = 0;
121  fSiTab = 0;
122  fCoThetaTab=0;
123 }
124 
125 ////////////////////////////////////////////////////////////////////////////////
126 /// Compute distance from point px,py to a PSPHE
127 ///
128 /// Compute the closest distance of approach from point px,py to each
129 /// computed outline point of the PSPHE (stolen from PCON).
130 
132 {
134  Int_t numPoints = 2*n*(fNz+1);
135  return ShapeDistancetoPrimitive(numPoints,px,py);
136 }
137 
138 ////////////////////////////////////////////////////////////////////////////////
139 /// Set ellipse.
140 
141 void TSPHE::SetEllipse(const Float_t *factors)
142 {
143  if (factors[0] > 0) faX = factors[0];
144  if (factors[1] > 0) faY = factors[1];
145  if (factors[2] > 0) faZ = factors[2];
146 }
147 
148 ////////////////////////////////////////////////////////////////////////////////
149 /// Set number of divisions.
150 
152 {
153  if (GetNumberOfDivisions () == p) return;
154  fNdiv=p;
155  fNz = Int_t(fAspectRatio*fNdiv*(fThemax - fThemin )/(fPhimax - fPhimin )) + 1;
157 }
158 
159 ////////////////////////////////////////////////////////////////////////////////
160 /// Create SPHE points
161 
163 {
164  Int_t i, j, n;
165  Int_t indx = 0;
166 
167  n = GetNumberOfDivisions()+1;
168 
169  if (points) {
170  if (!fCoTab) MakeTableOfCoSin();
171  Float_t z;
172  for (i = 0; i < fNz+1; i++) {
173  z = fRmin * fCoThetaTab[i]; // fSinPhiTab[i];
174  Float_t sithet = TMath::Sqrt(TMath::Abs(1-fCoThetaTab[i]*fCoThetaTab[i]));
175  Float_t zi = fRmin*sithet;
176  for (j = 0; j < n; j++) {
177  points[indx++] = faX*zi * fCoTab[j];
178  points[indx++] = faY*zi * fSiTab[j];
179  points[indx++] = faZ*z;
180  }
181  z = fRmax * fCoThetaTab[i];
182  zi = fRmax*sithet;
183  for (j = 0; j < n; j++) {
184  points[indx++] = faX*zi * fCoTab[j];
185  points[indx++] = faY*zi * fSiTab[j];
186  points[indx++] = faZ*z;
187  }
188  }
189  }
190 }
191 
192 ////////////////////////////////////////////////////////////////////////////////
193 /// Return total X3D needed by TNode::ls (when called with option "x")
194 
195 void TSPHE::Sizeof3D() const
196 {
197  Int_t n;
198 
199  n = GetNumberOfDivisions()+1;
200  Int_t nz = fNz+1;
201  Bool_t specialCase = kFALSE;
202 
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
205 
206  gSize3D.numPoints += 2*n*nz;
207  gSize3D.numSegs += 4*(nz*n-1+(specialCase == kTRUE));
208  gSize3D.numPolys += 2*(nz*n-1+(specialCase == kTRUE));
209 }
210 
211 ////////////////////////////////////////////////////////////////////////////////
212 /// Make table of sine and cosine.
213 
215 {
216  const Double_t pi = TMath::ATan(1) * 4.0;
217  const Double_t ragrad = pi/180.0;
218 
219  Float_t dphi = fPhimax - fPhimin;
220  while (dphi > 360) dphi -= 360;
221 
222  Float_t dtet = fThemax - fThemin;
223  while (dtet > 180) dtet -= 180;
224 
225  Int_t j;
226  Int_t n = GetNumberOfDivisions () + 1;
227  if (fCoTab)
228  delete [] fCoTab; // Delete the old tab if any
229  fCoTab = new Double_t [n];
230  if (!fCoTab ) return;
231 
232  if (fSiTab)
233  delete [] fSiTab; // Delete the old tab if any
234  fSiTab = new Double_t [n];
235  if (!fSiTab ) return;
236 
237  Double_t range = Double_t(dphi * ragrad);
238  Double_t phi1 = Double_t(fPhimin * ragrad);
239  Double_t angstep = range/(n-1);
240 
241  Double_t ph = phi1;
242  for (j = 0; j < n; j++)
243  {
244  ph = phi1 + j*angstep;
245  fCoTab[j] = TMath::Cos(ph);
246  fSiTab[j] = TMath::Sin(ph);
247  }
248 
249  n = fNz + 1;
250 
251  if (fCoThetaTab)
252  delete [] fCoThetaTab; // Delete the old tab if any
253  fCoThetaTab = new Double_t [n];
254  if (!fCoThetaTab ) return;
255 
256  range = Double_t(dtet * ragrad);
257  phi1 = Double_t(fThemin * ragrad);
258  angstep = range/(n-1);
259 
260  ph = phi1;
261  for (j = 0; j < n; j++)
262  {
263  fCoThetaTab[n-j-1] = TMath::Cos(ph);
264  ph += angstep;
265  }
266 
267 }
268 
269 ////////////////////////////////////////////////////////////////////////////////
270 /// Stream a class object
271 
272 void TSPHE::Streamer(TBuffer &b)
273 {
274  if (b.IsReading()) {
275  UInt_t R__s, R__c;
276  Version_t R__v = b.ReadVersion(&R__s, &R__c);
277  if (R__v > 2) {
278  b.ReadClassBuffer(TSPHE::Class(), this, R__v, R__s, R__c);
279  Int_t ndiv = fNdiv;
280  fNdiv = 0;
281  SetNumberOfDivisions (ndiv);
282  return;
283  }
284  //====process old versions before automatic schema evolution
285  TShape::Streamer(b);
286  b >> fRmin; // minimum radius
287  b >> fRmax; // maximum radius
288  b >> fThemin; // minimum theta
289  b >> fThemax; // maximum theta
290  b >> fPhimin; // minimum phi
291  b >> fPhimax; // maximum phi
292  Int_t tNdiv; // XXX added by RvdE XXX (fNdiv is set by SetNumberOfDivisions)
293  b >> tNdiv;
294  if (R__v > 1) {
295  b >> faX;
296  b >> faY;
297  b >> faZ;
298  }
299  SetNumberOfDivisions (tNdiv); // XXX added by RvdE
300  b.CheckByteCount(R__s, R__c, TSPHE::IsA());
301  //====end of old versions
302 
303  } else {
304  b.WriteClassBuffer(TSPHE::Class(),this);
305  }
306 }
307 
308 ////////////////////////////////////////////////////////////////////////////////
309 /// Get buffer 3d.
310 
311 const TBuffer3D & TSPHE::GetBuffer3D(Int_t reqSections) const
312 {
313  static TBuffer3D buffer(TBuffer3DTypes::kGeneric);
314 
315  TShape::FillBuffer3D(buffer, reqSections);
316 
317  // Needed by kRawSizes / kRaw
318  const Int_t n = GetNumberOfDivisions()+1;
319  const Int_t nz = fNz+1;
320  Bool_t specialCase = (TMath::Abs(TMath::Sin(2*(fPhimax - fPhimin))) <= 0.01);
321 
322  if (reqSections & TBuffer3D::kRawSizes) {
323  Int_t nbPnts = 2*n*nz;
324  Int_t nbSegs = 4*(nz*n-1+(specialCase == kTRUE));
325  Int_t nbPols = 2*(nz*n-1+(specialCase == kTRUE));
326  if (buffer.SetRawSizes(nbPnts, 3*nbPnts, nbSegs, 3*nbSegs, nbPols, 6*nbPols)) {
327  buffer.SetSectionsValid(TBuffer3D::kRawSizes);
328  }
329  }
330  if ((reqSections & TBuffer3D::kRaw) && buffer.SectionsValid(TBuffer3D::kRawSizes)) {
331  // Points
332  SetPoints(buffer.fPnts);
333  if (!buffer.fLocalFrame) {
334  TransformPoints(buffer.fPnts, buffer.NbPnts());
335  }
336 
337  Int_t c = GetBasicColor();
338 
339  // Segments
340  Int_t indx = 0;
341  Int_t indx2 = 0;
342  Int_t i, j, k;
343  //inside & outside spheres, number of segments: 2*nz*(n-1)
344  // special case number of segments: 2*nz*n
345  for (i = 0; i < nz*2; i++) {
346  indx2 = i*n;
347  for (j = 1; j < n; j++) {
348  buffer.fSegs[indx++] = c;
349  buffer.fSegs[indx++] = indx2+j-1;
350  buffer.fSegs[indx++] = indx2+j;
351  }
352  if (specialCase) {
353  buffer.fSegs[indx++] = c;
354  buffer.fSegs[indx++] = indx2+j-1;
355  buffer.fSegs[indx++] = indx2;
356  }
357  }
358 
359  //bottom & top lines, number of segments: 2*n
360  for (i = 0; i < 2; i++) {
361  indx2 = i*(nz-1)*2*n;
362  for (j = 0; j < n; j++) {
363  buffer.fSegs[indx++] = c;
364  buffer.fSegs[indx++] = indx2+j;
365  buffer.fSegs[indx++] = indx2+n+j;
366  }
367  }
368 
369  //inside & outside spheres, number of segments: 2*(nz-1)*n
370  for (i = 0; i < (nz-1); i++) {
371 
372  //inside sphere
373  indx2 = i*n*2;
374  for (j = 0; j < n; j++) {
375  buffer.fSegs[indx++] = c+2;
376  buffer.fSegs[indx++] = indx2+j;
377  buffer.fSegs[indx++] = indx2+n*2+j;
378  }
379  //outside sphere
380  indx2 = i*n*2+n;
381  for (j = 0; j < n; j++) {
382  buffer.fSegs[indx++] = c+3;
383  buffer.fSegs[indx++] = indx2+j;
384  buffer.fSegs[indx++] = indx2+n*2+j;
385  }
386  }
387 
388  //left & right sections, number of segments: 2*(nz-2)
389  // special case number of segments: 0
390  if (!specialCase) {
391  for (i = 1; i < (nz-1); i++) {
392  for (j = 0; j < 2; j++) {
393  buffer.fSegs[indx++] = c;
394  buffer.fSegs[indx++] = 2*i * n + j*(n-1);
395  buffer.fSegs[indx++] = (2*i+1) * n + j*(n-1);
396  }
397  }
398  }
399 
400  // Polygons
401  Int_t m = n - 1 + (specialCase == kTRUE);
402  indx = 0;
403 
404  //bottom & top, number of polygons: 2*(n-1)
405  // special case number of polygons: 2*n
406  for (j = 0; j < n-1; j++) {
407  buffer.fPols[indx++] = c+3;
408  buffer.fPols[indx++] = 4;
409  buffer.fPols[indx++] = 2*nz*m+j;
410  buffer.fPols[indx++] = m+j;
411  buffer.fPols[indx++] = 2*nz*m+j+1;
412  buffer.fPols[indx++] = j;
413  }
414  for (j = 0; j < n-1; j++) {
415  buffer.fPols[indx++] = c+3;
416  buffer.fPols[indx++] = 4;
417  buffer.fPols[indx++] = 2*nz*m+n+j;
418  buffer.fPols[indx++] = (nz*2-2)*m+j;
419  buffer.fPols[indx++] = 2*nz*m+n+j+1;
420  buffer.fPols[indx++] = (nz*2-2)*m+m+j;
421  }
422  if (specialCase) {
423  buffer.fPols[indx++] = c+3;
424  buffer.fPols[indx++] = 4;
425  buffer.fPols[indx++] = 2*nz*m+j;
426  buffer.fPols[indx++] = m+j;
427  buffer.fPols[indx++] = 2*nz*m;
428  buffer.fPols[indx++] = j;
429 
430  buffer.fPols[indx++] = c+3;
431  buffer.fPols[indx++] = 4;
432  buffer.fPols[indx++] = 2*nz*m+n+j;
433  buffer.fPols[indx++] = (nz*2-2)*m+j;
434  buffer.fPols[indx++] = 2*nz*m+n;
435  buffer.fPols[indx++] = (nz*2-2)*m+m+j;
436  }
437 
438  //inside & outside, number of polygons: (nz-1)*2*(n-1)
439  for (k = 0; k < (nz-1); k++) {
440  for (j = 0; j < n-1; j++) {
441  buffer.fPols[indx++] = c;
442  buffer.fPols[indx++] = 4;
443  buffer.fPols[indx++] = 2*k*m+j;
444  buffer.fPols[indx++] = nz*2*m+(2*k+2)*n+j+1;
445  buffer.fPols[indx++] = (2*k+2)*m+j;
446  buffer.fPols[indx++] = nz*2*m+(2*k+2)*n+j;
447  }
448  for (j = 0; j < n-1; j++) {
449  buffer.fPols[indx++] = c+1;
450  buffer.fPols[indx++] = 4;
451  buffer.fPols[indx++] = (2*k+1)*m+j;
452  buffer.fPols[indx++] = nz*2*m+(2*k + 3)*n+j;
453  buffer.fPols[indx++] = (2*k+ 3)*m+j;
454  buffer.fPols[indx++] = nz*2*m+(2*k+3)*n+j+1;
455  }
456 
457  if (specialCase) {
458  buffer.fPols[indx++] = c;
459  buffer.fPols[indx++] = 4;
460  buffer.fPols[indx++] = 2*k*m+j;
461  buffer.fPols[indx++] = nz*2*m+(2*k+2)*n+j;
462  buffer.fPols[indx++] = (2*k+2)*m+j;
463  buffer.fPols[indx++] = nz*2*m+(2*k+2)*n;
464 
465  buffer.fPols[indx++] = c+1;
466  buffer.fPols[indx++] = 4;
467  buffer.fPols[indx++] = (2*k+1)*m+j;
468  buffer.fPols[indx++] = nz*2*m+(2*k+3)*n+j;
469  buffer.fPols[indx++] = (2*k+3)*m+j;
470  buffer.fPols[indx++] = nz*2*m+(2*k+3)*n;
471  }
472  }
473 
474  //left & right sections, number of polygons: 2*(nz-1)
475  // special case number of polygons: 0
476  if (!specialCase) {
477  indx2 = nz*2*(n-1);
478  for (k = 0; k < (nz-1); k++) {
479  buffer.fPols[indx++] = c+2;
480  buffer.fPols[indx++] = 4;
481  buffer.fPols[indx++] = k==0 ? indx2 : indx2+2*nz*n+2*(k-1);
482  buffer.fPols[indx++] = indx2+2*(k+1)*n;
483  buffer.fPols[indx++] = indx2+2*nz*n+2*k;
484  buffer.fPols[indx++] = indx2+(2*k+3)*n;
485 
486  buffer.fPols[indx++] = c+2;
487  buffer.fPols[indx++] = 4;
488  buffer.fPols[indx++] = k==0 ? indx2+n-1 : indx2+2*nz*n+2*(k-1)+1;
489  buffer.fPols[indx++] = indx2+(2*k+3)*n+n-1;
490  buffer.fPols[indx++] = indx2+2*nz*n+2*k+1;
491  buffer.fPols[indx++] = indx2+2*(k+1)*n+n-1;
492  }
493 
494  buffer.fPols[indx-8] = indx2+n;
495  buffer.fPols[indx-2] = indx2+2*n-1;
496  }
497 
498  buffer.SetSectionsValid(TBuffer3D::kRaw);
499  }
500 
501  return buffer;
502 }
virtual Int_t DistancetoPrimitive(Int_t px, Int_t py)
Compute distance from point px,py to a PSPHE.
Definition: TSPHE.cxx:131
Float_t fPhimax
Definition: TSPHE.h:46
virtual Int_t WriteClassBuffer(const TClass *cl, void *pointer)=0
Bool_t IsReading() const
Definition: TBuffer.h:81
short Version_t
Definition: RtypesCore.h:61
const double pi
float Float_t
Definition: RtypesCore.h:53
Float_t fThemax
Definition: TSPHE.h:44
virtual void Sizeof3D() const
Return total X3D needed by TNode::ls (when called with option "x")
Definition: TSPHE.cxx:195
Float_t faZ
Definition: TSPHE.h:49
Buffer base class used for serializing objects.
Definition: TBuffer.h:40
virtual Int_t CheckByteCount(UInt_t startpos, UInt_t bcnt, const TClass *clss)=0
int Int_t
Definition: RtypesCore.h:41
bool Bool_t
Definition: RtypesCore.h:59
const Bool_t kFALSE
Definition: Rtypes.h:92
virtual void FillBuffer3D(TBuffer3D &buffer, Int_t reqSections) const
We have to set kRawSize (unless already done) to allocate buffer space before kRaw can be filled...
Definition: TShape.cxx:211
Short_t Abs(Short_t d)
Definition: TMathBase.h:110
Float_t fThemin
Definition: TSPHE.h:43
virtual Int_t GetNumberOfDivisions() const
Definition: TSPHE.h:69
void Class()
Definition: Class.C:29
A Sphere.
Definition: TSPHE.h:30
Double_t * fPnts
Definition: TBuffer3D.h:114
Double_t * fSiTab
Definition: TSPHE.h:33
void SetSectionsValid(UInt_t mask)
Definition: TBuffer3D.h:67
Int_t * fPols
Definition: TBuffer3D.h:116
Int_t ShapeDistancetoPrimitive(Int_t numPoints, Int_t px, Int_t py)
Distance to primitive.
Definition: TShape.cxx:117
Bool_t fLocalFrame
Definition: TBuffer3D.h:92
point * points
Definition: X3DBuffer.c:20
virtual void MakeTableOfCoSin() const
Make table of sine and cosine.
Definition: TSPHE.cxx:214
This is the base class for all geometry shapes.
Definition: TShape.h:47
#define gSize3D
Definition: X3DBuffer.h:42
void TransformPoints(Double_t *points, UInt_t NbPnts) const
Transform points (LocalToMaster)
Definition: TShape.cxx:190
virtual void SetEllipse(const Float_t *factors)
Set ellipse.
Definition: TSPHE.cxx:141
TClass * IsA() const
Int_t GetBasicColor() const
Get basic color.
Definition: TShape.cxx:241
unsigned int UInt_t
Definition: RtypesCore.h:42
TMarker * m
Definition: textangle.C:8
Float_t fRmin
Definition: TSPHE.h:41
Float_t fPhimin
Definition: TSPHE.h:45
Bool_t SetRawSizes(UInt_t reqPnts, UInt_t reqPntsCapacity, UInt_t reqSegs, UInt_t reqSegsCapacity, UInt_t reqPols, UInt_t reqPolsCapacity)
Set kRaw tessellation section of buffer with supplied sizes.
Definition: TBuffer3D.cxx:357
Double_t * fCoTab
Table of sin(fPhimin) .... sin(Phi)
Definition: TSPHE.h:34
Generic 3D primitive description class.
Definition: TBuffer3D.h:19
Float_t faY
Definition: TSPHE.h:48
Double_t Cos(Double_t)
Definition: TMath.h:424
virtual const TBuffer3D & GetBuffer3D(Int_t reqSections) const
Get buffer 3d.
Definition: TSPHE.cxx:311
virtual Int_t ReadClassBuffer(const TClass *cl, void *pointer, const TClass *onfile_class=0)=0
virtual ~TSPHE()
SPHE shape default destructor.
Definition: TSPHE.cxx:114
#define ClassImp(name)
Definition: Rtypes.h:279
double Double_t
Definition: RtypesCore.h:55
Int_t fNz
Definition: TSPHE.h:37
Double_t * fCoThetaTab
Table of cos(fPhimin) .... cos(Phi)
Definition: TSPHE.h:35
Float_t fRmax
Definition: TSPHE.h:42
Int_t fNdiv
Table of sin(gThemin) .... cos(Theta)
Definition: TSPHE.h:36
#define name(a, b)
Definition: linkTestLib0.cpp:5
Float_t faX
Definition: TSPHE.h:47
virtual void SetPoints(Double_t *points) const
Create SPHE points.
Definition: TSPHE.cxx:162
Int_t * fSegs
Definition: TBuffer3D.h:115
UInt_t NbPnts() const
Definition: TBuffer3D.h:82
virtual void SetNumberOfDivisions(Int_t p)
Set number of divisions.
Definition: TSPHE.cxx:151
Double_t Sin(Double_t)
Definition: TMath.h:421
Double_t Sqrt(Double_t x)
Definition: TMath.h:464
const Bool_t kTRUE
Definition: Rtypes.h:91
const Int_t n
Definition: legend1.C:16
Float_t fAspectRatio
number of sections
Definition: TSPHE.h:38
virtual Version_t ReadVersion(UInt_t *start=0, UInt_t *bcnt=0, const TClass *cl=0)=0
Bool_t SectionsValid(UInt_t mask) const
Definition: TBuffer3D.h:69
Double_t ATan(Double_t)
Definition: TMath.h:451