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