Logo ROOT   6.16/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
26A Sphere.
27
28It 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
40ROOT 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
66TSPHE::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
91TSPHE::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
142void 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
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
196void TSPHE::Sizeof3D() const
197{
198 Int_t n;
199
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;
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
273void 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;
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
312const 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
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}
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:363
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:40
A Sphere.
Definition: TSPHE.h:28
Float_t faY
Definition: TSPHE.h:46
virtual void SetPoints(Double_t *points) const
Create SPHE points.
Definition: TSPHE.cxx:163
virtual void SetNumberOfDivisions(Int_t p)
Set number of divisions.
Definition: TSPHE.cxx:152
Float_t fPhimax
Definition: TSPHE.h:44
Float_t fThemax
Definition: TSPHE.h:42
virtual void Sizeof3D() const
Return total X3D needed by TNode::ls (when called with option "x")
Definition: TSPHE.cxx:196
virtual const TBuffer3D & GetBuffer3D(Int_t reqSections) const
Get buffer 3d.
Definition: TSPHE.cxx:312
virtual Int_t GetNumberOfDivisions() const
Definition: TSPHE.h:67
virtual void MakeTableOfCoSin() const
Make table of sine and cosine.
Definition: TSPHE.cxx:215
TSPHE()
SPHE shape default constructor.
Definition: TSPHE.cxx:46
Float_t fRmax
Definition: TSPHE.h:40
Float_t faX
Definition: TSPHE.h:45
Int_t fNz
Definition: TSPHE.h:35
Float_t fRmin
Definition: TSPHE.h:39
virtual ~TSPHE()
SPHE shape default destructor.
Definition: TSPHE.cxx:115
Float_t fPhimin
Definition: TSPHE.h:43
Float_t faZ
Definition: TSPHE.h:47
Double_t * fCoThetaTab
Table of cos(fPhimin) .... cos(Phi)
Definition: TSPHE.h:33
Float_t fThemin
Definition: TSPHE.h:41
Double_t * fCoTab
Table of sin(fPhimin) .... sin(Phi)
Definition: TSPHE.h:32
virtual void SetEllipse(const Float_t *factors)
Set ellipse.
Definition: TSPHE.cxx:142
Float_t fAspectRatio
number of sections
Definition: TSPHE.h:36
Double_t * fSiTab
Definition: TSPHE.h:31
virtual Int_t DistancetoPrimitive(Int_t px, Int_t py)
Compute distance from point px,py to a PSPHE.
Definition: TSPHE.cxx:132
Int_t fNdiv
Table of sin(gThemin) .... cos(Theta)
Definition: TSPHE.h:34
This is the base class for all geometry shapes.
Definition: TShape.h:35
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
Double_t ATan(Double_t)
Definition: TMath.h:663
Double_t Sqrt(Double_t x)
Definition: TMath.h:679
Double_t Cos(Double_t)
Definition: TMath.h:629
Double_t Sin(Double_t)
Definition: TMath.h:625
Short_t Abs(Short_t d)
Definition: TMathBase.h:120
auto * m
Definition: textangle.C:8