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