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