Logo ROOT   6.12/07
Reference Guide
TPCON.cxx
Go to the documentation of this file.
1 // @(#)root/g3d:$Id$
2 // Author: Nenad Buncic 29/09/95
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 "TPCON.h"
13 #include "TNode.h"
14 #include "TMath.h"
15 #include "TVirtualPad.h"
16 #include "TBuffer.h"
17 #include "TBuffer3D.h"
18 #include "TBuffer3DTypes.h"
19 #include "TGeometry.h"
20 #include "TClass.h"
21 
23 
24 /** \class TPCON
25 \ingroup g3d
26 A polycone
27 
28 \image html g3d_pcon.png
29 It has the following parameters:
30 
31  - name: name of the shape
32  - title: shape's title
33  - material: (see TMaterial)
34  - phi1: the azimuthal angle phi at which the volume begins (angles
35  are counted counterclockwise)
36  - dphi: opening angle of the volume, which extends from
37  phi1 to phi1+dphi
38  - nz: number of planes perpendicular to the z axis where
39  the dimension of the section is given -- this number
40  should be at least 2
41  - rmin: array of dimension nz with minimum radius at a given plane
42  - rmax: array of dimension nz with maximum radius at a given plane
43  - z: array of dimension nz with z position of given plane
44 */
45 
46 ////////////////////////////////////////////////////////////////////////////////
47 /// PCON shape default constructor
48 
50 {
51  fRmin = 0;
52  fRmax = 0;
53  fDz = 0;
54  fCoTab = 0;
55  fSiTab = 0;
56  fPhi1 = 0.;
57  fDphi1 = 0.;
58  fNz = 0;
59  fNdiv = 0;
60 }
61 
62 ////////////////////////////////////////////////////////////////////////////////
63 /// PCON shape normal constructor
64 ///
65 /// Parameters of the nz positions must be entered via TPCON::DefineSection.
66 
67 TPCON::TPCON(const char *name, const char *title, const char *material, Float_t phi1, Float_t dphi1, Int_t nz)
68  : TShape(name, title,material)
69 {
70  if (nz < 2 ) {
71  Error(name, "number of z planes for %s must be at least two !", name);
72  return;
73  }
74  fPhi1 = phi1;
75  fDphi1 = dphi1;
76  fNz = nz;
77  fNdiv = 0;
78  fRmin = new Float_t [nz+1];
79  fRmax = new Float_t [nz+1];
80  fDz = new Float_t [nz+1];
81 
82  fCoTab = 0;
83  fSiTab = 0;
84 
85  while (fDphi1 > 360) fDphi1 -= 360;
86 
88 }
89 
90 ////////////////////////////////////////////////////////////////////////////////
91 /// copy constructor
92 
94  TShape(pc),
95  fSiTab(pc.fSiTab),
96  fCoTab(pc.fCoTab),
97  fPhi1(pc.fPhi1),
98  fDphi1(pc.fDphi1),
99  fNdiv(pc.fNdiv),
100  fNz(pc.fNz),
101  fRmin(pc.fRmin),
102  fRmax(pc.fRmax),
103  fDz(pc.fDz)
104 {
105 }
106 
107 ////////////////////////////////////////////////////////////////////////////////
108 /// assignment operator
109 
111 {
112  if(this!=&pc) {
113  TShape::operator=(pc);
114  fSiTab=pc.fSiTab;
115  fCoTab=pc.fCoTab;
116  fPhi1=pc.fPhi1;
117  fDphi1=pc.fDphi1;
118  fNdiv=pc.fNdiv;
119  fNz=pc.fNz;
120  fRmin=pc.fRmin;
121  fRmax=pc.fRmax;
122  fDz=pc.fDz;
123  }
124  return *this;
125 }
126 
127 ////////////////////////////////////////////////////////////////////////////////
128 /// Make table of cosine and sine
129 
131 {
132  const Double_t pi = TMath::ATan(1) * 4.0;
133  const Double_t ragrad = pi/180.0;
134 
135  Int_t n = GetNumberOfDivisions () + 1;
136  if (fCoTab) delete [] fCoTab; // Delete the old tab if any
137  fCoTab = new Double_t [n];
138  if (!fCoTab ) return;
139 
140  if (fSiTab) delete [] fSiTab; // Delete the old tab if any
141  fSiTab = new Double_t [n];
142  if (!fSiTab ) return;
143 
144  Double_t range = Double_t(fDphi1 * ragrad);
145  Double_t phi1 = Double_t(fPhi1 * ragrad);
146  Double_t angstep = range/(n-1);
147 
148  FillTableOfCoSin(phi1,angstep,n);
149 }
150 
151 ////////////////////////////////////////////////////////////////////////////////
152 /// PCON shape default destructor
153 
155 {
156  if (fRmin) delete [] fRmin;
157  if (fRmax) delete [] fRmax;
158  if (fDz) delete [] fDz;
159  if (fSiTab) delete [] fSiTab;
160  if (fCoTab) delete [] fCoTab;
161 
162  fRmin = 0;
163  fRmax = 0;
164  fDz = 0;
165  fCoTab = 0;
166  fSiTab = 0;
167 }
168 
169 ////////////////////////////////////////////////////////////////////////////////
170 /// Defines section secNum of the polycone
171 ///
172 /// - rmin radius of the inner circle in the cross-section
173 /// - rmax radius of the outer circle in the cross-section
174 /// - z z coordinate of the section
175 
177 {
178  if ((secNum < 0) || (secNum >= fNz)) return;
179 
180  fRmin[secNum] = rmin;
181  fRmax[secNum] = rmax;
182  fDz[secNum] = z;
183 }
184 
185 ////////////////////////////////////////////////////////////////////////////////
186 /// Compute distance from point px,py to a PCON
187 ///
188 /// Compute the closest distance of approach from point px,py to each
189 /// computed outline point of the PCON.
190 
192 {
194  Int_t numPoints = fNz*2*n;
195  return ShapeDistancetoPrimitive(numPoints,px,py);
196 }
197 
198 ////////////////////////////////////////////////////////////////////////////////
199 /// Fill the table of cos and sin to prepare drawing
200 
202 {
203  Double_t ph = phi-angstep;
204  for (Int_t j = 0; j < n; j++) {
205  ph += angstep;
206  fCoTab[j] = TMath::Cos(ph);
207  fSiTab[j] = TMath::Sin(ph);
208  }
209 }
210 
211 ////////////////////////////////////////////////////////////////////////////////
212 /// Set number of divisions.
213 
215 {
216  if (GetNumberOfDivisions () == p) return;
217  fNdiv=p;
219 }
220 
221 ////////////////////////////////////////////////////////////////////////////////
222 /// Create PCON points
223 
225 {
226  Int_t i, j;
227  Int_t indx = 0;
228 
230 
231  if (points) {
232  if (!fCoTab) MakeTableOfCoSin();
233  for (i = 0; i < fNz; i++) {
234  for (j = 0; j < n; j++) {
235  points[indx++] = fRmin[i] * fCoTab[j];
236  points[indx++] = fRmin[i] * fSiTab[j];
237  points[indx++] = fDz[i];
238  }
239  for (j = 0; j < n; j++) {
240  points[indx++] = fRmax[i] * fCoTab[j];
241  points[indx++] = fRmax[i] * fSiTab[j];
242  points[indx++] = fDz[i];
243  }
244  }
245  }
246 }
247 
248 ////////////////////////////////////////////////////////////////////////////////
249 /// Return total X3D needed by TNode::ls (when called with option "x")
250 
251 void TPCON::Sizeof3D() const
252 {
253  Int_t n;
254 
255  n = GetNumberOfDivisions()+1;
256 
257  gSize3D.numPoints += fNz*2*n;
258  gSize3D.numSegs += 4*(fNz*n-1+(fDphi1 == 360));
259  gSize3D.numPolys += 2*(fNz*n-1+(fDphi1 == 360));
260 }
261 
262 ////////////////////////////////////////////////////////////////////////////////
263 /// Stream a class object
264 
265 void TPCON::Streamer(TBuffer &b)
266 {
267  if (b.IsReading()) {
268  UInt_t R__s, R__c;
269  Version_t R__v = b.ReadVersion(&R__s, &R__c);
270  if (R__v > 1) {
271  b.ReadClassBuffer(TPCON::Class(), this, R__v, R__s, R__c);
272  return;
273  }
274  //====process old versions before automatic schema evolution
275  TShape::Streamer(b);
276  b >> fPhi1;
277  b >> fDphi1;
278  b >> fNz;
279  fRmin = new Float_t [fNz];
280  fRmax = new Float_t [fNz];
281  fDz = new Float_t [fNz];
282  b.ReadArray(fRmin);
283  b.ReadArray(fRmax);
284  b.ReadArray(fDz);
285  b >> fNdiv;
286  b.CheckByteCount(R__s, R__c, TPCON::IsA());
287  //====end of old versions
288 
289  } else {
290  b.WriteClassBuffer(TPCON::Class(),this);
291  }
292 }
293 
294 ////////////////////////////////////////////////////////////////////////////////
295 /// Get buffer 3d.
296 
297 const TBuffer3D & TPCON::GetBuffer3D(Int_t reqSections) const
298 {
299  static TBuffer3D buffer(TBuffer3DTypes::kGeneric);
300 
301  TShape::FillBuffer3D(buffer, reqSections);
302 
303  // No kShapeSpecific or kBoundingBox
304 
305  if (reqSections & TBuffer3D::kRawSizes)
306  {
307  const Int_t n = GetNumberOfDivisions()+1;
308  Int_t nbPnts = fNz*2*n;
309  Bool_t specialCase = (fDphi1 == 360);
310  Int_t nbSegs = 4*(fNz*n-1+(specialCase == kTRUE));
311  Int_t nbPols = 2*(fNz*n-1+(specialCase == kTRUE));
312 
313  if (buffer.SetRawSizes(nbPnts, 3*nbPnts, nbSegs, 3*nbSegs, nbPols, 6*nbPols)) {
314  buffer.SetSectionsValid(TBuffer3D::kRawSizes);
315  }
316  }
317  if ((reqSections & TBuffer3D::kRaw) && buffer.SectionsValid(TBuffer3D::kRawSizes))
318  {
319  // Points
320  SetPoints(buffer.fPnts);
321  if (!buffer.fLocalFrame) {
322  TransformPoints(buffer.fPnts, buffer.NbPnts());
323  }
324 
325  // Segments and Polygons
326  if (SetSegsAndPols(buffer))
327  {
328  buffer.SetSectionsValid(TBuffer3D::kRaw);
329  }
330  }
331  return buffer;
332 }
333 
334 ////////////////////////////////////////////////////////////////////////////////
335 /// Set segments and polygons.
336 
338 {
339  if (fNz < 2) return kFALSE;
340  const Int_t n = GetNumberOfDivisions()+1;
341  Bool_t specialCase = (fDphi1 == 360);
342 
343  Int_t c = GetBasicColor();
344 
345  Int_t i, j, k;
346  Int_t indx = 0;
347  Int_t indx2 = 0;
348 
349  //inside & outside circles, number of segments: 2*fNz*(n-1)
350  // special case number of segments: 2*fNz*n
351  for (i = 0; i < fNz*2; i++) {
352  indx2 = i*n;
353  for (j = 1; j < n; j++) {
354  buffer.fSegs[indx++] = c;
355  buffer.fSegs[indx++] = indx2+j-1;
356  buffer.fSegs[indx++] = indx2+j;
357  }
358  if (specialCase) {
359  buffer.fSegs[indx++] = c;
360  buffer.fSegs[indx++] = indx2+j-1;
361  buffer.fSegs[indx++] = indx2;
362  }
363  }
364 
365  //bottom & top lines, number of segments: 2*n
366  for (i = 0; i < 2; i++) {
367  indx2 = i*(fNz-1)*2*n;
368  for (j = 0; j < n; j++) {
369  buffer.fSegs[indx++] = c;
370  buffer.fSegs[indx++] = indx2+j;
371  buffer.fSegs[indx++] = indx2+n+j;
372  }
373  }
374 
375  //inside & outside cilindres, number of segments: 2*(fNz-1)*n
376  for (i = 0; i < (fNz-1); i++) {
377 
378  //inside cilinder
379  indx2 = i*n*2;
380  for (j = 0; j < n; j++) {
381  buffer.fSegs[indx++] = c+2;
382  buffer.fSegs[indx++] = indx2+j;
383  buffer.fSegs[indx++] = indx2+n*2+j;
384  }
385  //outside cilinder
386  indx2 = i*n*2+n;
387  for (j = 0; j < n; j++) {
388  buffer.fSegs[indx++] = c+3;
389  buffer.fSegs[indx++] = indx2+j;
390  buffer.fSegs[indx++] = indx2+n*2+j;
391  }
392  }
393 
394  //left & right sections, number of segments: 2*(fNz-2)
395  // special case number of segments: 0
396  if (!specialCase) {
397  for (i = 1; i < (fNz-1); i++) {
398  for (j = 0; j < 2; j++) {
399  buffer.fSegs[indx++] = c;
400  buffer.fSegs[indx++] = 2*i * n + j*(n-1);
401  buffer.fSegs[indx++] = (2*i+1) * n + j*(n-1);
402  }
403  }
404  }
405 
406  Int_t m = n - 1 + (specialCase == kTRUE);
407  indx = 0;
408 
409  //bottom & top, number of polygons: 2*(n-1)
410  // special case number of polygons: 2*n
411  for (j = 0; j < n-1; j++) {
412  buffer.fPols[indx++] = c+3;
413  buffer.fPols[indx++] = 4;
414  buffer.fPols[indx++] = 2*fNz*m+j;
415  buffer.fPols[indx++] = m+j;
416  buffer.fPols[indx++] = 2*fNz*m+j+1;
417  buffer.fPols[indx++] = j;
418  }
419  for (j = 0; j < n-1; j++) {
420  buffer.fPols[indx++] = c+3;
421  buffer.fPols[indx++] = 4;
422  buffer.fPols[indx++] = 2*fNz*m+n+j;
423  buffer.fPols[indx++] = (fNz*2-2)*m+j;
424  buffer.fPols[indx++] = 2*fNz*m+n+j+1;
425  buffer.fPols[indx++] = (fNz*2-2)*m+m+j;
426  }
427  if (specialCase) {
428  buffer.fPols[indx++] = c+3;
429  buffer.fPols[indx++] = 4;
430  buffer.fPols[indx++] = 2*fNz*m+j;
431  buffer.fPols[indx++] = m+j;
432  buffer.fPols[indx++] = 2*fNz*m;
433  buffer.fPols[indx++] = j;
434 
435  buffer.fPols[indx++] = c+3;
436  buffer.fPols[indx++] = 4;
437  buffer.fPols[indx++] = 2*fNz*m+n+j;
438  buffer.fPols[indx++] = (fNz*2-2)*m+j;
439  buffer.fPols[indx++] = 2*fNz*m+n;
440  buffer.fPols[indx++] = (fNz*2-2)*m+m+j;
441  }
442  for (k = 0; k < (fNz-1); k++) {
443  for (j = 0; j < n-1; j++) {
444  buffer.fPols[indx++] = c;
445  buffer.fPols[indx++] = 4;
446  buffer.fPols[indx++] = 2*k*m+j;
447  buffer.fPols[indx++] = fNz*2*m+(2*k+2)*n+j+1;
448  buffer.fPols[indx++] = (2*k+2)*m+j;
449  buffer.fPols[indx++] = fNz*2*m+(2*k+2)*n+j;
450  }
451  for (j = 0; j < n-1; j++) {
452  buffer.fPols[indx++] = c+1;
453  buffer.fPols[indx++] = 4;
454  buffer.fPols[indx++] = (2*k+1)*m+j;
455  buffer.fPols[indx++] = fNz*2*m+(2*k+3)*n+j;
456  buffer.fPols[indx++] = (2*k+3)*m+j;
457  buffer.fPols[indx++] = fNz*2*m+(2*k+3)*n+j+1;
458  }
459 
460  if (specialCase) {
461  buffer.fPols[indx++] = c;
462  buffer.fPols[indx++] = 4;
463  buffer.fPols[indx++] = 2*k*m+j;
464  buffer.fPols[indx++] = fNz*2*m+(2*k+2)*n;
465  buffer.fPols[indx++] = (2*k+2)*m+j;
466  buffer.fPols[indx++] = fNz*2*m+(2*k+2)*n+j;
467 
468  buffer.fPols[indx++] = c+1;
469  buffer.fPols[indx++] = 4;
470  buffer.fPols[indx++] = (2*k+1)*m+j;
471  buffer.fPols[indx++] = fNz*2*m+(2*k+3)*n+j;
472  buffer.fPols[indx++] = (2*k+3)*m+j;
473  buffer.fPols[indx++] = fNz*2*m+(2*k+3)*n;
474  }
475  }
476 
477  if (!specialCase) {
478  indx2 = fNz*2*(n-1);
479  for (k = 0; k < (fNz-1); k++) {
480  buffer.fPols[indx++] = c+2;
481  buffer.fPols[indx++] = 4;
482  buffer.fPols[indx++] = k==0 ? indx2 : indx2+2*fNz*n+2*(k-1);
483  buffer.fPols[indx++] = indx2+2*(k+1)*n;
484  buffer.fPols[indx++] = indx2+2*fNz*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*fNz*n+2*(k-1)+1;
490  buffer.fPols[indx++] = indx2+(2*k+3)*n+n-1;
491  buffer.fPols[indx++] = indx2+2*fNz*n+2*k+1;
492  buffer.fPols[indx++] = indx2+2*(k+1)*n+n-1;
493  }
494  buffer.fPols[indx-8] = indx2+n;
495  buffer.fPols[indx-2] = indx2+2*n-1;
496  }
497 
498  return kTRUE;
499 }
Bool_t IsReading() const
Definition: TBuffer.h:83
virtual Int_t WriteClassBuffer(const TClass *cl, void *pointer)=0
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
virtual void SetPoints(Double_t *points) const
Create PCON points.
Definition: TPCON.cxx:224
virtual void MakeTableOfCoSin() const
Make table of cosine and sine.
Definition: TPCON.cxx:130
static constexpr double pi
virtual ~TPCON()
PCON shape default destructor.
Definition: TPCON.cxx:154
auto * m
Definition: textangle.C:8
short Version_t
Definition: RtypesCore.h:61
Float_t fPhi1
Table of cos(fPhi1) .... cos(fPhil+fDphi1)
Definition: TPCON.h:39
float Float_t
Definition: RtypesCore.h:53
virtual void DefineSection(Int_t secNum, Float_t z, Float_t rmin, Float_t rmax)
Defines section secNum of the polycone.
Definition: TPCON.cxx:176
Float_t * fRmin
Definition: TPCON.h:43
Float_t fDphi1
Definition: TPCON.h:40
TPCON()
PCON shape default constructor.
Definition: TPCON.cxx: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
UInt_t NbPnts() const
Definition: TBuffer3D.h:80
int Int_t
Definition: RtypesCore.h:41
bool Bool_t
Definition: RtypesCore.h:59
void Class()
Definition: Class.C:29
TPCON & operator=(const TPCON &)
assignment operator
Definition: TPCON.cxx:110
Int_t fNdiv
Definition: TPCON.h:41
Double_t * fPnts
Definition: TBuffer3D.h:112
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:20
Int_t fNz
Definition: TPCON.h:42
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 Bool_t SetSegsAndPols(TBuffer3D &buffer) const
Set segments and polygons.
Definition: TPCON.cxx:337
virtual void Sizeof3D() const
Return total X3D needed by TNode::ls (when called with option "x")
Definition: TPCON.cxx:251
Double_t * fCoTab
Table of sin(fPhi1) .... sin(fPhil+fDphi1)
Definition: TPCON.h:37
virtual const TBuffer3D & GetBuffer3D(Int_t reqSections) const
Get buffer 3d.
Definition: TPCON.cxx:297
unsigned int UInt_t
Definition: RtypesCore.h:42
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition: TObject.cxx:880
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
Generic 3D primitive description class.
Definition: TBuffer3D.h:17
Double_t Cos(Double_t)
Definition: TMath.h:550
const Bool_t kFALSE
Definition: RtypesCore.h:88
virtual Int_t ReadClassBuffer(const TClass *cl, void *pointer, const TClass *onfile_class=0)=0
A polycone.
Definition: TPCON.h:33
#define ClassImp(name)
Definition: Rtypes.h:359
virtual void SetNumberOfDivisions(Int_t p)
Set number of divisions.
Definition: TPCON.cxx:214
Double_t * fSiTab
Definition: TPCON.h:36
double Double_t
Definition: RtypesCore.h:55
virtual Int_t DistancetoPrimitive(Int_t px, Int_t py)
Compute distance from point px,py to a PCON.
Definition: TPCON.cxx:191
virtual Int_t GetNumberOfDivisions() const
Definition: TPCON.h:63
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
Float_t * fDz
Definition: TPCON.h:45
Double_t Sin(Double_t)
Definition: TMath.h:547
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
static constexpr double pc
TShape & operator=(const TShape &)
assignment operator
Definition: TShape.cxx:93
virtual void FillTableOfCoSin(Double_t phi, Double_t angstep, Int_t n) const
Fill the table of cos and sin to prepare drawing.
Definition: TPCON.cxx:201
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
char name[80]
Definition: TGX11.cxx:109
virtual Version_t ReadVersion(UInt_t *start=0, UInt_t *bcnt=0, const TClass *cl=0)=0
virtual Int_t ReadArray(Bool_t *&b)=0
Double_t ATan(Double_t)
Definition: TMath.h:577
Float_t * fRmax
Definition: TPCON.h:44