Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
TGeoPcon.cxx
Go to the documentation of this file.
1// @(#)root/geom:$Id$
2// Author: Andrei Gheata 24/10/01
3// TGeoPcon::Contains() implemented by Mihaela Gheata
4
5/*************************************************************************
6 * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. *
7 * All rights reserved. *
8 * *
9 * For the licensing terms see $ROOTSYS/LICENSE. *
10 * For the list of contributors see $ROOTSYS/README/CREDITS. *
11 *************************************************************************/
12
13/** \class TGeoPcon
14\ingroup Shapes_classes
15
16A polycone is represented by a sequence of tubes/cones, glued together
17at defined Z planes. The polycone might have a phi segmentation, which
18globally applies to all the pieces. It has to be defined in two steps:
19
201. First call the TGeoPcon constructor to define a polycone:
21
22 ~~~{.cpp}
23 TGeoPcon(Double_t phi1,Double_t dphi,Int_t nz
24 ~~~
25
26 - `phi1:` starting phi angle in degrees
27 - `dphi:` total phi range
28 - `nz:` number of Z planes defining polycone sections (minimum 2)
29
302. Define one by one all sections [0, nz-1]
31
32~~~{.cpp}
33void TGeoPcon::DefineSection(Int_t i,Double_t z,
34Double_t rmin, Double_t rmax);
35~~~
36
37 - `i:` section index [0, nz-1]
38 - `z:` z coordinate of the section
39 - `rmin:` minimum radius corresponding too this section
40 - `rmax:` maximum radius.
41
42The first section (`i=0`) has to be positioned always the lowest Z
43coordinate. It defines the radii of the first cone/tube segment at its
44lower Z. The next section defines the end-cap of the first segment, but
45it can represent also the beginning of the next one. Any discontinuity
46in the radius has to be represented by a section defined at the same Z
47coordinate as the previous one. The Z coordinates of all sections must
48be sorted in increasing order. Any radius or Z coordinate of a given
49plane have corresponding getters:
50
51~~~{.cpp}
52Double_t TGeoPcon::GetRmin(Int_t i);
53Double_t TGeoPcon::GetRmax(Int_t i);
54Double_t TGeoPcon::GetZ(Int_t i);
55~~~
56
57Note that the last section should be defined last, since it triggers the
58computation of the bounding box of the polycone.
59
60Begin_Macro
61{
62 TCanvas *c = new TCanvas("c", "c",0,0,600,600);
63 new TGeoManager("pcon", "poza10");
64 TGeoMaterial *mat = new TGeoMaterial("Al", 26.98,13,2.7);
65 TGeoMedium *med = new TGeoMedium("MED",1,mat);
66 TGeoVolume *top = gGeoManager->MakeBox("TOP",med,100,100,100);
67 gGeoManager->SetTopVolume(top);
68 TGeoVolume *vol = gGeoManager->MakePcon("PCON",med, -30.0,300,4);
69 TGeoPcon *pcon = (TGeoPcon*)(vol->GetShape());
70 pcon->DefineSection(0,0,15,20);
71 pcon->DefineSection(1,20,15,20);
72 pcon->DefineSection(2,20,15,25);
73 pcon->DefineSection(3,50,15,20);
74 vol->SetLineWidth(2);
75 top->AddNode(vol,1);
76 gGeoManager->CloseGeometry();
77 gGeoManager->SetNsegments(30);
78 top->Draw();
79 TView *view = gPad->GetView();
80 if (view) view->ShowAxis();
81}
82End_Macro
83*/
84
85#include "TGeoPcon.h"
86
87#include <iostream>
88
89#include "TBuffer.h"
90#include "TGeoManager.h"
91#include "TGeoVolume.h"
92#include "TVirtualGeoPainter.h"
93#include "TGeoTube.h"
94#include "TGeoCone.h"
95#include "TBuffer3D.h"
96#include "TBuffer3DTypes.h"
97#include "TMath.h"
98
99
100////////////////////////////////////////////////////////////////////////////////
101/// dummy ctor
102
104 : TGeoBBox(),
105 fNz(0),
106 fPhi1(0.),
107 fDphi(0.),
108 fRmin(nullptr),
109 fRmax(nullptr),
110 fZ(nullptr),
111 fFullPhi(kFALSE),
112 fC1(0.),
113 fS1(0.),
114 fC2(0.),
115 fS2(0.),
116 fCm(0.),
117 fSm(0.),
118 fCdphi(0.)
119{
121}
122
123////////////////////////////////////////////////////////////////////////////////
124/// Default constructor
125
127 : TGeoBBox(0, 0, 0),
128 fNz(nz),
129 fPhi1(phi),
130 fDphi(dphi),
131 fRmin(nullptr),
132 fRmax(nullptr),
133 fZ(nullptr),
134 fFullPhi(kFALSE),
135 fC1(0.),
136 fS1(0.),
137 fC2(0.),
138 fS2(0.),
139 fCm(0.),
140 fSm(0.),
141 fCdphi(0.)
142{
144 while (fPhi1 < 0)
145 fPhi1 += 360.;
146 fRmin = new Double_t[nz];
147 fRmax = new Double_t[nz];
148 fZ = new Double_t[nz];
149 memset(fRmin, 0, nz * sizeof(Double_t));
150 memset(fRmax, 0, nz * sizeof(Double_t));
151 memset(fZ, 0, nz * sizeof(Double_t));
153 fFullPhi = kTRUE;
156 Double_t phim = 0.5 * (phi1 + phi2);
164}
165
166////////////////////////////////////////////////////////////////////////////////
167/// Default constructor
168
170 : TGeoBBox(name, 0, 0, 0),
171 fNz(nz),
172 fPhi1(phi),
173 fDphi(dphi),
174 fRmin(nullptr),
175 fRmax(nullptr),
176 fZ(nullptr),
177 fFullPhi(kFALSE),
178 fC1(0.),
179 fS1(0.),
180 fC2(0.),
181 fS2(0.),
182 fCm(0.),
183 fSm(0.),
184 fCdphi(0.)
185{
187 while (fPhi1 < 0)
188 fPhi1 += 360.;
189 fRmin = new Double_t[nz];
190 fRmax = new Double_t[nz];
191 fZ = new Double_t[nz];
192 memset(fRmin, 0, nz * sizeof(Double_t));
193 memset(fRmax, 0, nz * sizeof(Double_t));
194 memset(fZ, 0, nz * sizeof(Double_t));
196 fFullPhi = kTRUE;
199 Double_t phim = 0.5 * (phi1 + phi2);
207}
208
209////////////////////////////////////////////////////////////////////////////////
210/// Default constructor in GEANT3 style
211/// - param[0] = phi1
212/// - param[1] = dphi
213/// - param[2] = nz
214/// - param[3] = z1
215/// - param[4] = Rmin1
216/// - param[5] = Rmax1
217/// ...
218
220 : TGeoBBox(0, 0, 0),
221 fNz(0),
222 fPhi1(0.),
223 fDphi(0.),
224 fRmin(nullptr),
225 fRmax(nullptr),
226 fZ(nullptr),
227 fFullPhi(kFALSE),
228 fC1(0.),
229 fS1(0.),
230 fC2(0.),
231 fS2(0.),
232 fCm(0.),
233 fSm(0.),
234 fCdphi(0.)
235{
237 SetDimensions(param);
238 ComputeBBox();
239}
240
241////////////////////////////////////////////////////////////////////////////////
242/// destructor
243
245{
246 if (fRmin) {
247 delete[] fRmin;
248 fRmin = nullptr;
249 }
250 if (fRmax) {
251 delete[] fRmax;
252 fRmax = nullptr;
253 }
254 if (fZ) {
255 delete[] fZ;
256 fZ = nullptr;
257 }
258}
259
260////////////////////////////////////////////////////////////////////////////////
261/// Computes capacity of the shape in [length^3]
262
264{
265 Int_t ipl;
267 Double_t capacity = 0.;
268 phi1 = fPhi1;
269 phi2 = fPhi1 + fDphi;
270 for (ipl = 0; ipl < fNz - 1; ipl++) {
271 dz = 0.5 * (fZ[ipl + 1] - fZ[ipl]);
272 if (dz < TGeoShape::Tolerance())
273 continue;
274 rmin1 = fRmin[ipl];
275 rmax1 = fRmax[ipl];
276 rmin2 = fRmin[ipl + 1];
277 rmax2 = fRmax[ipl + 1];
279 }
280 return capacity;
281}
282
283////////////////////////////////////////////////////////////////////////////////
284/// compute bounding box of the pcon
285/// Check if the sections are in increasing Z order
286
288{
289 for (Int_t isec = 0; isec < fNz - 1; isec++) {
290 if (TMath::Abs(fZ[isec] - fZ[isec + 1]) < TGeoShape::Tolerance()) {
291 fZ[isec + 1] = fZ[isec];
294 InspectShape();
295 Error("ComputeBBox", "Duplicated section %d/%d for shape %s", isec, isec + 1, GetName());
296 }
297 }
298 if (fZ[isec] > fZ[isec + 1]) {
299 InspectShape();
300 Fatal("ComputeBBox", "Wrong section order");
301 }
302 }
303 // Check if the last sections are valid
304 if (TMath::Abs(fZ[1] - fZ[0]) < TGeoShape::Tolerance() ||
305 TMath::Abs(fZ[fNz - 1] - fZ[fNz - 2]) < TGeoShape::Tolerance()) {
306 InspectShape();
307 Fatal("ComputeBBox", "Shape %s at index %d: Not allowed first two or last two sections at same Z", GetName(),
309 }
310 Double_t zmin = TMath::Min(fZ[0], fZ[fNz - 1]);
311 Double_t zmax = TMath::Max(fZ[0], fZ[fNz - 1]);
312 // find largest rmax an smallest rmin
316
317 Double_t xc[4];
318 Double_t yc[4];
319 xc[0] = rmax * fC1;
320 yc[0] = rmax * fS1;
321 xc[1] = rmax * fC2;
322 yc[1] = rmax * fS2;
323 xc[2] = rmin * fC1;
324 yc[2] = rmin * fS1;
325 xc[3] = rmin * fC2;
326 yc[3] = rmin * fS2;
327
328 Double_t xmin = xc[TMath::LocMin(4, &xc[0])];
329 Double_t xmax = xc[TMath::LocMax(4, &xc[0])];
330 Double_t ymin = yc[TMath::LocMin(4, &yc[0])];
331 Double_t ymax = yc[TMath::LocMax(4, &yc[0])];
332
333 Double_t ddp = -fPhi1;
334 if (ddp < 0)
335 ddp += 360;
336 if (ddp <= fDphi)
337 xmax = rmax;
338 ddp = 90 - fPhi1;
339 if (ddp < 0)
340 ddp += 360;
341 if (ddp <= fDphi)
342 ymax = rmax;
343 ddp = 180 - fPhi1;
344 if (ddp < 0)
345 ddp += 360;
346 if (ddp <= fDphi)
347 xmin = -rmax;
348 ddp = 270 - fPhi1;
349 if (ddp < 0)
350 ddp += 360;
351 if (ddp <= fDphi)
352 ymin = -rmax;
353 fOrigin[0] = (xmax + xmin) / 2;
354 fOrigin[1] = (ymax + ymin) / 2;
355 fOrigin[2] = (zmax + zmin) / 2;
356 fDX = (xmax - xmin) / 2;
357 fDY = (ymax - ymin) / 2;
358 fDZ = (zmax - zmin) / 2;
360}
361
362////////////////////////////////////////////////////////////////////////////////
363/// Compute normal to closest surface from POINT.
364
365void TGeoPcon::ComputeNormal(const Double_t *point, const Double_t *dir, Double_t *norm) const
366{
367 memset(norm, 0, 3 * sizeof(Double_t));
368 Double_t r;
369 Double_t ptnew[3];
372 Int_t ipl = TMath::BinarySearch(fNz, fZ, point[2]);
373 if (ipl == (fNz - 1) || ipl < 0) {
374 // point outside Z range
375 norm[2] = TMath::Sign(1., dir[2]);
376 return;
377 }
379 if ((fZ[ipl + 1] - point[2]) < (point[2] - fZ[ipl]))
380 iplclose++;
381 dz = TMath::Abs(fZ[iplclose] - point[2]);
382 if (dz < 1E-5) {
383 if (iplclose == 0 || iplclose == (fNz - 1)) {
384 norm[2] = TMath::Sign(1., dir[2]);
385 return;
386 }
388 r = TMath::Sqrt(point[0] * point[0] + point[1] * point[1]);
389 if (r < TMath::Max(fRmin[ipl], fRmin[ipl - 1]) || r > TMath::Min(fRmax[ipl], fRmax[ipl - 1])) {
390 norm[2] = TMath::Sign(1., dir[2]);
391 return;
392 }
393 } else {
395 r = TMath::Sqrt(point[0] * point[0] + point[1] * point[1]);
396 if (r < TMath::Max(fRmin[iplclose], fRmin[iplclose + 1]) ||
398 norm[2] = TMath::Sign(1., dir[2]);
399 return;
400 }
401 }
402 }
403 } //-> Z done
404 memcpy(ptnew, point, 3 * sizeof(Double_t));
405 dz = 0.5 * (fZ[ipl + 1] - fZ[ipl]);
407 norm[2] = TMath::Sign(1., dir[2]);
408 return;
409 }
410 ptnew[2] -= 0.5 * (fZ[ipl] + fZ[ipl + 1]);
411 rmin1 = fRmin[ipl];
412 rmax1 = fRmax[ipl];
413 rmin2 = fRmin[ipl + 1];
414 rmax2 = fRmax[ipl + 1];
416 ? kTRUE
417 : kFALSE;
418 if (!fFullPhi) {
419 if (is_tube)
421 else
423 } else {
424 if (is_tube)
426 else
428 }
429}
430
431////////////////////////////////////////////////////////////////////////////////
432/// test if point is inside this shape
433/// check total z range
434
436{
437 if ((point[2] < fZ[0]) || (point[2] > fZ[fNz - 1]))
438 return kFALSE;
439 // check R squared
440 Double_t r2 = point[0] * point[0] + point[1] * point[1];
441
442 Int_t izl = 0;
443 Int_t izh = fNz - 1;
444 Int_t izt = (fNz - 1) / 2;
445 while ((izh - izl) > 1) {
446 if (point[2] > fZ[izt])
447 izl = izt;
448 else
449 izh = izt;
450 izt = (izl + izh) >> 1;
451 }
452 // the point is in the section bounded by izl and izh Z planes
453
454 // compute Rmin and Rmax and test the value of R squared
459 } else {
460 Double_t dz = fZ[izh] - fZ[izl];
461 Double_t dz1 = point[2] - fZ[izl];
462 rmin = (fRmin[izl] * (dz - dz1) + fRmin[izh] * dz1) / dz;
463 rmax = (fRmax[izl] * (dz - dz1) + fRmax[izh] * dz1) / dz;
464 }
465 if ((r2 < rmin * rmin) || (r2 > rmax * rmax))
466 return kFALSE;
467 // now check phi
469 return kTRUE;
470 if (r2 < 1E-10)
471 return kTRUE;
472 Double_t phi = TMath::ATan2(point[1], point[0]) * TMath::RadToDeg();
473 if (phi < 0)
474 phi += 360.0;
475 Double_t ddp = phi - fPhi1;
476 if (ddp < 0)
477 ddp += 360.;
478 if (ddp <= fDphi)
479 return kTRUE;
480 return kFALSE;
481}
482
483////////////////////////////////////////////////////////////////////////////////
484/// compute closest distance from point px,py to each corner
485
487{
489 const Int_t numPoints = 2 * n * fNz;
490 return ShapeDistancetoPrimitive(numPoints, px, py);
491}
492
493////////////////////////////////////////////////////////////////////////////////
494/// compute distance from inside point to surface of the polycone
495
498{
499 if (iact < 3 && safe) {
500 *safe = Safety(point, kTRUE);
501 if (iact == 0)
502 return TGeoShape::Big();
503 if ((iact == 1) && (*safe > step))
504 return TGeoShape::Big();
505 }
507 Double_t sstep = 1E-6;
509 // determine which z segment contains the point
510 Int_t ipl = TMath::BinarySearch(fNz, fZ, point[2] + TMath::Sign(1.E-10, dir[2]));
511 if (ipl < 0)
512 ipl = 0;
513 if (ipl == (fNz - 1))
514 ipl--;
515 Double_t dz = 0.5 * (fZ[ipl + 1] - fZ[ipl]);
517 if (dz < 1e-9) {
518 // radius changing segment, make sure track is not in the XY plane
519 if (TGeoShape::IsSameWithinTolerance(dir[2], 0)) {
521 } else {
522 // check if a close point is still contained
523 point_new[0] = point[0] + sstep * dir[0];
524 point_new[1] = point[1] + sstep * dir[1];
525 point_new[2] = point[2] + sstep * dir[2];
526 if (!Contains(point_new))
527 return 0.;
528 return (DistFromInside(point_new, dir, iact, step, safe) + sstep);
529 }
530 }
531 // determine if the current segment is a tube or a cone
534 intub = kFALSE;
536 intub = kFALSE;
537 // determine phi segmentation
538 memcpy(point_new, point, 2 * sizeof(Double_t));
539 // new point in reference system of the current segment
540 point_new[2] = point[2] - 0.5 * (fZ[ipl] + fZ[ipl + 1]);
541
542 if (special_case) {
543 if (!fFullPhi)
545 TMath::Max(fRmax[ipl], fRmax[ipl + 1]), dz, fC1, fS1, fC2, fS2, fCm, fSm,
546 fCdphi);
547 else
549 TMath::Max(fRmax[ipl], fRmax[ipl + 1]), dz);
550 return snxt;
551 }
552 if (intub) {
553 if (!fFullPhi)
555 fCdphi);
556 else
558 } else {
559 if (!fFullPhi)
561 fC1, fS1, fC2, fS2, fCm, fSm, fCdphi);
562 else
564 }
565
566 for (Int_t i = 0; i < 3; i++)
567 point_new[i] = point[i] + (snxt + 1E-6) * dir[i];
568 if (!Contains(&point_new[0]))
569 return snxt;
570
571 snxt += DistFromInside(&point_new[0], dir, 3) + 1E-6;
572 return snxt;
573}
574
575////////////////////////////////////////////////////////////////////////////////
576/// compute distance to a pcon Z slice. Segment iz must be valid
577
578Double_t TGeoPcon::DistToSegZ(const Double_t *point, const Double_t *dir, Int_t &iz) const
579{
580 Double_t zmin = fZ[iz];
581 Double_t zmax = fZ[iz + 1];
582 if (TGeoShape::IsSameWithinTolerance(zmin, zmax)) {
584 return TGeoShape::Big();
585 Int_t istep = (dir[2] > 0) ? 1 : -1;
586 iz += istep;
587 if (iz < 0 || iz > (fNz - 2))
588 return TGeoShape::Big();
589 return DistToSegZ(point, dir, iz);
590 }
591 Double_t dz = 0.5 * (zmax - zmin);
592 Double_t local[3];
593 memcpy(&local[0], point, 3 * sizeof(Double_t));
594 local[2] = point[2] - 0.5 * (zmin + zmax);
596 Double_t rmin1 = fRmin[iz];
597 Double_t rmax1 = fRmax[iz];
598 Double_t rmin2 = fRmin[iz + 1];
599 Double_t rmax2 = fRmax[iz + 1];
600
602 if (fFullPhi)
604 else
606 } else {
607 if (fFullPhi)
609 else
611 fCdphi);
612 }
613 if (snxt < 1E20)
614 return snxt;
615 // check next segment
617 return TGeoShape::Big();
618 Int_t istep = (dir[2] > 0) ? 1 : -1;
619 iz += istep;
620 if (iz < 0 || iz > (fNz - 2))
621 return TGeoShape::Big();
622 return DistToSegZ(point, dir, iz);
623}
624
625////////////////////////////////////////////////////////////////////////////////
626/// compute distance from outside point to surface of the tube
627
630{
631 if ((iact < 3) && safe) {
632 *safe = Safety(point, kFALSE);
633 if ((iact == 1) && (*safe > step))
634 return TGeoShape::Big();
635 if (iact == 0)
636 return TGeoShape::Big();
637 }
638 // check if ray intersect outscribed cylinder
639 if ((point[2] < fZ[0]) && (dir[2] <= 0))
640 return TGeoShape::Big();
641 if ((point[2] > fZ[fNz - 1]) && (dir[2] >= 0))
642 return TGeoShape::Big();
643 // Check if the bounding box is crossed within the requested distance
644 Double_t sdist = TGeoBBox::DistFromOutside(point, dir, fDX, fDY, fDZ, fOrigin, step);
645 if (sdist >= step)
646 return TGeoShape::Big();
647
648 Double_t r2 = point[0] * point[0] + point[1] * point[1];
649 Double_t radmax = 0;
651 if (r2 > (radmax * radmax)) {
652 Double_t rpr = -point[0] * dir[0] - point[1] * dir[1];
653 Double_t nxy = dir[0] * dir[0] + dir[1] * dir[1];
654 if (rpr < TMath::Sqrt((r2 - radmax * radmax) * nxy))
655 return TGeoShape::Big();
656 }
657
658 // find in which Z segment we are
659 Int_t ipl = TMath::BinarySearch(fNz, fZ, point[2]);
660 Int_t ifirst = ipl;
661 if (ifirst < 0) {
662 ifirst = 0;
663 } else if (ifirst >= (fNz - 1)) {
664 ifirst = fNz - 2;
665 }
666 // find if point is in the phi gap
667 Double_t phi = 0;
668 if (!fFullPhi) {
669 phi = TMath::ATan2(point[1], point[0]);
670 if (phi < 0)
671 phi += 2. * TMath::Pi();
672 }
673
674 // compute distance to boundary
675 return DistToSegZ(point, dir, ifirst);
676}
677
678////////////////////////////////////////////////////////////////////////////////
679/// Defines z position of a section plane, rmin and rmax at this z. Sections
680/// should be defined in increasing or decreasing Z order and the last section
681/// HAS to be snum = fNz-1
682
684{
685 if ((snum < 0) || (snum >= fNz))
686 return;
687 fZ[snum] = z;
688 fRmin[snum] = rmin;
689 fRmax[snum] = rmax;
690 if (rmin > rmax)
691 Warning("DefineSection", "Shape %s: invalid rmin=%g rmax=%g", GetName(), rmin, rmax);
692 if (snum == (fNz - 1)) {
693 // Reorder sections in increasing Z order
694 if (fZ[0] > fZ[snum]) {
695 Int_t iz = 0;
696 Int_t izi = fNz - 1;
697 Double_t temp;
698 while (iz < izi) {
699 temp = fZ[iz];
700 fZ[iz] = fZ[izi];
701 fZ[izi] = temp;
702 temp = fRmin[iz];
703 fRmin[iz] = fRmin[izi];
704 fRmin[izi] = temp;
705 temp = fRmax[iz];
706 fRmax[iz] = fRmax[izi];
707 fRmax[izi] = temp;
708 iz++;
709 izi--;
710 }
711 }
712 ComputeBBox();
713 }
714}
715
716////////////////////////////////////////////////////////////////////////////////
717/// Returns number of segments on each mesh circle segment.
718
720{
721 return gGeoManager->GetNsegments();
722}
723
724////////////////////////////////////////////////////////////////////////////////
725/// Divide this polycone shape belonging to volume "voldiv" into ndiv volumes
726/// called divname, from start position with the given step. Returns pointer
727/// to created division cell volume in case of Z divisions. Z divisions can be
728/// performed if the divided range is in between two consecutive Z planes.
729/// In case a wrong division axis is supplied, returns pointer to
730/// volume that was divided.
731
734{
735 TGeoShape *shape; //--- shape to be created
736 TGeoVolume *vol; //--- division volume to be created
737 TGeoVolumeMulti *vmulti; //--- generic divided volume
738 TGeoPatternFinder *finder; //--- finder to be attached
739 TString opt = ""; //--- option to be attached
740 Double_t zmin = start;
741 Double_t zmax = start + ndiv * step;
742 Int_t isect = -1;
743 Int_t is, id, ipl;
744 switch (iaxis) {
745 case 1: //--- R division
746 Error("Divide", "Shape %s: cannot divide a pcon on radius", GetName());
747 return nullptr;
748 case 2: //--- Phi division
749 finder = new TGeoPatternCylPhi(voldiv, ndiv, start, start + ndiv * step);
751 voldiv->SetFinder(finder);
752 finder->SetDivIndex(voldiv->GetNdaughters());
753 shape = new TGeoPcon(-step / 2, step, fNz);
754 for (is = 0; is < fNz; is++)
755 ((TGeoPcon *)shape)->DefineSection(is, fZ[is], fRmin[is], fRmax[is]);
756 vol = new TGeoVolume(divname, shape, voldiv->GetMedium());
757 vmulti->AddVolume(vol);
758 opt = "Phi";
759 for (id = 0; id < ndiv; id++) {
760 voldiv->AddNodeOffset(vol, id, start + id * step + step / 2, opt.Data());
761 ((TGeoNodeOffset *)voldiv->GetNodes()->At(voldiv->GetNdaughters() - 1))->SetFinder(finder);
762 }
763 return vmulti;
764 case 3: //--- Z division
765 // find start plane
766 for (ipl = 0; ipl < fNz - 1; ipl++) {
767 if (start < fZ[ipl])
768 continue;
769 else {
770 if ((start + ndiv * step) > fZ[ipl + 1])
771 continue;
772 }
773 isect = ipl;
774 zmin = fZ[isect];
775 zmax = fZ[isect + 1];
776 break;
777 }
778 if (isect < 0) {
779 Error("Divide", "Shape %s: cannot divide pcon on Z if divided region is not between 2 planes", GetName());
780 return nullptr;
781 }
782 finder = new TGeoPatternZ(voldiv, ndiv, start, start + ndiv * step);
784 voldiv->SetFinder(finder);
785 finder->SetDivIndex(voldiv->GetNdaughters());
786 opt = "Z";
787 for (id = 0; id < ndiv; id++) {
788 Double_t z1 = start + id * step;
789 Double_t z2 = start + (id + 1) * step;
790 Double_t rmin1 = (fRmin[isect] * (zmax - z1) - fRmin[isect + 1] * (zmin - z1)) / (zmax - zmin);
791 Double_t rmax1 = (fRmax[isect] * (zmax - z1) - fRmax[isect + 1] * (zmin - z1)) / (zmax - zmin);
792 Double_t rmin2 = (fRmin[isect] * (zmax - z2) - fRmin[isect + 1] * (zmin - z2)) / (zmax - zmin);
793 Double_t rmax2 = (fRmax[isect] * (zmax - z2) - fRmax[isect + 1] * (zmin - z2)) / (zmax - zmin);
796 ? kTRUE
797 : kFALSE;
798 Bool_t is_seg = (fDphi < 360) ? kTRUE : kFALSE;
799 if (is_seg) {
800 if (is_tube)
801 shape = new TGeoTubeSeg(fRmin[isect], fRmax[isect], step / 2, fPhi1, fPhi1 + fDphi);
802 else
803 shape = new TGeoConeSeg(step / 2, rmin1, rmax1, rmin2, rmax2, fPhi1, fPhi1 + fDphi);
804 } else {
805 if (is_tube)
806 shape = new TGeoTube(fRmin[isect], fRmax[isect], step / 2);
807 else
808 shape = new TGeoCone(step / 2, rmin1, rmax1, rmin2, rmax2);
809 }
810 vol = new TGeoVolume(divname, shape, voldiv->GetMedium());
811 vmulti->AddVolume(vol);
812 voldiv->AddNodeOffset(vol, id, start + id * step + step / 2, opt.Data());
813 ((TGeoNodeOffset *)voldiv->GetNodes()->At(voldiv->GetNdaughters() - 1))->SetFinder(finder);
814 }
815 return vmulti;
816 default: Error("Divide", "Shape %s: Wrong axis %d for division", GetName(), iaxis); return nullptr;
817 }
818}
819
820////////////////////////////////////////////////////////////////////////////////
821/// Returns name of axis IAXIS.
822
824{
825 switch (iaxis) {
826 case 1: return "R";
827 case 2: return "PHI";
828 case 3: return "Z";
829 default: return "UNDEFINED";
830 }
831}
832
833////////////////////////////////////////////////////////////////////////////////
834/// Get range of shape for a given axis.
835
837{
838 xlo = 0;
839 xhi = 0;
840 Double_t dx = 0;
841 switch (iaxis) {
842 case 2:
843 xlo = fPhi1;
844 xhi = fPhi1 + fDphi;
845 dx = fDphi;
846 return dx;
847 case 3:
848 xlo = fZ[0];
849 xhi = fZ[fNz - 1];
850 dx = xhi - xlo;
851 return dx;
852 }
853 return dx;
854}
855
856////////////////////////////////////////////////////////////////////////////////
857/// Fill vector param[4] with the bounding cylinder parameters. The order
858/// is the following : Rmin, Rmax, Phi1, Phi2
859
861{
862 param[0] = fRmin[0]; // Rmin
863 param[1] = fRmax[0]; // Rmax
864 for (Int_t i = 1; i < fNz; i++) {
865 if (fRmin[i] < param[0])
866 param[0] = fRmin[i];
867 if (fRmax[i] > param[1])
868 param[1] = fRmax[i];
869 }
870 param[0] *= param[0];
871 param[1] *= param[1];
873 param[2] = 0.;
874 param[3] = 360.;
875 return;
876 }
877 param[2] = (fPhi1 < 0) ? (fPhi1 + 360.) : fPhi1; // Phi1
878 param[3] = param[2] + fDphi; // Phi2
879}
880
881////////////////////////////////////////////////////////////////////////////////
882/// Returns Rmin for Z segment IPL.
883
885{
886 if (ipl < 0 || ipl > (fNz - 1)) {
887 Error("GetRmin", "ipl=%i out of range (0,%i) in shape %s", ipl, fNz - 1, GetName());
888 return 0.;
889 }
890 return fRmin[ipl];
891}
892
893////////////////////////////////////////////////////////////////////////////////
894/// Returns Rmax for Z segment IPL.
895
897{
898 if (ipl < 0 || ipl > (fNz - 1)) {
899 Error("GetRmax", "ipl=%i out of range (0,%i) in shape %s", ipl, fNz - 1, GetName());
900 return 0.;
901 }
902 return fRmax[ipl];
903}
904
905////////////////////////////////////////////////////////////////////////////////
906/// Returns Z for segment IPL.
907
909{
910 if (ipl < 0 || ipl > (fNz - 1)) {
911 Error("GetZ", "ipl=%i out of range (0,%i) in shape %s", ipl, fNz - 1, GetName());
912 return 0.;
913 }
914 return fZ[ipl];
915}
916
917////////////////////////////////////////////////////////////////////////////////
918/// print shape parameters
919
921{
922 printf("*** Shape %s: TGeoPcon ***\n", GetName());
923 printf(" Nz = %i\n", fNz);
924 printf(" phi1 = %11.5f\n", fPhi1);
925 printf(" dphi = %11.5f\n", fDphi);
926 for (Int_t ipl = 0; ipl < fNz; ipl++)
927 printf(" plane %i: z=%11.5f Rmin=%11.5f Rmax=%11.5f\n", ipl, fZ[ipl], fRmin[ipl], fRmax[ipl]);
928 printf(" Bounding box:\n");
930}
931
932////////////////////////////////////////////////////////////////////////////////
933/// Creates a TBuffer3D describing *this* shape.
934/// Coordinates are in local reference frame.
935
937{
940 if (nbPnts <= 0)
941 return nullptr;
942
943 TBuffer3D *buff =
945 if (buff) {
946 SetPoints(buff->fPnts);
948 }
949
950 return buff;
951}
952
953////////////////////////////////////////////////////////////////////////////////
954/// Fill TBuffer3D structure for segments and polygons.
955
957{
958 if (!HasInsideSurface()) {
960 return;
961 }
962
963 Int_t i, j;
964 const Int_t n = gGeoManager->GetNsegments() + 1;
965 Int_t nz = GetNz();
966 if (nz < 2)
967 return;
968 Int_t nbPnts = nz * 2 * n;
969 if (nbPnts <= 0)
970 return;
972
975
976 Int_t indx = 0, indx2, k;
977
978 // inside & outside circles, number of segments: 2*nz*(n-1)
979 // special case number of segments: 2*nz*n
980 for (i = 0; i < nz * 2; i++) {
981 indx2 = i * n;
982 for (j = 1; j < n; j++) {
983 buff.fSegs[indx++] = c;
984 buff.fSegs[indx++] = indx2 + j - 1;
985 buff.fSegs[indx++] = indx2 + j;
986 }
987 if (specialCase) {
988 buff.fSegs[indx++] = c;
989 buff.fSegs[indx++] = indx2 + j - 1;
990 buff.fSegs[indx++] = indx2;
991 }
992 }
993
994 // bottom & top lines, number of segments: 2*n
995 for (i = 0; i < 2; i++) {
996 indx2 = i * (nz - 1) * 2 * n;
997 for (j = 0; j < n; j++) {
998 buff.fSegs[indx++] = c;
999 buff.fSegs[indx++] = indx2 + j;
1000 buff.fSegs[indx++] = indx2 + n + j;
1001 }
1002 }
1003
1004 // inside & outside cylinders, number of segments: 2*(nz-1)*n
1005 for (i = 0; i < (nz - 1); i++) {
1006 // inside cylinder
1007 indx2 = i * n * 2;
1008 for (j = 0; j < n; j++) {
1009 buff.fSegs[indx++] = c + 2;
1010 buff.fSegs[indx++] = indx2 + j;
1011 buff.fSegs[indx++] = indx2 + n * 2 + j;
1012 }
1013 // outside cylinder
1014 indx2 = i * n * 2 + n;
1015 for (j = 0; j < n; j++) {
1016 buff.fSegs[indx++] = c + 3;
1017 buff.fSegs[indx++] = indx2 + j;
1018 buff.fSegs[indx++] = indx2 + n * 2 + j;
1019 }
1020 }
1021
1022 // left & right sections, number of segments: 2*(nz-2)
1023 // special case number of segments: 0
1024 if (!specialCase) {
1025 for (i = 1; i < (nz - 1); i++) {
1026 for (j = 0; j < 2; j++) {
1027 buff.fSegs[indx++] = c;
1028 buff.fSegs[indx++] = 2 * i * n + j * (n - 1);
1029 buff.fSegs[indx++] = (2 * i + 1) * n + j * (n - 1);
1030 }
1031 }
1032 }
1033
1034 Int_t m = n - 1 + (specialCase ? 1 : 0);
1035 indx = 0;
1036
1037 // bottom & top, number of polygons: 2*(n-1)
1038 // special case number of polygons: 2*n
1039 for (j = 0; j < n - 1; j++) {
1040 buff.fPols[indx++] = c + 3;
1041 buff.fPols[indx++] = 4;
1042 buff.fPols[indx++] = 2 * nz * m + j;
1043 buff.fPols[indx++] = m + j;
1044 buff.fPols[indx++] = 2 * nz * m + j + 1;
1045 buff.fPols[indx++] = j;
1046 }
1047 for (j = 0; j < n - 1; j++) {
1048 buff.fPols[indx++] = c + 3;
1049 buff.fPols[indx++] = 4;
1050 buff.fPols[indx++] = 2 * nz * m + n + j;
1051 buff.fPols[indx++] = (nz * 2 - 2) * m + j;
1052 buff.fPols[indx++] = 2 * nz * m + n + j + 1;
1053 buff.fPols[indx++] = (nz * 2 - 2) * m + m + j;
1054 }
1055 if (specialCase) {
1056 buff.fPols[indx++] = c + 3;
1057 buff.fPols[indx++] = 4;
1058 buff.fPols[indx++] = 2 * nz * m + j;
1059 buff.fPols[indx++] = m + j;
1060 buff.fPols[indx++] = 2 * nz * m;
1061 buff.fPols[indx++] = j;
1062
1063 buff.fPols[indx++] = c + 3;
1064 buff.fPols[indx++] = 4;
1065 buff.fPols[indx++] = 2 * nz * m + n + j;
1066 buff.fPols[indx++] = (nz * 2 - 2) * m + m + j;
1067 buff.fPols[indx++] = 2 * nz * m + n;
1068 buff.fPols[indx++] = (nz * 2 - 2) * m + j;
1069 }
1070
1071 // inside & outside, number of polygons: (nz-1)*2*(n-1)
1072 for (k = 0; k < (nz - 1); k++) {
1073 for (j = 0; j < n - 1; j++) {
1074 buff.fPols[indx++] = c;
1075 buff.fPols[indx++] = 4;
1076 buff.fPols[indx++] = 2 * k * m + j;
1077 buff.fPols[indx++] = nz * 2 * m + (2 * k + 2) * n + j + 1;
1078 buff.fPols[indx++] = (2 * k + 2) * m + j;
1079 buff.fPols[indx++] = nz * 2 * m + (2 * k + 2) * n + j;
1080 }
1081 for (j = 0; j < n - 1; j++) {
1082 buff.fPols[indx++] = c + 1;
1083 buff.fPols[indx++] = 4;
1084 buff.fPols[indx++] = (2 * k + 1) * m + j;
1085 buff.fPols[indx++] = nz * 2 * m + (2 * k + 3) * n + j;
1086 buff.fPols[indx++] = (2 * k + 3) * m + j;
1087 buff.fPols[indx++] = nz * 2 * m + (2 * k + 3) * n + j + 1;
1088 }
1089 if (specialCase) {
1090 buff.fPols[indx++] = c;
1091 buff.fPols[indx++] = 4;
1092 buff.fPols[indx++] = 2 * k * m + j;
1093 buff.fPols[indx++] = nz * 2 * m + (2 * k + 2) * n;
1094 buff.fPols[indx++] = (2 * k + 2) * m + j;
1095 buff.fPols[indx++] = nz * 2 * m + (2 * k + 2) * n + j;
1096
1097 buff.fPols[indx++] = c + 1;
1098 buff.fPols[indx++] = 4;
1099 buff.fPols[indx++] = (2 * k + 1) * m + j;
1100 buff.fPols[indx++] = nz * 2 * m + (2 * k + 3) * n + j;
1101 buff.fPols[indx++] = (2 * k + 3) * m + j;
1102 buff.fPols[indx++] = nz * 2 * m + (2 * k + 3) * n;
1103 }
1104 }
1105
1106 // left & right sections, number of polygons: 2*(nz-1)
1107 // special case number of polygons: 0
1108 if (!specialCase) {
1109 indx2 = nz * 2 * (n - 1);
1110 for (k = 0; k < (nz - 1); k++) {
1111 buff.fPols[indx++] = c + 2;
1112 buff.fPols[indx++] = 4;
1113 buff.fPols[indx++] = k == 0 ? indx2 : indx2 + 2 * nz * n + 2 * (k - 1);
1114 buff.fPols[indx++] = indx2 + 2 * (k + 1) * n;
1115 buff.fPols[indx++] = indx2 + 2 * nz * n + 2 * k;
1116 buff.fPols[indx++] = indx2 + (2 * k + 3) * n;
1117
1118 buff.fPols[indx++] = c + 2;
1119 buff.fPols[indx++] = 4;
1120 buff.fPols[indx++] = k == 0 ? indx2 + n - 1 : indx2 + 2 * nz * n + 2 * (k - 1) + 1;
1121 buff.fPols[indx++] = indx2 + (2 * k + 3) * n + n - 1;
1122 buff.fPols[indx++] = indx2 + 2 * nz * n + 2 * k + 1;
1123 buff.fPols[indx++] = indx2 + 2 * (k + 1) * n + n - 1;
1124 }
1125 buff.fPols[indx - 8] = indx2 + n;
1126 buff.fPols[indx - 2] = indx2 + 2 * n - 1;
1127 }
1128}
1129
1130////////////////////////////////////////////////////////////////////////////////
1131/// Fill TBuffer3D structure for segments and polygons, when no inner surface exists
1132
1134{
1135 const Int_t n = gGeoManager->GetNsegments() + 1;
1136 const Int_t nz = GetNz();
1137 const Int_t nbPnts = nz * n + 2;
1138
1139 if ((nz < 2) || (nbPnts <= 0) || (n < 2))
1140 return;
1141
1142 Int_t c = GetBasicColor();
1143
1144 Int_t indx = 0, indx1 = 0, indx2 = 0, i, j;
1145
1146 // outside circles, number of segments: nz*n
1147 for (i = 0; i < nz; i++) {
1148 indx2 = i * n;
1149 for (j = 1; j < n; j++) {
1150 buff.fSegs[indx++] = c;
1151 buff.fSegs[indx++] = indx2 + j - 1;
1152 buff.fSegs[indx++] = indx2 + j % (n - 1);
1153 }
1154 }
1155
1156 indx2 = 0;
1157 // bottom lines
1158 for (j = 0; j < n; j++) {
1159 buff.fSegs[indx++] = c;
1160 buff.fSegs[indx++] = indx2 + j % (n - 1);
1161 buff.fSegs[indx++] = nbPnts - 2;
1162 }
1163
1164 indx2 = (nz - 1) * n;
1165 // top lines
1166 for (j = 0; j < n; j++) {
1167 buff.fSegs[indx++] = c;
1168 buff.fSegs[indx++] = indx2 + j % (n - 1);
1169 buff.fSegs[indx++] = nbPnts - 1;
1170 }
1171
1172 // outside cylinders, number of segments: (nz-1)*n
1173 for (i = 0; i < (nz - 1); i++) {
1174 // outside cylinder
1175 indx2 = i * n;
1176 for (j = 0; j < n; j++) {
1177 buff.fSegs[indx++] = c;
1178 buff.fSegs[indx++] = indx2 + j % (n - 1);
1179 buff.fSegs[indx++] = indx2 + n + j % (n - 1);
1180 }
1181 }
1182
1183 indx = 0;
1184
1185 // bottom cap
1186 indx1 = 0; // start of first z layer
1187 indx2 = nz * (n - 1);
1188 for (j = 0; j < n - 1; j++) {
1189 buff.fPols[indx++] = c;
1190 buff.fPols[indx++] = 3;
1191 buff.fPols[indx++] = indx1 + j;
1192 buff.fPols[indx++] = indx2 + j + 1;
1193 buff.fPols[indx++] = indx2 + j;
1194 }
1195
1196 // top cap
1197 indx1 = (nz - 1) * (n - 1); // start last z layer
1198 indx2 = nz * (n - 1) + n;
1199 for (j = 0; j < n - 1; j++) {
1200 buff.fPols[indx++] = c;
1201 buff.fPols[indx++] = 3;
1202 buff.fPols[indx++] = indx1 + j; // last z layer
1203 buff.fPols[indx++] = indx2 + j;
1204 buff.fPols[indx++] = indx2 + j + 1;
1205 }
1206
1207 // outside, number of polygons: (nz-1)*(n-1)
1208 for (Int_t k = 0; k < (nz - 1); k++) {
1209 indx1 = k * (n - 1);
1210 indx2 = nz * (n - 1) + n * 2 + k * n;
1211 for (j = 0; j < n - 1; j++) {
1212 buff.fPols[indx++] = c;
1213 buff.fPols[indx++] = 4;
1214 buff.fPols[indx++] = indx1 + j;
1215 buff.fPols[indx++] = indx2 + j;
1216 buff.fPols[indx++] = indx1 + j + (n - 1);
1217 buff.fPols[indx++] = indx2 + j + 1;
1218 }
1219 }
1220}
1221
1222////////////////////////////////////////////////////////////////////////////////
1223/// Compute safety from POINT to segment between planes ipl, ipl+1 within safmin.
1224
1226{
1227 if (ipl < 0 || ipl > fNz - 2)
1228 return (safmin + 1.); // error in input plane
1229 // Get info about segment.
1230 Double_t dz = 0.5 * (fZ[ipl + 1] - fZ[ipl]);
1231 if (dz < 1E-9)
1232 return 1E9; // radius-changing segment
1233 Double_t ptnew[3];
1234 memcpy(ptnew, point, 3 * sizeof(Double_t));
1235 ptnew[2] -= 0.5 * (fZ[ipl] + fZ[ipl + 1]);
1237 if (safe > safmin)
1238 return TGeoShape::Big(); // means: stop checking further segments
1241 Double_t rmin2 = fRmin[ipl + 1];
1242 Double_t rmax2 = fRmax[ipl + 1];
1244 ? kTRUE
1245 : kFALSE;
1246 if (!fFullPhi) {
1247 if (is_tube)
1249 else
1251 } else {
1252 if (is_tube)
1254 else
1256 }
1257 if (safe < 0)
1258 safe = 0;
1259 return safe;
1260}
1261
1262////////////////////////////////////////////////////////////////////////////////
1263/// computes the closest distance from given point to this shape, according
1264/// to option. The matching point on the shape is stored in spoint.
1265/// localize the Z segment
1266
1268{
1270 Double_t dz;
1271 Int_t ipl, iplane;
1272
1273 if (in) {
1274 //---> point is inside pcon
1275 ipl = TMath::BinarySearch(fNz, fZ, point[2]);
1276 if (ipl == (fNz - 1))
1277 return 0; // point on last Z boundary
1278 if (ipl < 0)
1279 return 0; // point on first Z boundary
1280 if (ipl > 0 && TGeoShape::IsSameWithinTolerance(fZ[ipl - 1], fZ[ipl]) &&
1281 TGeoShape::IsSameWithinTolerance(point[2], fZ[ipl - 1]))
1282 ipl--;
1283 dz = 0.5 * (fZ[ipl + 1] - fZ[ipl]);
1284 if (dz < 1E-8) {
1285 // Point on a segment-changing plane
1286 safmin = TMath::Min(point[2] - fZ[ipl - 1], fZ[ipl + 2] - point[2]);
1288 if (fDphi < 360)
1290 if (saftmp < safmin)
1291 safmin = saftmp;
1292 Double_t radius = TMath::Sqrt(point[0] * point[0] + point[1] * point[1]);
1293 if (fRmin[ipl] > 0)
1295 if (fRmin[ipl + 1] > 0)
1299 if (safmin < 0)
1300 safmin = 0;
1301 return safmin;
1302 }
1303 // Check safety for current segment
1304 safmin = SafetyToSegment(point, ipl);
1305 if (safmin > 1E10) {
1306 // something went wrong - point is not inside current segment
1307 return 0.;
1308 }
1309 if (safmin < 1E-6)
1310 return TMath::Abs(safmin); // point on radius-changing plane
1311 // check increasing iplanes
1312 /*
1313 iplane = ipl+1;
1314 saftmp = 0.;
1315 while ((iplane<fNz-1) && saftmp<1E10) {
1316 saftmp = TMath::Abs(SafetyToSegment(point,iplane,kFALSE,safmin));
1317 if (saftmp<safmin) safmin=saftmp;
1318 iplane++;
1319 }
1320 // now decreasing nplanes
1321 iplane = ipl-1;
1322 saftmp = 0.;
1323 while ((iplane>=0) && saftmp<1E10) {
1324 saftmp = TMath::Abs(SafetyToSegment(point,iplane,kFALSE,safmin));
1325 if (saftmp<safmin) safmin=saftmp;
1326 iplane--;
1327 }
1328 */
1329 return safmin;
1330 }
1331 //---> point is outside pcon
1332 ipl = TMath::BinarySearch(fNz, fZ, point[2]);
1333 if (ipl < 0)
1334 ipl = 0;
1335 else if (ipl == fNz - 1)
1336 ipl = fNz - 2;
1337 dz = 0.5 * (fZ[ipl + 1] - fZ[ipl]);
1338 if (dz < 1E-8 && (ipl + 2 < fNz)) {
1339 ipl++;
1340 dz = 0.5 * (fZ[ipl + 1] - fZ[ipl]);
1341 }
1342 // Check safety for current segment
1343 safmin = SafetyToSegment(point, ipl, kFALSE);
1344 if (safmin < 1E-6)
1345 return TMath::Abs(safmin); // point on radius-changing plane
1346 saftmp = 0.;
1347 // check increasing iplanes
1348 iplane = ipl + 1;
1349 saftmp = 0.;
1350 while ((iplane < fNz - 1) && saftmp < 1E10) {
1352 if (saftmp < safmin)
1353 safmin = saftmp;
1354 iplane++;
1355 }
1356 // now decreasing nplanes
1357 iplane = ipl - 1;
1358 saftmp = 0.;
1359 while ((iplane >= 0) && saftmp < 1E10) {
1361 if (saftmp < safmin)
1362 safmin = saftmp;
1363 iplane--;
1364 }
1365 return safmin;
1366}
1367
1368////////////////////////////////////////////////////////////////////////////////
1369/// Save a primitive as a C++ statement(s) on output stream "out".
1370
1371void TGeoPcon::SavePrimitive(std::ostream &out, Option_t * /*option*/ /*= ""*/)
1372{
1374 return;
1375 out << " // Shape: " << GetName() << " type: " << ClassName() << std::endl;
1376 out << " phi1 = " << fPhi1 << ";" << std::endl;
1377 out << " dphi = " << fDphi << ";" << std::endl;
1378 out << " nz = " << fNz << ";" << std::endl;
1379 out << " auto " << GetPointerName() << " = new TGeoPcon(\"" << GetName() << "\", phi1, dphi, nz);" << std::endl;
1380 for (Int_t i = 0; i < fNz; i++) {
1381 out << " z = " << fZ[i] << ";" << std::endl;
1382 out << " rmin = " << fRmin[i] << ";" << std::endl;
1383 out << " rmax = " << fRmax[i] << ";" << std::endl;
1384 out << " " << GetPointerName() << "->DefineSection(" << i << ", z,rmin,rmax);" << std::endl;
1385 }
1387}
1388
1389////////////////////////////////////////////////////////////////////////////////
1390/// Set polycone dimensions starting from an array.
1391
1393{
1394 fPhi1 = param[0];
1395 while (fPhi1 < 0)
1396 fPhi1 += 360.;
1397 fDphi = param[1];
1398 fNz = (Int_t)param[2];
1399 if (fNz < 2) {
1400 Error("SetDimensions", "Pcon %s: Number of Z sections must be > 2", GetName());
1401 return;
1402 }
1403 if (fRmin)
1404 delete[] fRmin;
1405 if (fRmax)
1406 delete[] fRmax;
1407 if (fZ)
1408 delete[] fZ;
1409 fRmin = new Double_t[fNz];
1410 fRmax = new Double_t[fNz];
1411 fZ = new Double_t[fNz];
1412 memset(fRmin, 0, fNz * sizeof(Double_t));
1413 memset(fRmax, 0, fNz * sizeof(Double_t));
1414 memset(fZ, 0, fNz * sizeof(Double_t));
1416 fFullPhi = kTRUE;
1418 Double_t phi2 = phi1 + fDphi;
1419 Double_t phim = 0.5 * (phi1 + phi2);
1427
1428 for (Int_t i = 0; i < fNz; i++)
1429 DefineSection(i, param[3 + 3 * i], param[4 + 3 * i], param[5 + 3 * i]);
1430}
1431
1432////////////////////////////////////////////////////////////////////////////////
1433/// create polycone mesh points
1434
1436{
1437 Double_t phi, dphi;
1439 dphi = fDphi / (n - 1);
1440 Int_t i, j;
1441 Int_t indx = 0;
1442
1444
1445 if (points) {
1446 for (i = 0; i < fNz; i++) {
1447 if (hasInside)
1448 for (j = 0; j < n; j++) {
1449 phi = (fPhi1 + j * dphi) * TMath::DegToRad();
1450 points[indx++] = fRmin[i] * TMath::Cos(phi);
1451 points[indx++] = fRmin[i] * TMath::Sin(phi);
1452 points[indx++] = fZ[i];
1453 }
1454 for (j = 0; j < n; j++) {
1455 phi = (fPhi1 + j * dphi) * TMath::DegToRad();
1456 points[indx++] = fRmax[i] * TMath::Cos(phi);
1457 points[indx++] = fRmax[i] * TMath::Sin(phi);
1458 points[indx++] = fZ[i];
1459 }
1460 }
1461 if (!hasInside) {
1462 points[indx++] = 0;
1463 points[indx++] = 0;
1464 points[indx++] = fZ[0];
1465
1466 points[indx++] = 0;
1467 points[indx++] = 0;
1468 points[indx++] = fZ[GetNz() - 1];
1469 }
1470 }
1471}
1472
1473////////////////////////////////////////////////////////////////////////////////
1474/// create polycone mesh points
1475
1477{
1478 Double_t phi, dphi;
1480 dphi = fDphi / (n - 1);
1481 Int_t i, j;
1482 Int_t indx = 0;
1483
1485
1486 if (points) {
1487 for (i = 0; i < fNz; i++) {
1488 if (hasInside)
1489 for (j = 0; j < n; j++) {
1490 phi = (fPhi1 + j * dphi) * TMath::DegToRad();
1491 points[indx++] = fRmin[i] * TMath::Cos(phi);
1492 points[indx++] = fRmin[i] * TMath::Sin(phi);
1493 points[indx++] = fZ[i];
1494 }
1495 for (j = 0; j < n; j++) {
1496 phi = (fPhi1 + j * dphi) * TMath::DegToRad();
1497 points[indx++] = fRmax[i] * TMath::Cos(phi);
1498 points[indx++] = fRmax[i] * TMath::Sin(phi);
1499 points[indx++] = fZ[i];
1500 }
1501 }
1502 if (!hasInside) {
1503 points[indx++] = 0;
1504 points[indx++] = 0;
1505 points[indx++] = fZ[0];
1506
1507 points[indx++] = 0;
1508 points[indx++] = 0;
1509 points[indx++] = fZ[GetNz() - 1];
1510 }
1511 }
1512}
1513////////////////////////////////////////////////////////////////////////////////
1514/// Return number of vertices of the mesh representation
1515
1517{
1520 return nvert;
1521}
1522
1523////////////////////////////////////////////////////////////////////////////////
1524/// fill size of this 3-D object
1525
1526void TGeoPcon::Sizeof3D() const {}
1527
1528////////////////////////////////////////////////////////////////////////////////
1529/// Returns true when pgon has internal surface
1530/// It will be only disabled when all Rmin values are 0
1531
1533{
1534 // only when full 360 is used, internal part can be excluded
1536 if (!specialCase)
1537 return kTRUE;
1538
1539 for (Int_t i = 0; i < GetNz(); i++)
1540 if (fRmin[i] > 0.)
1541 return kTRUE;
1542
1543 return kFALSE;
1544}
1545
1546////////////////////////////////////////////////////////////////////////////////
1547/// Returns numbers of vertices, segments and polygons composing the shape mesh.
1548
1550{
1551 nvert = nsegs = npols = 0;
1552
1554 Int_t nz = GetNz();
1555 if (nz < 2)
1556 return;
1557
1558 if (HasInsideSurface()) {
1560 nvert = nz * 2 * n;
1561 nsegs = 4 * (nz * n - 1 + (specialCase ? 1 : 0));
1562 npols = 2 * (nz * n - 1 + (specialCase ? 1 : 0));
1563 } else {
1564 nvert = nz * n + 2;
1565 nsegs = nz * (n - 1) + n * 2 + (nz - 1) * n;
1566 npols = 2 * (n - 1) + (nz - 1) * (n - 1);
1567 }
1568}
1569
1570////////////////////////////////////////////////////////////////////////////////
1571/// Fills a static 3D buffer and returns a reference.
1572
1574{
1575 static TBuffer3D buffer(TBuffer3DTypes::kGeneric);
1576
1578
1582 if (nbPnts > 0) {
1583 if (buffer.SetRawSizes(nbPnts, 3 * nbPnts, nbSegs, 3 * nbSegs, nbPols, 6 * nbPols)) {
1585 }
1586 }
1587 }
1588 // TODO: Push down to TGeoShape?? Would have to do raw sizes set first..
1589 // can rest of TGeoShape be deferred until after this?
1591 SetPoints(buffer.fPnts);
1592 if (!buffer.fLocalFrame) {
1593 TransformPoints(buffer.fPnts, buffer.NbPnts());
1594 }
1595
1596 SetSegsAndPols(buffer);
1598 }
1599
1600 return buffer;
1601}
1602
1603////////////////////////////////////////////////////////////////////////////////
1604/// Stream an object of class TGeoPcon.
1605
1607{
1608 if (R__b.IsReading()) {
1609 R__b.ReadClassBuffer(TGeoPcon::Class(), this);
1611 fFullPhi = kTRUE;
1613 Double_t phi2 = phi1 + fDphi;
1614 Double_t phim = 0.5 * (phi1 + phi2);
1622 } else {
1623 R__b.WriteClassBuffer(TGeoPcon::Class(), this);
1624 }
1625}
1626
1627////////////////////////////////////////////////////////////////////////////////
1628/// Check the inside status for each of the points in the array.
1629/// Input: Array of point coordinates + vector size
1630/// Output: Array of Booleans for the inside of each point
1631
1633{
1634 for (Int_t i = 0; i < vecsize; i++)
1635 inside[i] = Contains(&points[3 * i]);
1636}
1637
1638////////////////////////////////////////////////////////////////////////////////
1639/// Compute the normal for an array o points so that norm.dot.dir is positive
1640/// Input: Arrays of point coordinates and directions + vector size
1641/// Output: Array of normal directions
1642
1644{
1645 for (Int_t i = 0; i < vecsize; i++)
1646 ComputeNormal(&points[3 * i], &dirs[3 * i], &norms[3 * i]);
1647}
1648
1649////////////////////////////////////////////////////////////////////////////////
1650/// Compute distance from array of input points having directions specified by dirs. Store output in dists
1651
1653 Double_t *step) const
1654{
1655 for (Int_t i = 0; i < vecsize; i++)
1656 dists[i] = DistFromInside(&points[3 * i], &dirs[3 * i], 3, step[i]);
1657}
1658
1659////////////////////////////////////////////////////////////////////////////////
1660/// Compute distance from array of input points having directions specified by dirs. Store output in dists
1661
1663 Double_t *step) const
1664{
1665 for (Int_t i = 0; i < vecsize; i++)
1666 dists[i] = DistFromOutside(&points[3 * i], &dirs[3 * i], 3, step[i]);
1667}
1668
1669////////////////////////////////////////////////////////////////////////////////
1670/// Compute safe distance from each of the points in the input array.
1671/// Input: Array of point coordinates, array of statuses for these points, size of the arrays
1672/// Output: Safety values
1673
1675{
1676 for (Int_t i = 0; i < vecsize; i++)
1677 safe[i] = Safety(&points[3 * i], inside[i]);
1678}
#define c(i)
Definition RSha256.hxx:101
#define e(i)
Definition RSha256.hxx:103
int Int_t
Signed integer 4 bytes (int)
Definition RtypesCore.h:59
float Float_t
Float 4 bytes (float)
Definition RtypesCore.h:71
constexpr Bool_t kFALSE
Definition RtypesCore.h:108
double Double_t
Double 8 bytes.
Definition RtypesCore.h:73
constexpr Bool_t kTRUE
Definition RtypesCore.h:107
const char Option_t
Option string (const char)
Definition RtypesCore.h:80
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
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 r
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize id
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
R__EXTERN TGeoManager * gGeoManager
float xmin
float ymin
float xmax
float ymax
Generic 3D primitive description class.
Definition TBuffer3D.h:18
UInt_t NbPnts() const
Definition TBuffer3D.h:80
Bool_t SectionsValid(UInt_t mask) const
Definition TBuffer3D.h:67
void SetSectionsValid(UInt_t mask)
Definition TBuffer3D.h:65
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.
Double_t * fPnts
Definition TBuffer3D.h:113
Buffer base class used for serializing objects.
Definition TBuffer.h:43
Box class.
Definition TGeoBBox.h:17
void FillBuffer3D(TBuffer3D &buffer, Int_t reqSections, Bool_t localFrame) const override
Fills the supplied buffer, with sections in desired frame See TBuffer3D.h for explanation of sections...
Double_t fDX
Definition TGeoBBox.h:20
Double_t DistFromOutside(const Double_t *point, const Double_t *dir, Int_t iact=1, Double_t step=TGeoShape::Big(), Double_t *safe=nullptr) const override
Compute distance from outside point to surface of the box.
Definition TGeoBBox.cxx:432
Double_t fOrigin[3]
Definition TGeoBBox.h:23
void InspectShape() const override
Prints shape parameters.
Definition TGeoBBox.cxx:810
Double_t fDY
Definition TGeoBBox.h:21
Double_t fDZ
Definition TGeoBBox.h:22
A cone segment is a cone having a range in phi.
Definition TGeoCone.h:99
static void ComputeNormalS(const Double_t *point, const Double_t *dir, Double_t *norm, Double_t dz, Double_t rmin1, Double_t rmax1, Double_t rmin2, Double_t rmax2, Double_t c1, Double_t s1, Double_t c2, Double_t s2)
Compute normal to closest surface from POINT.
Double_t Capacity() const override
Computes capacity of the shape in [length^3].
static Double_t DistFromOutsideS(const Double_t *point, const Double_t *dir, Double_t dz, Double_t rmin1, Double_t rmax1, Double_t rmin2, Double_t rmax2, Double_t c1, Double_t s1, Double_t c2, Double_t s2, Double_t cm, Double_t sm, Double_t cdfi)
compute distance from outside point to surface of arbitrary tube
static Double_t SafetyS(const Double_t *point, Bool_t in, Double_t dz, Double_t rmin1, Double_t rmax1, Double_t rmin2, Double_t rmax2, Double_t phi1, Double_t phi2, Int_t skipz=0)
Static method to compute the closest distance from given point to this shape.
static Double_t DistFromInsideS(const Double_t *point, const Double_t *dir, Double_t dz, Double_t rmin1, Double_t rmax1, Double_t rmin2, Double_t rmax2, Double_t c1, Double_t s1, Double_t c2, Double_t s2, Double_t cm, Double_t sm, Double_t cdfi)
compute distance from inside point to surface of the tube segment
The cones are defined by 5 parameters:
Definition TGeoCone.h:17
static void ComputeNormalS(const Double_t *point, const Double_t *dir, Double_t *norm, Double_t dz, Double_t rmin1, Double_t rmax1, Double_t rmin2, Double_t rmax2)
Compute normal to closest surface from POINT.
Definition TGeoCone.cxx:233
static Double_t DistFromInsideS(const Double_t *point, const Double_t *dir, Double_t dz, Double_t rmin1, Double_t rmax1, Double_t rmin2, Double_t rmax2)
Compute distance from inside point to surface of the cone (static) Boundary safe algorithm.
Definition TGeoCone.cxx:286
static Double_t DistFromOutsideS(const Double_t *point, const Double_t *dir, Double_t dz, Double_t rmin1, Double_t rmax1, Double_t rmin2, Double_t rmax2)
Compute distance from outside point to surface of the tube Boundary safe algorithm.
Definition TGeoCone.cxx:388
static Double_t SafetyS(const Double_t *point, Bool_t in, Double_t dz, Double_t rmin1, Double_t rmax1, Double_t rmin2, Double_t rmax2, Int_t skipz=0)
computes the closest distance from given point to this shape, according to option.
Definition TGeoCone.cxx:940
TGeoVolumeMulti * MakeVolumeMulti(const char *name, TGeoMedium *medium)
Make a TGeoVolumeMulti handling a list of volumes.
TObjArray * GetListOfShapes() const
Int_t GetNsegments() const
Get number of segments approximating circles.
Node containing an offset.
Definition TGeoNode.h:184
a cylindrical phi divison pattern
base finder class for patterns. A pattern is specifying a division type
a Z axis divison pattern
A polycone is represented by a sequence of tubes/cones, glued together at defined Z planes.
Definition TGeoPcon.h:17
Double_t fSm
Cosine of (phi1+phi2)/2.
Definition TGeoPcon.h:32
Double_t * GetRmax() const
Definition TGeoPcon.h:82
void DistFromInside_v(const Double_t *points, const Double_t *dirs, Double_t *dists, Int_t vecsize, Double_t *step) const override
Compute distance from array of input points having directions specified by dirs. Store output in dist...
Double_t GetDphi() const
Definition TGeoPcon.h:77
Double_t SafetyToSegment(const Double_t *point, Int_t ipl, Bool_t in=kTRUE, Double_t safmin=TGeoShape::Big()) const
Compute safety from POINT to segment between planes ipl, ipl+1 within safmin.
void ComputeNormal(const Double_t *point, const Double_t *dir, Double_t *norm) const override
Compute normal to closest surface from POINT.
Definition TGeoPcon.cxx:365
Double_t * fRmax
Definition TGeoPcon.h:24
void SavePrimitive(std::ostream &out, Option_t *option="") override
Save a primitive as a C++ statement(s) on output stream "out".
void SetPoints(Double_t *points) const override
create polycone mesh points
Double_t DistFromOutside(const Double_t *point, const Double_t *dir, Int_t iact=1, Double_t step=TGeoShape::Big(), Double_t *safe=nullptr) const override
compute distance from outside point to surface of the tube
Definition TGeoPcon.cxx:629
TBuffer3D * MakeBuffer3D() const override
Creates a TBuffer3D describing this shape.
Definition TGeoPcon.cxx:936
Bool_t Contains(const Double_t *point) const override
test if point is inside this shape check total z range
Definition TGeoPcon.cxx:435
const char * GetAxisName(Int_t iaxis) const override
Returns name of axis IAXIS.
Definition TGeoPcon.cxx:823
Double_t * fRmin
Definition TGeoPcon.h:23
Double_t Capacity() const override
Computes capacity of the shape in [length^3].
Definition TGeoPcon.cxx:263
void Streamer(TBuffer &) override
Stream an object of class TGeoPcon.
Int_t GetNmeshVertices() const override
Return number of vertices of the mesh representation.
void Contains_v(const Double_t *points, Bool_t *inside, Int_t vecsize) const override
Check the inside status for each of the points in the array.
Int_t fNz
Definition TGeoPcon.h:20
Double_t * fZ
Definition TGeoPcon.h:25
virtual void DefineSection(Int_t snum, Double_t z, Double_t rmin, Double_t rmax)
Defines z position of a section plane, rmin and rmax at this z.
Definition TGeoPcon.cxx:683
Double_t GetAxisRange(Int_t iaxis, Double_t &xlo, Double_t &xhi) const override
Get range of shape for a given axis.
Definition TGeoPcon.cxx:836
Double_t fC1
Full phi range flag.
Definition TGeoPcon.h:27
void InspectShape() const override
print shape parameters
Definition TGeoPcon.cxx:920
void SetDimensions(Double_t *param) override
Set polycone dimensions starting from an array.
Double_t fCdphi
Sine of (phi1+phi2)/2.
Definition TGeoPcon.h:33
Bool_t fFullPhi
Definition TGeoPcon.h:26
Double_t fS1
Cosine of phi1.
Definition TGeoPcon.h:28
TGeoVolume * Divide(TGeoVolume *voldiv, const char *divname, Int_t iaxis, Int_t ndiv, Double_t start, Double_t step) override
Divide this polycone shape belonging to volume "voldiv" into ndiv volumes called divname,...
Definition TGeoPcon.cxx:733
Double_t DistToSegZ(const Double_t *point, const Double_t *dir, Int_t &iz) const
compute distance to a pcon Z slice. Segment iz must be valid
Definition TGeoPcon.cxx:578
Double_t fCm
Sine of phi1+dphi.
Definition TGeoPcon.h:31
Int_t DistancetoPrimitive(Int_t px, Int_t py) override
compute closest distance from point px,py to each corner
Definition TGeoPcon.cxx:486
~TGeoPcon() override
destructor
Definition TGeoPcon.cxx:244
Double_t * GetZ() const
Definition TGeoPcon.h:84
static TClass * Class()
Double_t DistFromInside(const Double_t *point, const Double_t *dir, Int_t iact=1, Double_t step=TGeoShape::Big(), Double_t *safe=nullptr) const override
compute distance from inside point to surface of the polycone
Definition TGeoPcon.cxx:497
Bool_t HasInsideSurface() const
Returns true when pgon has internal surface It will be only disabled when all Rmin values are 0.
virtual Int_t GetNsegments() const
Returns number of segments on each mesh circle segment.
Definition TGeoPcon.cxx:719
Double_t fPhi1
Definition TGeoPcon.h:21
void GetMeshNumbers(Int_t &nvert, Int_t &nsegs, Int_t &npols) const override
Returns numbers of vertices, segments and polygons composing the shape mesh.
Double_t fS2
Cosine of phi1+dphi.
Definition TGeoPcon.h:30
void SetSegsAndPolsNoInside(TBuffer3D &buff) const
Fill TBuffer3D structure for segments and polygons, when no inner surface exists.
Double_t fDphi
Definition TGeoPcon.h:22
void Safety_v(const Double_t *points, const Bool_t *inside, Double_t *safe, Int_t vecsize) const override
Compute safe distance from each of the points in the input array.
void ComputeBBox() override
compute bounding box of the pcon Check if the sections are in increasing Z order
Definition TGeoPcon.cxx:287
Double_t fC2
Sine of phi1.
Definition TGeoPcon.h:29
void Sizeof3D() const override
fill size of this 3-D object
void SetSegsAndPols(TBuffer3D &buff) const override
Fill TBuffer3D structure for segments and polygons.
Definition TGeoPcon.cxx:956
const TBuffer3D & GetBuffer3D(Int_t reqSections, Bool_t localFrame) const override
Fills a static 3D buffer and returns a reference.
void DistFromOutside_v(const Double_t *points, const Double_t *dirs, Double_t *dists, Int_t vecsize, Double_t *step) const override
Compute distance from array of input points having directions specified by dirs. Store output in dist...
Int_t GetNz() const
Definition TGeoPcon.h:78
void GetBoundingCylinder(Double_t *param) const override
Fill vector param[4] with the bounding cylinder parameters.
Definition TGeoPcon.cxx:860
Double_t * GetRmin() const
Definition TGeoPcon.h:80
TGeoPcon()
dummy ctor
Definition TGeoPcon.cxx:103
Double_t Safety(const Double_t *point, Bool_t in=kTRUE) const override
computes the closest distance from given point to this shape, according to option.
void ComputeNormal_v(const Double_t *points, const Double_t *dirs, Double_t *norms, Int_t vecsize) override
Compute the normal for an array o points so that norm.dot.dir is positive Input: Arrays of point coor...
Base abstract class for all shapes.
Definition TGeoShape.h:25
static Double_t Big()
Definition TGeoShape.h:94
Int_t GetBasicColor() const
Get the basic color (0-7).
void TransformPoints(Double_t *points, UInt_t NbPoints) const
Tranform a set of points (LocalToMaster)
void SetShapeBit(UInt_t f, Bool_t set)
Equivalent of TObject::SetBit.
static Double_t SafetyPhi(const Double_t *point, Bool_t in, Double_t phi1, Double_t phi2)
Static method to compute safety w.r.t a phi corner defined by cosines/sines of the angles phi1,...
static Bool_t IsSameWithinTolerance(Double_t a, Double_t b)
Check if two numbers differ with less than a tolerance.
const char * GetPointerName() const
Provide a pointer name containing uid.
Int_t ShapeDistancetoPrimitive(Int_t numpoints, Int_t px, Int_t py) const
Returns distance to shape primitive mesh.
const char * GetName() const override
Get the shape name.
@ kGeoClosedShape
Definition TGeoShape.h:59
@ kGeoSavePrimitive
Definition TGeoShape.h:64
static Double_t Tolerance()
Definition TGeoShape.h:97
A tube segment is a tube having a range in phi.
Definition TGeoTube.h:94
static Double_t DistFromInsideS(const Double_t *point, const Double_t *dir, Double_t rmin, Double_t rmax, Double_t dz, Double_t c1, Double_t s1, Double_t c2, Double_t s2, Double_t cm, Double_t sm, Double_t cdfi)
Compute distance from inside point to surface of the tube segment (static) Boundary safe algorithm.
static Double_t DistFromOutsideS(const Double_t *point, const Double_t *dir, Double_t rmin, Double_t rmax, Double_t dz, Double_t c1, Double_t s1, Double_t c2, Double_t s2, Double_t cm, Double_t sm, Double_t cdfi)
Static method to compute distance to arbitrary tube segment from outside point Boundary safe algorith...
static Double_t SafetyS(const Double_t *point, Bool_t in, Double_t rmin, Double_t rmax, Double_t dz, Double_t phi1, Double_t phi2, Int_t skipz=0)
Static method to compute the closest distance from given point to this shape.
static void ComputeNormalS(const Double_t *point, const Double_t *dir, Double_t *norm, Double_t rmin, Double_t rmax, Double_t dz, Double_t c1, Double_t s1, Double_t c2, Double_t s2)
Compute normal to closest surface from POINT.
Cylindrical tube class.
Definition TGeoTube.h:17
static Double_t DistFromOutsideS(const Double_t *point, const Double_t *dir, Double_t rmin, Double_t rmax, Double_t dz)
Static method to compute distance from outside point to a tube with given parameters Boundary safe al...
Definition TGeoTube.cxx:374
static Double_t SafetyS(const Double_t *point, Bool_t in, Double_t rmin, Double_t rmax, Double_t dz, Int_t skipz=0)
computes the closest distance from given point to this shape, according to option.
Definition TGeoTube.cxx:914
static void ComputeNormalS(const Double_t *point, const Double_t *dir, Double_t *norm, Double_t rmin, Double_t rmax, Double_t dz)
Compute normal to closest surface from POINT.
Definition TGeoTube.cxx:259
static Double_t DistFromInsideS(const Double_t *point, const Double_t *dir, Double_t rmin, Double_t rmax, Double_t dz)
Compute distance from inside point to surface of the tube (static) Boundary safe algorithm.
Definition TGeoTube.cxx:304
Volume families.
Definition TGeoVolume.h:266
TGeoVolume, TGeoVolumeMulti, TGeoVolumeAssembly are the volume classes.
Definition TGeoVolume.h:43
Int_t IndexOf(const TObject *obj) const override
R__ALWAYS_INLINE Bool_t TestBit(UInt_t f) const
Definition TObject.h:202
virtual const char * ClassName() const
Returns name of class to which the object belongs.
Definition TObject.cxx:226
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition TObject.cxx:1057
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
Definition TObject.cxx:864
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition TObject.cxx:1071
virtual void Fatal(const char *method, const char *msgfmt,...) const
Issue fatal error message.
Definition TObject.cxx:1099
Basic string class.
Definition TString.h:138
const char * Data() const
Definition TString.h:384
const Int_t n
Definition legend1.C:16
Long64_t LocMin(Long64_t n, const T *a)
Returns index of array with the minimum element.
Definition TMath.h:993
Short_t Max(Short_t a, Short_t b)
Returns the largest of a and b.
Definition TMathBase.h:251
T1 Sign(T1 a, T2 b)
Returns a value with the magnitude of a and the sign of b.
Definition TMathBase.h:176
Double_t ATan2(Double_t y, Double_t x)
Returns the principal value of the arc tangent of y/x, expressed in radians.
Definition TMath.h:657
Long64_t LocMax(Long64_t n, const T *a)
Returns index of array with the maximum element.
Definition TMath.h:1099
constexpr Double_t DegToRad()
Conversion from degree to radian: .
Definition TMath.h:82
Double_t Sqrt(Double_t x)
Returns the square root of x.
Definition TMath.h:673
Short_t Min(Short_t a, Short_t b)
Returns the smallest of a and b.
Definition TMathBase.h:199
Double_t Cos(Double_t)
Returns the cosine of an angle of x radians.
Definition TMath.h:605
constexpr Double_t Pi()
Definition TMath.h:40
Double_t Sin(Double_t)
Returns the sine of an angle of x radians.
Definition TMath.h:599
Long64_t BinarySearch(Long64_t n, const T *array, T value)
Binary search in an array of n values to locate value.
Definition TMathBase.h:348
constexpr Double_t RadToDeg()
Conversion from radian to degree: .
Definition TMath.h:75
Short_t Abs(Short_t d)
Returns the absolute value of parameter Short_t d.
Definition TMathBase.h:124
TMarker m
Definition textangle.C:8