Logo ROOT  
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
26A polycone
27
28\image html g3d_pcon.png
29It 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
67TPCON::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) {
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
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
251void TPCON::Sizeof3D() const
252{
253 Int_t n;
254
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
265void 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
297const 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)) {
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 {
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
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}
void Class()
Definition: Class.C:29
#define b(i)
Definition: RSha256.hxx:100
#define c(i)
Definition: RSha256.hxx:101
int Int_t
Definition: RtypesCore.h:41
short Version_t
Definition: RtypesCore.h:61
unsigned int UInt_t
Definition: RtypesCore.h:42
const Bool_t kFALSE
Definition: RtypesCore.h:88
bool Bool_t
Definition: RtypesCore.h:59
double Double_t
Definition: RtypesCore.h:55
float Float_t
Definition: RtypesCore.h:53
const Bool_t kTRUE
Definition: RtypesCore.h:87
#define ClassImp(name)
Definition: Rtypes.h:365
char name[80]
Definition: TGX11.cxx:109
point * points
Definition: X3DBuffer.c:22
#define gSize3D
Definition: X3DBuffer.h:40
Generic 3D primitive description class.
Definition: TBuffer3D.h:18
Int_t * fPols
Definition: TBuffer3D.h:114
UInt_t NbPnts() const
Definition: TBuffer3D.h:80
Bool_t SectionsValid(UInt_t mask) const
Definition: TBuffer3D.h:67
@ kRawSizes
Definition: TBuffer3D.h:53
void SetSectionsValid(UInt_t mask)
Definition: TBuffer3D.h:65
Int_t * fSegs
Definition: TBuffer3D.h:113
Bool_t fLocalFrame
Definition: TBuffer3D.h:90
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 * fPnts
Definition: TBuffer3D.h:112
Buffer base class used for serializing objects.
Definition: TBuffer.h:42
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition: TObject.cxx:880
A polycone.
Definition: TPCON.h:33
virtual void Sizeof3D() const
Return total X3D needed by TNode::ls (when called with option "x")
Definition: TPCON.cxx:251
virtual void SetNumberOfDivisions(Int_t p)
Set number of divisions.
Definition: TPCON.cxx:214
Double_t * fCoTab
Table of sin(fPhi1) .... sin(fPhil+fDphi1)
Definition: TPCON.h:37
Float_t fPhi1
Table of cos(fPhi1) .... cos(fPhil+fDphi1)
Definition: TPCON.h:39
Float_t * fRmax
Definition: TPCON.h:44
virtual Int_t GetNumberOfDivisions() const
Definition: TPCON.h:63
virtual ~TPCON()
PCON shape default destructor.
Definition: TPCON.cxx:154
Int_t fNdiv
Definition: TPCON.h:41
Int_t fNz
Definition: TPCON.h:42
Float_t * fDz
Definition: TPCON.h:45
TPCON & operator=(const TPCON &)
assignment operator
Definition: TPCON.cxx:110
TPCON()
PCON shape default constructor.
Definition: TPCON.cxx:49
virtual const TBuffer3D & GetBuffer3D(Int_t reqSections) const
Get buffer 3d.
Definition: TPCON.cxx:297
virtual Bool_t SetSegsAndPols(TBuffer3D &buffer) const
Set segments and polygons.
Definition: TPCON.cxx:337
Float_t fDphi1
Definition: TPCON.h:40
Double_t * fSiTab
Definition: TPCON.h:36
Float_t * fRmin
Definition: TPCON.h:43
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
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
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
virtual Int_t DistancetoPrimitive(Int_t px, Int_t py)
Compute distance from point px,py to a PCON.
Definition: TPCON.cxx:191
This is the base class for all geometry shapes.
Definition: TShape.h:35
TShape & operator=(const TShape &)
assignment operator
Definition: TShape.cxx:93
Int_t GetBasicColor() const
Get basic color.
Definition: TShape.cxx:242
Int_t ShapeDistancetoPrimitive(Int_t numPoints, Int_t px, Int_t py)
Distance to primitive.
Definition: TShape.cxx:118
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
void TransformPoints(Double_t *points, UInt_t NbPnts) const
Transform points (LocalToMaster)
Definition: TShape.cxx:191
const Int_t n
Definition: legend1.C:16
static constexpr double pi
static constexpr double pc
Double_t ATan(Double_t)
Definition: TMath.h:665
Double_t Cos(Double_t)
Definition: TMath.h:631
Double_t Sin(Double_t)
Definition: TMath.h:627
auto * m
Definition: textangle.C:8