ROOT  6.06/09
Reference Guide
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 //_____________________________________________________________________________
14 // TGeoPcon - a polycone. It has at least 9 parameters :
15 // - the lower phi limit;
16 // - the range in phi;
17 // - the number of z planes (at least two) where the inner/outer
18 // radii are changing;
19 // - z coordinate, inner and outer radius for each z plane
20 //
21 //_____________________________________________________________________________
22 //Begin_Html
23 /*
24 <img src="gif/t_pcon.gif">
25 */
26 //End_Html
27 
28 //Begin_Html
29 /*
30 <img src="gif/t_pcondivPHI.gif">
31 */
32 //End_Html
33 
34 //Begin_Html
35 /*
36 <img src="gif/t_pcondivstepPHI.gif">
37 */
38 //End_Html
39 
40 //Begin_Html
41 /*
42 <img src="gif/t_pcondivstepZ.gif">
43 */
44 //End_Html
45 
46 #include "Riostream.h"
47 
48 #include "TGeoManager.h"
49 #include "TGeoVolume.h"
50 #include "TVirtualGeoPainter.h"
51 #include "TGeoTube.h"
52 #include "TGeoCone.h"
53 #include "TGeoPcon.h"
54 #include "TVirtualPad.h"
55 #include "TBuffer3D.h"
56 #include "TBuffer3DTypes.h"
57 #include "TMath.h"
58 
60 
61 ////////////////////////////////////////////////////////////////////////////////
62 /// dummy ctor
63 
65  :TGeoBBox(0, 0, 0),
66  fNz(0),
67  fPhi1(0.),
68  fDphi(0.),
69  fRmin(NULL),
70  fRmax(NULL),
71  fZ(NULL),
72  fFullPhi(kFALSE),
73  fC1(0.),
74  fS1(0.),
75  fC2(0.),
76  fS2(0.),
77  fCm(0.),
78  fSm(0.),
79  fCdphi(0.)
80 {
81  SetShapeBit(TGeoShape::kGeoPcon);
82 }
83 
84 ////////////////////////////////////////////////////////////////////////////////
85 /// Default constructor
86 
88  :TGeoBBox(0, 0, 0),
89  fNz(nz),
90  fPhi1(phi),
91  fDphi(dphi),
92  fRmin(NULL),
93  fRmax(NULL),
94  fZ(NULL),
95  fFullPhi(kFALSE),
96  fC1(0.),
97  fS1(0.),
98  fC2(0.),
99  fS2(0.),
100  fCm(0.),
101  fSm(0.),
102  fCdphi(0.)
103 {
105  while (fPhi1<0) fPhi1+=360.;
106  fRmin = new Double_t [nz];
107  fRmax = new Double_t [nz];
108  fZ = new Double_t [nz];
109  memset(fRmin, 0, nz*sizeof(Double_t));
110  memset(fRmax, 0, nz*sizeof(Double_t));
111  memset(fZ, 0, nz*sizeof(Double_t));
113  Double_t phi1 = fPhi1;
114  Double_t phi2 = phi1+fDphi;
115  Double_t phim = 0.5*(phi1+phi2);
116  fC1 = TMath::Cos(phi1*TMath::DegToRad());
117  fS1 = TMath::Sin(phi1*TMath::DegToRad());
118  fC2 = TMath::Cos(phi2*TMath::DegToRad());
119  fS2 = TMath::Sin(phi2*TMath::DegToRad());
120  fCm = TMath::Cos(phim*TMath::DegToRad());
121  fSm = TMath::Sin(phim*TMath::DegToRad());
122  fCdphi = TMath::Cos(0.5*fDphi*TMath::DegToRad());
123 }
124 
125 ////////////////////////////////////////////////////////////////////////////////
126 /// Default constructor
127 
128 TGeoPcon::TGeoPcon(const char *name, Double_t phi, Double_t dphi, Int_t nz)
129  :TGeoBBox(name, 0, 0, 0),
130  fNz(nz),
131  fPhi1(phi),
132  fDphi(dphi),
133  fRmin(NULL),
134  fRmax(NULL),
135  fZ(NULL),
136  fFullPhi(kFALSE),
137  fC1(0.),
138  fS1(0.),
139  fC2(0.),
140  fS2(0.),
141  fCm(0.),
142  fSm(0.),
143  fCdphi(0.)
144 {
146  while (fPhi1<0) fPhi1+=360.;
147  fRmin = new Double_t [nz];
148  fRmax = new Double_t [nz];
149  fZ = new Double_t [nz];
150  memset(fRmin, 0, nz*sizeof(Double_t));
151  memset(fRmax, 0, nz*sizeof(Double_t));
152  memset(fZ, 0, nz*sizeof(Double_t));
154  Double_t phi1 = fPhi1;
155  Double_t phi2 = phi1+fDphi;
156  Double_t phim = 0.5*(phi1+phi2);
157  fC1 = TMath::Cos(phi1*TMath::DegToRad());
158  fS1 = TMath::Sin(phi1*TMath::DegToRad());
159  fC2 = TMath::Cos(phi2*TMath::DegToRad());
160  fS2 = TMath::Sin(phi2*TMath::DegToRad());
161  fCm = TMath::Cos(phim*TMath::DegToRad());
162  fSm = TMath::Sin(phim*TMath::DegToRad());
163  fCdphi = TMath::Cos(0.5*fDphi*TMath::DegToRad());
164 }
165 
166 ////////////////////////////////////////////////////////////////////////////////
167 /// Default constructor in GEANT3 style
168 /// param[0] = phi1
169 /// param[1] = dphi
170 /// param[2] = nz
171 ///
172 /// param[3] = z1
173 /// param[4] = Rmin1
174 /// param[5] = Rmax1
175 /// ...
176 
178  :TGeoBBox(0, 0, 0),
179  fNz(0),
180  fPhi1(0.),
181  fDphi(0.),
182  fRmin(0),
183  fRmax(0),
184  fZ(0),
185  fFullPhi(kFALSE),
186  fC1(0.),
187  fS1(0.),
188  fC2(0.),
189  fS2(0.),
190  fCm(0.),
191  fSm(0.),
192  fCdphi(0.)
193 {
195  SetDimensions(param);
196  ComputeBBox();
197 }
198 
199 ////////////////////////////////////////////////////////////////////////////////
200 ///copy constructor
201 
203  TGeoBBox(pc),
204  fNz(0),
205  fPhi1(0.),
206  fDphi(0.),
207  fRmin(0),
208  fRmax(0),
209  fZ(0),
210  fFullPhi(kFALSE),
211  fC1(0.),
212  fS1(0.),
213  fC2(0.),
214  fS2(0.),
215  fCm(0.),
216  fSm(0.),
217  fCdphi(0.)
218 {
219 }
220 
221 ////////////////////////////////////////////////////////////////////////////////
222 ///assignment operator
223 
225 {
226  if(this!=&pc) {
228  fNz=0;
229  fPhi1=0.;
230  fDphi=0.;
231  fRmin=0;
232  fRmax=0;
233  fZ=0;
235  fC1=0;
236  fS1=0;
237  fC2=0;
238  fS2=0;
239  fCm=0;
240  fSm=0;
241  fCdphi=0;
242  }
243  return *this;
244 }
245 
246 ////////////////////////////////////////////////////////////////////////////////
247 /// destructor
248 
250 {
251  if (fRmin) {delete[] fRmin; fRmin = 0;}
252  if (fRmax) {delete[] fRmax; fRmax = 0;}
253  if (fZ) {delete[] fZ; fZ = 0;}
254 }
255 
256 ////////////////////////////////////////////////////////////////////////////////
257 /// Computes capacity of the shape in [length^3]
258 
260 {
261  Int_t ipl;
262  Double_t rmin1, rmax1, rmin2, rmax2, phi1, phi2, dz;
263  Double_t capacity = 0.;
264  phi1 = fPhi1;
265  phi2 = fPhi1 + fDphi;
266  for (ipl=0; ipl<fNz-1; ipl++) {
267  dz = 0.5*(fZ[ipl+1]-fZ[ipl]);
268  if (dz < TGeoShape::Tolerance()) continue;
269  rmin1 = fRmin[ipl];
270  rmax1 = fRmax[ipl];
271  rmin2 = fRmin[ipl+1];
272  rmax2 = fRmax[ipl+1];
273  capacity += TGeoConeSeg::Capacity(dz,rmin1,rmax1,rmin2,rmax2,phi1,phi2);
274  }
275  return capacity;
276 }
277 
278 ////////////////////////////////////////////////////////////////////////////////
279 /// compute bounding box of the pcon
280 /// Check if the sections are in increasing Z order
281 
283 {
284  for (Int_t isec=0; isec<fNz-1; isec++) {
285  if (TMath::Abs(fZ[isec]-fZ[isec+1]) < TGeoShape::Tolerance()) {
286  fZ[isec+1]=fZ[isec];
287  if (IsSameWithinTolerance(fRmin[isec], fRmin[isec+1]) &&
288  IsSameWithinTolerance(fRmax[isec], fRmax[isec+1])) {
289  InspectShape();
290  Error("ComputeBBox", "Duplicated section %d/%d for shape %s", isec, isec+1, GetName());
291  }
292  }
293  if (fZ[isec]>fZ[isec+1]) {
294  InspectShape();
295  Fatal("ComputeBBox", "Wrong section order");
296  }
297  }
298  // Check if the last sections are valid
299  if (TMath::Abs(fZ[1]-fZ[0]) < TGeoShape::Tolerance() ||
300  TMath::Abs(fZ[fNz-1]-fZ[fNz-2]) < TGeoShape::Tolerance()) {
301  InspectShape();
302  Fatal("ComputeBBox","Shape %s at index %d: Not allowed first two or last two sections at same Z",
304  }
305  Double_t zmin = TMath::Min(fZ[0], fZ[fNz-1]);
306  Double_t zmax = TMath::Max(fZ[0], fZ[fNz-1]);
307  // find largest rmax an smallest rmin
308  Double_t rmin, rmax;
309  rmin = fRmin[TMath::LocMin(fNz, fRmin)];
310  rmax = fRmax[TMath::LocMax(fNz, fRmax)];
311 
312  Double_t xc[4];
313  Double_t yc[4];
314  xc[0] = rmax*fC1;
315  yc[0] = rmax*fS1;
316  xc[1] = rmax*fC2;
317  yc[1] = rmax*fS2;
318  xc[2] = rmin*fC1;
319  yc[2] = rmin*fS1;
320  xc[3] = rmin*fC2;
321  yc[3] = rmin*fS2;
322 
323  Double_t xmin = xc[TMath::LocMin(4, &xc[0])];
324  Double_t xmax = xc[TMath::LocMax(4, &xc[0])];
325  Double_t ymin = yc[TMath::LocMin(4, &yc[0])];
326  Double_t ymax = yc[TMath::LocMax(4, &yc[0])];
327 
328  Double_t ddp = -fPhi1;
329  if (ddp<0) ddp+= 360;
330  if (ddp<=fDphi) xmax = rmax;
331  ddp = 90-fPhi1;
332  if (ddp<0) ddp+= 360;
333  if (ddp<=fDphi) ymax = rmax;
334  ddp = 180-fPhi1;
335  if (ddp<0) ddp+= 360;
336  if (ddp<=fDphi) xmin = -rmax;
337  ddp = 270-fPhi1;
338  if (ddp<0) ddp+= 360;
339  if (ddp<=fDphi) ymin = -rmax;
340  fOrigin[0] = (xmax+xmin)/2;
341  fOrigin[1] = (ymax+ymin)/2;
342  fOrigin[2] = (zmax+zmin)/2;
343  fDX = (xmax-xmin)/2;
344  fDY = (ymax-ymin)/2;
345  fDZ = (zmax-zmin)/2;
347 }
348 
349 ////////////////////////////////////////////////////////////////////////////////
350 /// Compute normal to closest surface from POINT.
351 
352 void TGeoPcon::ComputeNormal(const Double_t *point, const Double_t *dir, Double_t *norm)
353 {
354  memset(norm,0,3*sizeof(Double_t));
355  Double_t r;
356  Double_t ptnew[3];
357  Double_t dz, rmin1, rmax1, rmin2, rmax2;
358  Bool_t is_tube;
359  Int_t ipl = TMath::BinarySearch(fNz, fZ, point[2]);
360  if (ipl==(fNz-1) || ipl<0) {
361  // point outside Z range
362  norm[2] = TMath::Sign(1., dir[2]);
363  return;
364  }
365  Int_t iplclose = ipl;
366  if ((fZ[ipl+1]-point[2])<(point[2]-fZ[ipl])) iplclose++;
367  dz = TMath::Abs(fZ[iplclose]-point[2]);
368  if (dz<1E-5) {
369  if (iplclose==0 || iplclose==(fNz-1)) {
370  norm[2] = TMath::Sign(1., dir[2]);
371  return;
372  }
373  if (iplclose==ipl && TGeoShape::IsSameWithinTolerance(fZ[ipl],fZ[ipl-1])) {
374  r = TMath::Sqrt(point[0]*point[0]+point[1]*point[1]);
375  if (r<TMath::Max(fRmin[ipl],fRmin[ipl-1]) || r>TMath::Min(fRmax[ipl],fRmax[ipl-1])) {
376  norm[2] = TMath::Sign(1., dir[2]);
377  return;
378  }
379  } else {
380  if (TGeoShape::IsSameWithinTolerance(fZ[iplclose],fZ[iplclose+1])) {
381  r = TMath::Sqrt(point[0]*point[0]+point[1]*point[1]);
382  if (r<TMath::Max(fRmin[iplclose],fRmin[iplclose+1]) || r>TMath::Min(fRmax[iplclose],fRmax[iplclose+1])) {
383  norm[2] = TMath::Sign(1., dir[2]);
384  return;
385  }
386  }
387  }
388  } //-> Z done
389  memcpy(ptnew, point, 3*sizeof(Double_t));
390  dz = 0.5*(fZ[ipl+1]-fZ[ipl]);
392  norm[2] = TMath::Sign(1., dir[2]);
393  return;
394  }
395  ptnew[2] -= 0.5*(fZ[ipl]+fZ[ipl+1]);
396  rmin1 = fRmin[ipl];
397  rmax1 = fRmax[ipl];
398  rmin2 = fRmin[ipl+1];
399  rmax2 = fRmax[ipl+1];
400  is_tube = (TGeoShape::IsSameWithinTolerance(rmin1,rmin2) && TGeoShape::IsSameWithinTolerance(rmax1,rmax2))?kTRUE:kFALSE;
401  if (!fFullPhi) {
402  if (is_tube) TGeoTubeSeg::ComputeNormalS(ptnew,dir,norm,rmin1,rmax1,dz,fC1,fS1,fC2,fS2);
403  else TGeoConeSeg::ComputeNormalS(ptnew,dir,norm,dz,rmin1,rmax1,rmin2,rmax2,fC1,fS1,fC2,fS2);
404  } else {
405  if (is_tube) TGeoTube::ComputeNormalS(ptnew,dir,norm,rmin1,rmax1,dz);
406  else TGeoCone::ComputeNormalS(ptnew,dir,norm,dz,rmin1,rmax1,rmin2,rmax2);
407  }
408 }
409 
410 ////////////////////////////////////////////////////////////////////////////////
411 /// test if point is inside this shape
412 /// check total z range
413 
414 Bool_t TGeoPcon::Contains(const Double_t *point) const
415 {
416  if ((point[2]<fZ[0]) || (point[2]>fZ[fNz-1])) return kFALSE;
417  // check R squared
418  Double_t r2 = point[0]*point[0]+point[1]*point[1];
419 
420  Int_t izl = 0;
421  Int_t izh = fNz-1;
422  Int_t izt = (fNz-1)/2;
423  while ((izh-izl)>1) {
424  if (point[2] > fZ[izt]) izl = izt;
425  else izh = izt;
426  izt = (izl+izh)>>1;
427  }
428  // the point is in the section bounded by izl and izh Z planes
429 
430  // compute Rmin and Rmax and test the value of R squared
431  Double_t rmin, rmax;
432  if (TGeoShape::IsSameWithinTolerance(fZ[izl],fZ[izh]) && TGeoShape::IsSameWithinTolerance(point[2],fZ[izl])) {
433  rmin = TMath::Min(fRmin[izl], fRmin[izh]);
434  rmax = TMath::Max(fRmax[izl], fRmax[izh]);
435  } else {
436  Double_t dz = fZ[izh] - fZ[izl];
437  Double_t dz1 = point[2] - fZ[izl];
438  rmin = (fRmin[izl]*(dz-dz1)+fRmin[izh]*dz1)/dz;
439  rmax = (fRmax[izl]*(dz-dz1)+fRmax[izh]*dz1)/dz;
440  }
441  if ((r2<rmin*rmin) || (r2>rmax*rmax)) return kFALSE;
442  // now check phi
443  if (TGeoShape::IsSameWithinTolerance(fDphi,360)) return kTRUE;
444  if (r2<1E-10) return kTRUE;
445  Double_t phi = TMath::ATan2(point[1], point[0]) * TMath::RadToDeg();
446  if (phi < 0) phi+=360.0;
447  Double_t ddp = phi-fPhi1;
448  if (ddp<0) ddp+=360.;
449  if (ddp<=fDphi) return kTRUE;
450  return kFALSE;
451 }
452 
453 ////////////////////////////////////////////////////////////////////////////////
454 /// compute closest distance from point px,py to each corner
455 
457 {
459  const Int_t numPoints = 2*n*fNz;
460  return ShapeDistancetoPrimitive(numPoints, px, py);
461 }
462 
463 ////////////////////////////////////////////////////////////////////////////////
464 /// compute distance from inside point to surface of the polycone
465 
466 Double_t TGeoPcon::DistFromInside(const Double_t *point, const Double_t *dir, Int_t iact, Double_t step, Double_t *safe) const
467 {
468  if (iact<3 && safe) {
469  *safe = Safety(point, kTRUE);
470  if (iact==0) return TGeoShape::Big();
471  if ((iact==1) && (*safe>step)) return TGeoShape::Big();
472  }
473  Double_t snxt = TGeoShape::Big();
474  Double_t sstep = 1E-6;
475  Double_t point_new[3];
476  // determine which z segment contains the point
477  Int_t ipl = TMath::BinarySearch(fNz, fZ, point[2]+TMath::Sign(1.E-10,dir[2]));
478  if (ipl<0) ipl=0;
479  if (ipl==(fNz-1)) ipl--;
480  Double_t dz = 0.5*(fZ[ipl+1]-fZ[ipl]);
481  Bool_t special_case = kFALSE;
482  if (dz<1e-9) {
483  // radius changing segment, make sure track is not in the XY plane
484  if (TGeoShape::IsSameWithinTolerance(dir[2], 0)) {
485  special_case = kTRUE;
486  } else {
487  //check if a close point is still contained
488  point_new[0] = point[0]+sstep*dir[0];
489  point_new[1] = point[1]+sstep*dir[1];
490  point_new[2] = point[2]+sstep*dir[2];
491  if (!Contains(point_new)) return 0.;
492  return (DistFromInside(point_new,dir,iact,step,safe)+sstep);
493  }
494  }
495  // determine if the current segment is a tube or a cone
496  Bool_t intub = kTRUE;
497  if (!TGeoShape::IsSameWithinTolerance(fRmin[ipl],fRmin[ipl+1])) intub=kFALSE;
498  else if (!TGeoShape::IsSameWithinTolerance(fRmax[ipl],fRmax[ipl+1])) intub=kFALSE;
499  // determine phi segmentation
500  memcpy(point_new, point, 2*sizeof(Double_t));
501  // new point in reference system of the current segment
502  point_new[2] = point[2]-0.5*(fZ[ipl]+fZ[ipl+1]);
503 
504  if (special_case) {
505  if (!fFullPhi) snxt = TGeoTubeSeg::DistFromInsideS(point_new, dir,
506  TMath::Min(fRmin[ipl],fRmin[ipl+1]), TMath::Max(fRmax[ipl],fRmax[ipl+1]),
507  dz, fC1,fS1,fC2,fS2,fCm,fSm,fCdphi);
508  else snxt = TGeoTube::DistFromInsideS(point_new, dir,
509  TMath::Min(fRmin[ipl],fRmin[ipl+1]), TMath::Max(fRmax[ipl],fRmax[ipl+1]),dz);
510  return snxt;
511  }
512  if (intub) {
513  if (!fFullPhi) snxt=TGeoTubeSeg::DistFromInsideS(point_new, dir, fRmin[ipl], fRmax[ipl],dz, fC1,fS1,fC2,fS2,fCm,fSm,fCdphi);
514  else snxt=TGeoTube::DistFromInsideS(point_new, dir, fRmin[ipl], fRmax[ipl],dz);
515  } else {
516  if (!fFullPhi) snxt=TGeoConeSeg::DistFromInsideS(point_new,dir,dz,fRmin[ipl],fRmax[ipl],fRmin[ipl+1],fRmax[ipl+1],fC1,fS1,fC2,fS2,fCm,fSm,fCdphi);
517  else snxt=TGeoCone::DistFromInsideS(point_new,dir,dz,fRmin[ipl],fRmax[ipl],fRmin[ipl+1], fRmax[ipl+1]);
518  }
519 
520  for (Int_t i=0; i<3; i++) point_new[i]=point[i]+(snxt+1E-6)*dir[i];
521  if (!Contains(&point_new[0])) return snxt;
522 
523  snxt += DistFromInside(&point_new[0], dir, 3) + 1E-6;
524  return snxt;
525 }
526 
527 ////////////////////////////////////////////////////////////////////////////////
528 /// compute distance to a pcon Z slice. Segment iz must be valid
529 
530 Double_t TGeoPcon::DistToSegZ(const Double_t *point, const Double_t *dir, Int_t &iz) const
531 {
532  Double_t zmin=fZ[iz];
533  Double_t zmax=fZ[iz+1];
534  if (TGeoShape::IsSameWithinTolerance(zmin,zmax)) {
535  if (TGeoShape::IsSameWithinTolerance(dir[2],0)) return TGeoShape::Big();
536  Int_t istep=(dir[2]>0)?1:-1;
537  iz+=istep;
538  if (iz<0 || iz>(fNz-2)) return TGeoShape::Big();
539  return DistToSegZ(point,dir,iz);
540  }
541  Double_t dz=0.5*(zmax-zmin);
542  Double_t local[3];
543  memcpy(&local[0], point, 3*sizeof(Double_t));
544  local[2]=point[2]-0.5*(zmin+zmax);
545  Double_t snxt;
546  Double_t rmin1=fRmin[iz];
547  Double_t rmax1=fRmax[iz];
548  Double_t rmin2=fRmin[iz+1];
549  Double_t rmax2=fRmax[iz+1];
550 
551  if (TGeoShape::IsSameWithinTolerance(rmin1,rmin2) && TGeoShape::IsSameWithinTolerance(rmax1,rmax2)) {
552  if (fFullPhi) snxt=TGeoTube::DistFromOutsideS(local, dir, rmin1, rmax1, dz);
553  else snxt=TGeoTubeSeg::DistFromOutsideS(local,dir,rmin1,rmax1,dz,fC1,fS1,fC2,fS2,fCm,fSm,fCdphi);
554  } else {
555  if (fFullPhi) snxt=TGeoCone::DistFromOutsideS(local,dir,dz,rmin1, rmax1,rmin2,rmax2);
556  else snxt=TGeoConeSeg::DistFromOutsideS(local,dir,dz,rmin1,rmax1,rmin2,rmax2,fC1,fS1,fC2,fS2,fCm,fSm,fCdphi);
557  }
558  if (snxt<1E20) return snxt;
559  // check next segment
560  if (TGeoShape::IsSameWithinTolerance(dir[2],0)) return TGeoShape::Big();
561  Int_t istep=(dir[2]>0)?1:-1;
562  iz+=istep;
563  if (iz<0 || iz>(fNz-2)) return TGeoShape::Big();
564  return DistToSegZ(point,dir,iz);
565 }
566 
567 ////////////////////////////////////////////////////////////////////////////////
568 /// compute distance from outside point to surface of the tube
569 
570 Double_t TGeoPcon::DistFromOutside(const Double_t *point, const Double_t *dir, Int_t iact, Double_t step, Double_t *safe) const
571 {
572  if ((iact<3) && safe) {
573  *safe = Safety(point, kFALSE);
574  if ((iact==1) && (*safe>step)) return TGeoShape::Big();
575  if (iact==0) return TGeoShape::Big();
576  }
577  // check if ray intersect outscribed cylinder
578  if ((point[2]<fZ[0]) && (dir[2]<=0)) return TGeoShape::Big();
579  if ((point[2]>fZ[fNz-1]) && (dir[2]>=0)) return TGeoShape::Big();
580 // Check if the bounding box is crossed within the requested distance
581  Double_t sdist = TGeoBBox::DistFromOutside(point,dir, fDX, fDY, fDZ, fOrigin, step);
582  if (sdist>=step) return TGeoShape::Big();
583 
584  Double_t r2 = point[0]*point[0]+point[1]*point[1];
585  Double_t radmax=0;
586  radmax=fRmax[TMath::LocMax(fNz, fRmax)];
587  if (r2>(radmax*radmax)) {
588  Double_t rpr=-point[0]*dir[0]-point[1]*dir[1];
589  Double_t nxy=dir[0]*dir[0]+dir[1]*dir[1];
590  if (rpr<TMath::Sqrt((r2-radmax*radmax)*nxy)) return TGeoShape::Big();
591  }
592 
593  // find in which Z segment we are
594  Int_t ipl = TMath::BinarySearch(fNz, fZ, point[2]);
595  Int_t ifirst = ipl;
596  if (ifirst<0) {
597  ifirst=0;
598  } else if (ifirst>=(fNz-1)) ifirst=fNz-2;
599  // find if point is in the phi gap
600  Double_t phi=0;
601  if (!fFullPhi) {
602  phi=TMath::ATan2(point[1], point[0]);
603  if (phi<0) phi+=2.*TMath::Pi();
604  }
605 
606  // compute distance to boundary
607  return DistToSegZ(point,dir,ifirst);
608 }
609 
610 ////////////////////////////////////////////////////////////////////////////////
611 /// Defines z position of a section plane, rmin and rmax at this z. Sections
612 /// should be defined in increasing or decreasing Z order and the last section
613 /// HAS to be snum = fNz-1
614 
616 {
617  if ((snum<0) || (snum>=fNz)) return;
618  fZ[snum] = z;
619  fRmin[snum] = rmin;
620  fRmax[snum] = rmax;
621  if (rmin>rmax)
622  Warning("DefineSection", "Shape %s: invalid rmin=%g rmax=%g", GetName(), rmin, rmax);
623  if (snum==(fNz-1)) {
624  // Reorder sections in increasing Z order
625  if (fZ[0] > fZ[snum]) {
626  Int_t iz = 0;
627  Int_t izi = fNz-1;
628  Double_t temp;
629  while (iz<izi) {
630  temp = fZ[iz];
631  fZ[iz] = fZ[izi];
632  fZ[izi] = temp;
633  temp = fRmin[iz];
634  fRmin[iz] = fRmin[izi];
635  fRmin[izi] = temp;
636  temp = fRmax[iz];
637  fRmax[iz] = fRmax[izi];
638  fRmax[izi] = temp;
639  iz++;
640  izi--;
641  }
642  }
643  ComputeBBox();
644  }
645 }
646 
647 ////////////////////////////////////////////////////////////////////////////////
648 /// Returns number of segments on each mesh circle segment.
649 
651 {
652  return gGeoManager->GetNsegments();
653 }
654 
655 ////////////////////////////////////////////////////////////////////////////////
656 ///--- Divide this polycone shape belonging to volume "voldiv" into ndiv volumes
657 /// called divname, from start position with the given step. Returns pointer
658 /// to created division cell volume in case of Z divisions. Z divisions can be
659 /// performed if the divided range is in between two consecutive Z planes.
660 /// In case a wrong division axis is supplied, returns pointer to
661 /// volume that was divided.
662 
663 TGeoVolume *TGeoPcon::Divide(TGeoVolume *voldiv, const char *divname, Int_t iaxis, Int_t ndiv,
664  Double_t start, Double_t step)
665 {
666  TGeoShape *shape; //--- shape to be created
667  TGeoVolume *vol; //--- division volume to be created
668  TGeoVolumeMulti *vmulti; //--- generic divided volume
669  TGeoPatternFinder *finder; //--- finder to be attached
670  TString opt = ""; //--- option to be attached
671  Double_t zmin = start;
672  Double_t zmax = start+ndiv*step;
673  Int_t isect = -1;
674  Int_t is, id, ipl;
675  switch (iaxis) {
676  case 1: //--- R division
677  Error("Divide", "Shape %s: cannot divide a pcon on radius", GetName());
678  return 0;
679  case 2: //--- Phi division
680  finder = new TGeoPatternCylPhi(voldiv, ndiv, start, start+ndiv*step);
681  vmulti = gGeoManager->MakeVolumeMulti(divname, voldiv->GetMedium());
682  voldiv->SetFinder(finder);
683  finder->SetDivIndex(voldiv->GetNdaughters());
684  shape = new TGeoPcon(-step/2, step, fNz);
685  for (is=0; is<fNz; is++)
686  ((TGeoPcon*)shape)->DefineSection(is, fZ[is], fRmin[is], fRmax[is]);
687  vol = new TGeoVolume(divname, shape, voldiv->GetMedium());
688  vmulti->AddVolume(vol);
689  opt = "Phi";
690  for (id=0; id<ndiv; id++) {
691  voldiv->AddNodeOffset(vol, id, start+id*step+step/2, opt.Data());
692  ((TGeoNodeOffset*)voldiv->GetNodes()->At(voldiv->GetNdaughters()-1))->SetFinder(finder);
693  }
694  return vmulti;
695  case 3: //--- Z division
696  // find start plane
697  for (ipl=0; ipl<fNz-1; ipl++) {
698  if (start<fZ[ipl]) continue;
699  else {
700  if ((start+ndiv*step)>fZ[ipl+1]) continue;
701  }
702  isect = ipl;
703  zmin = fZ[isect];
704  zmax= fZ[isect+1];
705  break;
706  }
707  if (isect<0) {
708  Error("Divide", "Shape %s: cannot divide pcon on Z if divided region is not between 2 planes", GetName());
709  return 0;
710  }
711  finder = new TGeoPatternZ(voldiv, ndiv, start, start+ndiv*step);
712  vmulti = gGeoManager->MakeVolumeMulti(divname, voldiv->GetMedium());
713  voldiv->SetFinder(finder);
714  finder->SetDivIndex(voldiv->GetNdaughters());
715  opt = "Z";
716  for (id=0; id<ndiv; id++) {
717  Double_t z1 = start+id*step;
718  Double_t z2 = start+(id+1)*step;
719  Double_t rmin1 = (fRmin[isect]*(zmax-z1)-fRmin[isect+1]*(zmin-z1))/(zmax-zmin);
720  Double_t rmax1 = (fRmax[isect]*(zmax-z1)-fRmax[isect+1]*(zmin-z1))/(zmax-zmin);
721  Double_t rmin2 = (fRmin[isect]*(zmax-z2)-fRmin[isect+1]*(zmin-z2))/(zmax-zmin);
722  Double_t rmax2 = (fRmax[isect]*(zmax-z2)-fRmax[isect+1]*(zmin-z2))/(zmax-zmin);
724  Bool_t is_seg = (fDphi<360)?kTRUE:kFALSE;
725  if (is_seg) {
726  if (is_tube) shape=new TGeoTubeSeg(fRmin[isect],fRmax[isect],step/2, fPhi1, fPhi1+fDphi);
727  else shape=new TGeoConeSeg(step/2, rmin1, rmax1, rmin2, rmax2, fPhi1, fPhi1+fDphi);
728  } else {
729  if (is_tube) shape=new TGeoTube(fRmin[isect],fRmax[isect],step/2);
730  else shape = new TGeoCone(step/2,rmin1,rmax1,rmin2,rmax2);
731  }
732  vol = new TGeoVolume(divname, shape, voldiv->GetMedium());
733  vmulti->AddVolume(vol);
734  voldiv->AddNodeOffset(vol, id, start+id*step+step/2, opt.Data());
735  ((TGeoNodeOffset*)voldiv->GetNodes()->At(voldiv->GetNdaughters()-1))->SetFinder(finder);
736  }
737  return vmulti;
738  default:
739  Error("Divide", "Shape %s: Wrong axis %d for division",GetName(), iaxis);
740  return 0;
741  }
742 }
743 
744 ////////////////////////////////////////////////////////////////////////////////
745 /// Returns name of axis IAXIS.
746 
747 const char *TGeoPcon::GetAxisName(Int_t iaxis) const
748 {
749  switch (iaxis) {
750  case 1:
751  return "R";
752  case 2:
753  return "PHI";
754  case 3:
755  return "Z";
756  default:
757  return "UNDEFINED";
758  }
759 }
760 
761 ////////////////////////////////////////////////////////////////////////////////
762 /// Get range of shape for a given axis.
763 
765 {
766  xlo = 0;
767  xhi = 0;
768  Double_t dx = 0;
769  switch (iaxis) {
770  case 2:
771  xlo = fPhi1;
772  xhi = fPhi1 + fDphi;
773  dx = fDphi;
774  return dx;
775  case 3:
776  xlo = fZ[0];
777  xhi = fZ[fNz-1];
778  dx = xhi-xlo;
779  return dx;
780  }
781  return dx;
782 }
783 
784 ////////////////////////////////////////////////////////////////////////////////
785 ///--- Fill vector param[4] with the bounding cylinder parameters. The order
786 /// is the following : Rmin, Rmax, Phi1, Phi2
787 
789 {
790  param[0] = fRmin[0]; // Rmin
791  param[1] = fRmax[0]; // Rmax
792  for (Int_t i=1; i<fNz; i++) {
793  if (fRmin[i] < param[0]) param[0] = fRmin[i];
794  if (fRmax[i] > param[1]) param[1] = fRmax[i];
795  }
796  param[0] *= param[0];
797  param[1] *= param[1];
798  if (TGeoShape::IsSameWithinTolerance(fDphi,360.)) {
799  param[2] = 0.;
800  param[3] = 360.;
801  return;
802  }
803  param[2] = (fPhi1<0)?(fPhi1+360.):fPhi1; // Phi1
804  param[3] = param[2]+fDphi; // Phi2
805 }
806 
807 ////////////////////////////////////////////////////////////////////////////////
808 /// Returns Rmin for Z segment IPL.
809 
811 {
812  if (ipl<0 || ipl>(fNz-1)) {
813  Error("GetRmin","ipl=%i out of range (0,%i) in shape %s",ipl,fNz-1,GetName());
814  return 0.;
815  }
816  return fRmin[ipl];
817 }
818 
819 ////////////////////////////////////////////////////////////////////////////////
820 /// Returns Rmax for Z segment IPL.
821 
823 {
824  if (ipl<0 || ipl>(fNz-1)) {
825  Error("GetRmax","ipl=%i out of range (0,%i) in shape %s",ipl,fNz-1,GetName());
826  return 0.;
827  }
828  return fRmax[ipl];
829 }
830 
831 ////////////////////////////////////////////////////////////////////////////////
832 /// Returns Z for segment IPL.
833 
835 {
836  if (ipl<0 || ipl>(fNz-1)) {
837  Error("GetZ","ipl=%i out of range (0,%i) in shape %s",ipl,fNz-1,GetName());
838  return 0.;
839  }
840  return fZ[ipl];
841 }
842 
843 ////////////////////////////////////////////////////////////////////////////////
844 /// print shape parameters
845 
847 {
848  printf("*** Shape %s: TGeoPcon ***\n", GetName());
849  printf(" Nz = %i\n", fNz);
850  printf(" phi1 = %11.5f\n", fPhi1);
851  printf(" dphi = %11.5f\n", fDphi);
852  for (Int_t ipl=0; ipl<fNz; ipl++)
853  printf(" plane %i: z=%11.5f Rmin=%11.5f Rmax=%11.5f\n", ipl, fZ[ipl], fRmin[ipl], fRmax[ipl]);
854  printf(" Bounding box:\n");
856 }
857 
858 ////////////////////////////////////////////////////////////////////////////////
859 /// Creates a TBuffer3D describing *this* shape.
860 /// Coordinates are in local reference frame.
861 
863 {
864  const Int_t n = gGeoManager->GetNsegments()+1;
865  Int_t nz = GetNz();
866  if (nz < 2) return 0;
867  Int_t nbPnts = nz*2*n;
868  if (nbPnts <= 0) return 0;
869  Double_t dphi = GetDphi();
870 
871  Bool_t specialCase = kFALSE;
872  if (TGeoShape::IsSameWithinTolerance(dphi,360)) specialCase = kTRUE;
873 
874  Int_t nbSegs = 4*(nz*n-1+(specialCase == kTRUE));
875  Int_t nbPols = 2*(nz*n-1+(specialCase == kTRUE));
877  nbPnts, 3*nbPnts, nbSegs, 3*nbSegs, nbPols, 6*nbPols);
878  if (buff)
879  {
880  SetPoints(buff->fPnts);
881  SetSegsAndPols(*buff);
882  }
883 
884  return buff;
885 }
886 
887 ////////////////////////////////////////////////////////////////////////////////
888 /// Fill TBuffer3D structure for segments and polygons.
889 
891 {
892  Int_t i, j;
893  const Int_t n = gGeoManager->GetNsegments()+1;
894  Int_t nz = GetNz();
895  if (nz < 2) return;
896  Int_t nbPnts = nz*2*n;
897  if (nbPnts <= 0) return;
898  Double_t dphi = GetDphi();
899 
900  Bool_t specialCase = kFALSE;
901  if (TGeoShape::IsSameWithinTolerance(dphi,360)) specialCase = kTRUE;
902  Int_t c = GetBasicColor();
903 
904  Int_t indx, indx2, k;
905  indx = indx2 = 0;
906 
907  //inside & outside circles, number of segments: 2*nz*(n-1)
908  // special case number of segments: 2*nz*n
909  for (i = 0; i < nz*2; i++) {
910  indx2 = i*n;
911  for (j = 1; j < n; j++) {
912  buff.fSegs[indx++] = c;
913  buff.fSegs[indx++] = indx2+j-1;
914  buff.fSegs[indx++] = indx2+j;
915  }
916  if (specialCase) {
917  buff.fSegs[indx++] = c;
918  buff.fSegs[indx++] = indx2+j-1;
919  buff.fSegs[indx++] = indx2;
920  }
921  }
922 
923  //bottom & top lines, number of segments: 2*n
924  for (i = 0; i < 2; i++) {
925  indx2 = i*(nz-1)*2*n;
926  for (j = 0; j < n; j++) {
927  buff.fSegs[indx++] = c;
928  buff.fSegs[indx++] = indx2+j;
929  buff.fSegs[indx++] = indx2+n+j;
930  }
931  }
932 
933  //inside & outside cilindres, number of segments: 2*(nz-1)*n
934  for (i = 0; i < (nz-1); i++) {
935  //inside cilinder
936  indx2 = i*n*2;
937  for (j = 0; j < n; j++) {
938  buff.fSegs[indx++] = c+2;
939  buff.fSegs[indx++] = indx2+j;
940  buff.fSegs[indx++] = indx2+n*2+j;
941  }
942  //outside cilinder
943  indx2 = i*n*2+n;
944  for (j = 0; j < n; j++) {
945  buff.fSegs[indx++] = c+3;
946  buff.fSegs[indx++] = indx2+j;
947  buff.fSegs[indx++] = indx2+n*2+j;
948  }
949  }
950 
951  //left & right sections, number of segments: 2*(nz-2)
952  // special case number of segments: 0
953  if (!specialCase) {
954  for (i = 1; i < (nz-1); i++) {
955  for (j = 0; j < 2; j++) {
956  buff.fSegs[indx++] = c;
957  buff.fSegs[indx++] = 2*i * n + j*(n-1);
958  buff.fSegs[indx++] = (2*i+1) * n + j*(n-1);
959  }
960  }
961  }
962 
963  Int_t m = n - 1 + (specialCase == kTRUE);
964  indx = 0;
965 
966  //bottom & top, number of polygons: 2*(n-1)
967  // special case number of polygons: 2*n
968  for (j = 0; j < n-1; j++) {
969  buff.fPols[indx++] = c+3;
970  buff.fPols[indx++] = 4;
971  buff.fPols[indx++] = 2*nz*m+j;
972  buff.fPols[indx++] = m+j;
973  buff.fPols[indx++] = 2*nz*m+j+1;
974  buff.fPols[indx++] = j;
975  }
976  for (j = 0; j < n-1; j++) {
977  buff.fPols[indx++] = c+3;
978  buff.fPols[indx++] = 4;
979  buff.fPols[indx++] = 2*nz*m+n+j;
980  buff.fPols[indx++] = (nz*2-2)*m+j;
981  buff.fPols[indx++] = 2*nz*m+n+j+1;
982  buff.fPols[indx++] = (nz*2-2)*m+m+j;
983  }
984  if (specialCase) {
985  buff.fPols[indx++] = c+3;
986  buff.fPols[indx++] = 4;
987  buff.fPols[indx++] = 2*nz*m+j;
988  buff.fPols[indx++] = m+j;
989  buff.fPols[indx++] = 2*nz*m;
990  buff.fPols[indx++] = j;
991 
992  buff.fPols[indx++] = c+3;
993  buff.fPols[indx++] = 4;
994  buff.fPols[indx++] = 2*nz*m+n+j;
995  buff.fPols[indx++] = (nz*2-2)*m+m+j;
996  buff.fPols[indx++] = 2*nz*m+n;
997  buff.fPols[indx++] = (nz*2-2)*m+j;
998  }
999 
1000  //inside & outside, number of polygons: (nz-1)*2*(n-1)
1001  for (k = 0; k < (nz-1); k++) {
1002  for (j = 0; j < n-1; j++) {
1003  buff.fPols[indx++] = c;
1004  buff.fPols[indx++] = 4;
1005  buff.fPols[indx++] = 2*k*m+j;
1006  buff.fPols[indx++] = nz*2*m+(2*k+2)*n+j+1;
1007  buff.fPols[indx++] = (2*k+2)*m+j;
1008  buff.fPols[indx++] = nz*2*m+(2*k+2)*n+j;
1009  }
1010  for (j = 0; j < n-1; j++) {
1011  buff.fPols[indx++] = c+1;
1012  buff.fPols[indx++] = 4;
1013  buff.fPols[indx++] = (2*k+1)*m+j;
1014  buff.fPols[indx++] = nz*2*m+(2*k+3)*n+j;
1015  buff.fPols[indx++] = (2*k+3)*m+j;
1016  buff.fPols[indx++] = nz*2*m+(2*k+3)*n+j+1;
1017  }
1018  if (specialCase) {
1019  buff.fPols[indx++] = c;
1020  buff.fPols[indx++] = 4;
1021  buff.fPols[indx++] = 2*k*m+j;
1022  buff.fPols[indx++] = nz*2*m+(2*k+2)*n;
1023  buff.fPols[indx++] = (2*k+2)*m+j;
1024  buff.fPols[indx++] = nz*2*m+(2*k+2)*n+j;
1025 
1026  buff.fPols[indx++] = c+1;
1027  buff.fPols[indx++] = 4;
1028  buff.fPols[indx++] = (2*k+1)*m+j;
1029  buff.fPols[indx++] = nz*2*m+(2*k+3)*n+j;
1030  buff.fPols[indx++] = (2*k+3)*m+j;
1031  buff.fPols[indx++] = nz*2*m+(2*k+3)*n;
1032  }
1033  }
1034 
1035  //left & right sections, number of polygons: 2*(nz-1)
1036  // special case number of polygons: 0
1037  if (!specialCase) {
1038  indx2 = nz*2*(n-1);
1039  for (k = 0; k < (nz-1); k++) {
1040  buff.fPols[indx++] = c+2;
1041  buff.fPols[indx++] = 4;
1042  buff.fPols[indx++] = k==0 ? indx2 : indx2+2*nz*n+2*(k-1);
1043  buff.fPols[indx++] = indx2+2*(k+1)*n;
1044  buff.fPols[indx++] = indx2+2*nz*n+2*k;
1045  buff.fPols[indx++] = indx2+(2*k+3)*n;
1046 
1047  buff.fPols[indx++] = c+2;
1048  buff.fPols[indx++] = 4;
1049  buff.fPols[indx++] = k==0 ? indx2+n-1 : indx2+2*nz*n+2*(k-1)+1;
1050  buff.fPols[indx++] = indx2+(2*k+3)*n+n-1;
1051  buff.fPols[indx++] = indx2+2*nz*n+2*k+1;
1052  buff.fPols[indx++] = indx2+2*(k+1)*n+n-1;
1053  }
1054  buff.fPols[indx-8] = indx2+n;
1055  buff.fPols[indx-2] = indx2+2*n-1;
1056  }
1057 }
1058 
1059 ////////////////////////////////////////////////////////////////////////////////
1060 /// Compute safety from POINT to segment between planes ipl, ipl+1 within safmin.
1061 
1062 Double_t TGeoPcon::SafetyToSegment(const Double_t *point, Int_t ipl, Bool_t in, Double_t safmin) const
1063 {
1064  Double_t safe = TGeoShape::Big();
1065  if (ipl<0 || ipl>fNz-2) return (safmin+1.); // error in input plane
1066 // Get info about segment.
1067  Double_t dz = 0.5*(fZ[ipl+1]-fZ[ipl]);
1068  if (dz<1E-9) return 1E9; // radius-changing segment
1069  Double_t ptnew[3];
1070  memcpy(ptnew, point, 3*sizeof(Double_t));
1071  ptnew[2] -= 0.5*(fZ[ipl]+fZ[ipl+1]);
1072  safe = TMath::Abs(ptnew[2])-dz;
1073  if (safe>safmin) return TGeoShape::Big(); // means: stop checking further segments
1074  Double_t rmin1 = fRmin[ipl];
1075  Double_t rmax1 = fRmax[ipl];
1076  Double_t rmin2 = fRmin[ipl+1];
1077  Double_t rmax2 = fRmax[ipl+1];
1078  Bool_t is_tube = (TGeoShape::IsSameWithinTolerance(rmin1,rmin2) && TGeoShape::IsSameWithinTolerance(rmax1,rmax2))?kTRUE:kFALSE;
1079  if (!fFullPhi) {
1080  if (is_tube) safe = TGeoTubeSeg::SafetyS(ptnew,in,rmin1,rmax1, dz,fPhi1,fPhi1+fDphi,0);
1081  else safe = TGeoConeSeg::SafetyS(ptnew,in,dz,rmin1,rmax1,rmin2,rmax2,fPhi1,fPhi1+fDphi,0);
1082  } else {
1083  if (is_tube) safe = TGeoTube::SafetyS(ptnew,in,rmin1,rmax1,dz,0);
1084  else safe = TGeoCone::SafetyS(ptnew,in,dz,rmin1,rmax1,rmin2,rmax2,0);
1085  }
1086  if (safe<0) safe=0;
1087  return safe;
1088 }
1089 
1090 ////////////////////////////////////////////////////////////////////////////////
1091 /// computes the closest distance from given point to this shape, according
1092 /// to option. The matching point on the shape is stored in spoint.
1093 ///---> localize the Z segment
1094 
1095 Double_t TGeoPcon::Safety(const Double_t *point, Bool_t in) const
1096 {
1097  Double_t safmin, saftmp;
1098  Double_t dz;
1099  Int_t ipl, iplane;
1100 
1101  if (in) {
1102  //---> point is inside pcon
1103  ipl = TMath::BinarySearch(fNz, fZ, point[2]);
1104  if (ipl==(fNz-1)) return 0; // point on last Z boundary
1105  if (ipl<0) return 0; // point on first Z boundary
1106  if (ipl>0 && TGeoShape::IsSameWithinTolerance(fZ[ipl-1],fZ[ipl]) && TGeoShape::IsSameWithinTolerance(point[2],fZ[ipl-1])) ipl--;
1107  dz = 0.5*(fZ[ipl+1]-fZ[ipl]);
1108  if (dz<1E-8) {
1109  // Point on a segment-changing plane
1110  safmin = TMath::Min(point[2]-fZ[ipl-1],fZ[ipl+2]-point[2]);
1111  saftmp = TGeoShape::Big();
1112  if (fDphi<360) saftmp = TGeoShape::SafetyPhi(point,in,fPhi1,fPhi1+fDphi);
1113  if (saftmp<safmin) safmin = saftmp;
1114  Double_t radius = TMath::Sqrt(point[0]*point[0]+point[1]*point[1]);
1115  if (fRmin[ipl]>0) safmin = TMath::Min(safmin, radius-fRmin[ipl]);
1116  if (fRmin[ipl+1]>0) safmin = TMath::Min(safmin, radius-fRmin[ipl+1]);
1117  safmin = TMath::Min(safmin, fRmax[ipl]-radius);
1118  safmin = TMath::Min(safmin, fRmax[ipl+1]-radius);
1119  if (safmin<0) safmin = 0;
1120  return safmin;
1121  }
1122  // Check safety for current segment
1123  safmin = SafetyToSegment(point, ipl);
1124  if (safmin>1E10) {
1125  // something went wrong - point is not inside current segment
1126  return 0.;
1127  }
1128  if (safmin<1E-6) return TMath::Abs(safmin); // point on radius-changing plane
1129  // check increasing iplanes
1130  iplane = ipl+1;
1131  saftmp = 0.;
1132  while ((iplane<fNz-1) && saftmp<1E10) {
1133  saftmp = TMath::Abs(SafetyToSegment(point,iplane,kFALSE,safmin));
1134  if (saftmp<safmin) safmin=saftmp;
1135  iplane++;
1136  }
1137  // now decreasing nplanes
1138  iplane = ipl-1;
1139  saftmp = 0.;
1140  while ((iplane>=0) && saftmp<1E10) {
1141  saftmp = TMath::Abs(SafetyToSegment(point,iplane,kFALSE,safmin));
1142  if (saftmp<safmin) safmin=saftmp;
1143  iplane--;
1144  }
1145  return safmin;
1146  }
1147  //---> point is outside pcon
1148  ipl = TMath::BinarySearch(fNz, fZ, point[2]);
1149  if (ipl<0) ipl=0;
1150  else if (ipl==fNz-1) ipl=fNz-2;
1151  dz = 0.5*(fZ[ipl+1]-fZ[ipl]);
1152  if (dz<1E-8 && (ipl+2<fNz)) {
1153  ipl++;
1154  dz = 0.5*(fZ[ipl+1]-fZ[ipl]);
1155  }
1156  // Check safety for current segment
1157  safmin = SafetyToSegment(point, ipl, kFALSE);
1158  if (safmin<1E-6) return TMath::Abs(safmin); // point on radius-changing plane
1159  saftmp = 0.;
1160  // check increasing iplanes
1161  iplane = ipl+1;
1162  saftmp = 0.;
1163  while ((iplane<fNz-1) && saftmp<1E10) {
1164  saftmp = TMath::Abs(SafetyToSegment(point,iplane,kFALSE,safmin));
1165  if (saftmp<safmin) safmin=saftmp;
1166  iplane++;
1167  }
1168  // now decreasing nplanes
1169  iplane = ipl-1;
1170  saftmp = 0.;
1171  while ((iplane>=0) && saftmp<1E10) {
1172  saftmp = TMath::Abs(SafetyToSegment(point,iplane,kFALSE,safmin));
1173  if (saftmp<safmin) safmin=saftmp;
1174  iplane--;
1175  }
1176  return safmin;
1177 }
1178 
1179 ////////////////////////////////////////////////////////////////////////////////
1180 /// Save a primitive as a C++ statement(s) on output stream "out".
1181 
1182 void TGeoPcon::SavePrimitive(std::ostream &out, Option_t * /*option*/ /*= ""*/)
1183 {
1184  if (TObject::TestBit(kGeoSavePrimitive)) return;
1185  out << " // Shape: " << GetName() << " type: " << ClassName() << std::endl;
1186  out << " phi1 = " << fPhi1 << ";" << std::endl;
1187  out << " dphi = " << fDphi << ";" << std::endl;
1188  out << " nz = " << fNz << ";" << std::endl;
1189  out << " TGeoPcon *pcon = new TGeoPcon(\"" << GetName() << "\",phi1,dphi,nz);" << std::endl;
1190  for (Int_t i=0; i<fNz; i++) {
1191  out << " z = " << fZ[i] << ";" << std::endl;
1192  out << " rmin = " << fRmin[i] << ";" << std::endl;
1193  out << " rmax = " << fRmax[i] << ";" << std::endl;
1194  out << " pcon->DefineSection(" << i << ", z,rmin,rmax);" << std::endl;
1195  }
1196  out << " TGeoShape *" << GetPointerName() << " = pcon;" << std::endl;
1198 }
1199 
1200 ////////////////////////////////////////////////////////////////////////////////
1201 /// Set polycone dimensions starting from an array.
1202 
1204 {
1205  fPhi1 = param[0];
1206  while (fPhi1<0) fPhi1 += 360.;
1207  fDphi = param[1];
1208  fNz = (Int_t)param[2];
1209  if (fNz<2) {
1210  Error("SetDimensions","Pcon %s: Number of Z sections must be > 2", GetName());
1211  return;
1212  }
1213  if (fRmin) delete [] fRmin;
1214  if (fRmax) delete [] fRmax;
1215  if (fZ) delete [] fZ;
1216  fRmin = new Double_t [fNz];
1217  fRmax = new Double_t [fNz];
1218  fZ = new Double_t [fNz];
1219  memset(fRmin, 0, fNz*sizeof(Double_t));
1220  memset(fRmax, 0, fNz*sizeof(Double_t));
1221  memset(fZ, 0, fNz*sizeof(Double_t));
1223  Double_t phi1 = fPhi1;
1224  Double_t phi2 = phi1+fDphi;
1225  Double_t phim = 0.5*(phi1+phi2);
1226  fC1 = TMath::Cos(phi1*TMath::DegToRad());
1227  fS1 = TMath::Sin(phi1*TMath::DegToRad());
1228  fC2 = TMath::Cos(phi2*TMath::DegToRad());
1229  fS2 = TMath::Sin(phi2*TMath::DegToRad());
1230  fCm = TMath::Cos(phim*TMath::DegToRad());
1231  fSm = TMath::Sin(phim*TMath::DegToRad());
1232  fCdphi = TMath::Cos(0.5*fDphi*TMath::DegToRad());
1233 
1234  for (Int_t i=0; i<fNz; i++)
1235  DefineSection(i, param[3+3*i], param[4+3*i], param[5+3*i]);
1236 }
1237 
1238 ////////////////////////////////////////////////////////////////////////////////
1239 /// create polycone mesh points
1240 
1242 {
1243  Double_t phi, dphi;
1244  Int_t n = gGeoManager->GetNsegments() + 1;
1245  dphi = fDphi/(n-1);
1246  Int_t i, j;
1247  Int_t indx = 0;
1248 
1249  if (points) {
1250  for (i = 0; i < fNz; i++) {
1251  for (j = 0; j < n; j++) {
1252  phi = (fPhi1+j*dphi)*TMath::DegToRad();
1253  points[indx++] = fRmin[i] * TMath::Cos(phi);
1254  points[indx++] = fRmin[i] * TMath::Sin(phi);
1255  points[indx++] = fZ[i];
1256  }
1257  for (j = 0; j < n; j++) {
1258  phi = (fPhi1+j*dphi)*TMath::DegToRad();
1259  points[indx++] = fRmax[i] * TMath::Cos(phi);
1260  points[indx++] = fRmax[i] * TMath::Sin(phi);
1261  points[indx++] = fZ[i];
1262  }
1263  }
1264  }
1265 }
1266 
1267 ////////////////////////////////////////////////////////////////////////////////
1268 /// create polycone mesh points
1269 
1271 {
1272  Double_t phi, dphi;
1273  Int_t n = gGeoManager->GetNsegments() + 1;
1274  dphi = fDphi/(n-1);
1275  Int_t i, j;
1276  Int_t indx = 0;
1277 
1278  if (points) {
1279  for (i = 0; i < fNz; i++) {
1280  for (j = 0; j < n; j++) {
1281  phi = (fPhi1+j*dphi)*TMath::DegToRad();
1282  points[indx++] = fRmin[i] * TMath::Cos(phi);
1283  points[indx++] = fRmin[i] * TMath::Sin(phi);
1284  points[indx++] = fZ[i];
1285  }
1286  for (j = 0; j < n; j++) {
1287  phi = (fPhi1+j*dphi)*TMath::DegToRad();
1288  points[indx++] = fRmax[i] * TMath::Cos(phi);
1289  points[indx++] = fRmax[i] * TMath::Sin(phi);
1290  points[indx++] = fZ[i];
1291  }
1292  }
1293  }
1294 }
1295 ////////////////////////////////////////////////////////////////////////////////
1296 /// Return number of vertices of the mesh representation
1297 
1299 {
1301  Int_t numPoints = fNz*2*n;
1302  return numPoints;
1303 }
1304 
1305 ////////////////////////////////////////////////////////////////////////////////
1306 ////// fill size of this 3-D object
1307 //// TVirtualGeoPainter *painter = gGeoManager->GetGeomer();
1308 //// if (!painter) return;
1309 //// Int_t n;
1310 ////
1311 //// n = gGeoManager->GetNsegments()+1;
1312 ////
1313 //// Int_t numPoints = fNz*2*n;
1314 //// Int_t numSegs = 4*(fNz*n-1+(fDphi == 360));
1315 //// Int_t numPolys = 2*(fNz*n-1+(fDphi == 360));
1316 //// painter->AddSize3D(numPoints, numSegs, numPolys);
1317 
1319 {
1320 }
1321 
1322 ////////////////////////////////////////////////////////////////////////////////
1323 /// Returns numbers of vertices, segments and polygons composing the shape mesh.
1324 
1325 void TGeoPcon::GetMeshNumbers(Int_t &nvert, Int_t &nsegs, Int_t &npols) const
1326 {
1328  Int_t nz = GetNz();
1329  nvert = nz*2*n;
1330  Bool_t specialCase = TGeoShape::IsSameWithinTolerance(GetDphi(),360);
1331  nsegs = 4*(nz*n-1+(specialCase == kTRUE));
1332  npols = 2*(nz*n-1+(specialCase == kTRUE));
1333 }
1334 
1335 ////////////////////////////////////////////////////////////////////////////////
1336 /// Fills a static 3D buffer and returns a reference.
1337 
1338 const TBuffer3D & TGeoPcon::GetBuffer3D(Int_t reqSections, Bool_t localFrame) const
1339 {
1340  static TBuffer3D buffer(TBuffer3DTypes::kGeneric);
1341 
1342  TGeoBBox::FillBuffer3D(buffer, reqSections, localFrame);
1343 
1344  if (reqSections & TBuffer3D::kRawSizes) {
1345  const Int_t n = gGeoManager->GetNsegments()+1;
1346  Int_t nz = GetNz();
1347  Int_t nbPnts = nz*2*n;
1348  if (nz >= 2 && nbPnts > 0) {
1349  Bool_t specialCase = TGeoShape::IsSameWithinTolerance(GetDphi(),360);
1350  Int_t nbSegs = 4*(nz*n-1+(specialCase == kTRUE));
1351  Int_t nbPols = 2*(nz*n-1+(specialCase == kTRUE));
1352  if (buffer.SetRawSizes(nbPnts, 3*nbPnts, nbSegs, 3*nbSegs, nbPols, 6*nbPols)) {
1353  buffer.SetSectionsValid(TBuffer3D::kRawSizes);
1354  }
1355  }
1356  }
1357  // TODO: Push down to TGeoShape?? Wuld have to do raw sizes set first..
1358  // can rest of TGeoShape be defered until after this?
1359  if ((reqSections & TBuffer3D::kRaw) && buffer.SectionsValid(TBuffer3D::kRawSizes)) {
1360  SetPoints(buffer.fPnts);
1361  if (!buffer.fLocalFrame) {
1362  TransformPoints(buffer.fPnts, buffer.NbPnts());
1363  }
1364 
1365  SetSegsAndPols(buffer);
1366  buffer.SetSectionsValid(TBuffer3D::kRaw);
1367  }
1368 
1369  return buffer;
1370 }
1371 
1372 ////////////////////////////////////////////////////////////////////////////////
1373 /// Stream an object of class TGeoPcon.
1374 
1375 void TGeoPcon::Streamer(TBuffer &R__b)
1376 {
1377  if (R__b.IsReading()) {
1378  R__b.ReadClassBuffer(TGeoPcon::Class(),this);
1380  Double_t phi1 = fPhi1;
1381  Double_t phi2 = phi1+fDphi;
1382  Double_t phim = 0.5*(phi1+phi2);
1383  fC1 = TMath::Cos(phi1*TMath::DegToRad());
1384  fS1 = TMath::Sin(phi1*TMath::DegToRad());
1385  fC2 = TMath::Cos(phi2*TMath::DegToRad());
1386  fS2 = TMath::Sin(phi2*TMath::DegToRad());
1387  fCm = TMath::Cos(phim*TMath::DegToRad());
1388  fSm = TMath::Sin(phim*TMath::DegToRad());
1389  fCdphi = TMath::Cos(0.5*fDphi*TMath::DegToRad());
1390  } else {
1391  R__b.WriteClassBuffer(TGeoPcon::Class(),this);
1392  }
1393 }
1394 
1395 ////////////////////////////////////////////////////////////////////////////////
1396 /// Check the inside status for each of the points in the array.
1397 /// Input: Array of point coordinates + vector size
1398 /// Output: Array of Booleans for the inside of each point
1399 
1400 void TGeoPcon::Contains_v(const Double_t *points, Bool_t *inside, Int_t vecsize) const
1401 {
1402  for (Int_t i=0; i<vecsize; i++) inside[i] = Contains(&points[3*i]);
1403 }
1404 
1405 ////////////////////////////////////////////////////////////////////////////////
1406 /// Compute the normal for an array o points so that norm.dot.dir is positive
1407 /// Input: Arrays of point coordinates and directions + vector size
1408 /// Output: Array of normal directions
1409 
1410 void TGeoPcon::ComputeNormal_v(const Double_t *points, const Double_t *dirs, Double_t *norms, Int_t vecsize)
1411 {
1412  for (Int_t i=0; i<vecsize; i++) ComputeNormal(&points[3*i], &dirs[3*i], &norms[3*i]);
1413 }
1414 
1415 ////////////////////////////////////////////////////////////////////////////////
1416 /// Compute distance from array of input points having directions specisied by dirs. Store output in dists
1417 
1418 void TGeoPcon::DistFromInside_v(const Double_t *points, const Double_t *dirs, Double_t *dists, Int_t vecsize, Double_t* step) const
1419 {
1420  for (Int_t i=0; i<vecsize; i++) dists[i] = DistFromInside(&points[3*i], &dirs[3*i], 3, step[i]);
1421 }
1422 
1423 ////////////////////////////////////////////////////////////////////////////////
1424 /// Compute distance from array of input points having directions specisied by dirs. Store output in dists
1425 
1426 void TGeoPcon::DistFromOutside_v(const Double_t *points, const Double_t *dirs, Double_t *dists, Int_t vecsize, Double_t* step) const
1427 {
1428  for (Int_t i=0; i<vecsize; i++) dists[i] = DistFromOutside(&points[3*i], &dirs[3*i], 3, step[i]);
1429 }
1430 
1431 ////////////////////////////////////////////////////////////////////////////////
1432 /// Compute safe distance from each of the points in the input array.
1433 /// Input: Array of point coordinates, array of statuses for these points, size of the arrays
1434 /// Output: Safety values
1435 
1436 void TGeoPcon::Safety_v(const Double_t *points, const Bool_t *inside, Double_t *safe, Int_t vecsize) const
1437 {
1438  for (Int_t i=0; i<vecsize; i++) safe[i] = Safety(&points[3*i], inside[i]);
1439 }
TGeoVolumeMulti * MakeVolumeMulti(const char *name, TGeoMedium *medium)
Make a TGeoVolumeMulti handling a list of volumes.
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:357
float xmin
Definition: THbookFile.cxx:93
virtual Int_t WriteClassBuffer(const TClass *cl, void *pointer)=0
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:269
virtual Int_t GetNsegments() const
Returns number of segments on each mesh circle segment.
Definition: TGeoPcon.cxx:650
Double_t fC2
Sine of phi1.
Definition: TGeoPcon.h:44
Int_t GetNsegments() const
Get number of segments approximating circles.
virtual Bool_t Contains(const Double_t *point) const
test if point is inside this shape check total z range
Definition: TGeoPcon.cxx:414
Long64_t LocMax(Long64_t n, const T *a)
Definition: TMath.h:724
T1 Sign(T1 a, T2 b)
Definition: TMathBase.h:155
void SetFinder(TGeoPatternFinder *finder)
Definition: TGeoVolume.h:247
Bool_t IsReading() const
Definition: TBuffer.h:81
Double_t fDphi
Definition: TGeoPcon.h:37
virtual void SetDimensions(Double_t *param)
Set polycone dimensions starting from an array.
Definition: TGeoPcon.cxx:1203
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
Definition: TGeoCone.cxx:1607
Double_t fC1
Full phi range flag.
Definition: TGeoPcon.h:42
float Float_t
Definition: RtypesCore.h:53
virtual void SetPoints(Double_t *points) const
create polycone mesh points
Definition: TGeoPcon.cxx:1241
void AddNodeOffset(TGeoVolume *vol, Int_t copy_no, Double_t offset=0, Option_t *option="")
Add a division node to the list of nodes.
Definition: TGeoVolume.cxx:987
const char Option_t
Definition: RtypesCore.h:62
float ymin
Definition: THbookFile.cxx:93
Double_t fS2
Cosine of phi1+dphi.
Definition: TGeoPcon.h:45
Int_t GetBasicColor() const
Get the basic color (0-7).
Definition: TGeoShape.cxx:671
virtual ~TGeoPcon()
destructor
Definition: TGeoPcon.cxx:249
Double_t DegToRad()
Definition: TMath.h:50
Buffer base class used for serializing objects.
Definition: TBuffer.h:40
virtual void ComputeNormal(const Double_t *point, const Double_t *dir, Double_t *norm)
Compute normal to closest surface from POINT.
Definition: TGeoPcon.cxx:352
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:877
Double_t fOrigin[3]
Definition: TGeoBBox.h:36
Double_t RadToDeg()
Definition: TMath.h:49
Basic string class.
Definition: TString.h:137
TObjArray * GetListOfShapes() const
Definition: TGeoManager.h:467
Short_t Min(Short_t a, Short_t b)
Definition: TMathBase.h:170
int Int_t
Definition: RtypesCore.h:41
Double_t fS1
Cosine of phi1.
Definition: TGeoPcon.h:43
bool Bool_t
Definition: RtypesCore.h:59
const Bool_t kFALSE
Definition: Rtypes.h:92
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...
Definition: TGeoShape.cxx:463
TGeoPcon & operator=(const TGeoPcon &)
assignment operator
Definition: TGeoPcon.cxx:224
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.
Definition: TGeoTube.cxx:1400
virtual Double_t DistFromOutside(const Double_t *point, const Double_t *dir, Int_t iact=1, Double_t step=TGeoShape::Big(), Double_t *safe=0) const
Compute distance from outside point to surface of the box.
Definition: TGeoBBox.cxx:386
virtual Int_t DistancetoPrimitive(Int_t px, Int_t py)
compute closest distance from point px,py to each corner
Definition: TGeoPcon.cxx:456
Short_t Abs(Short_t d)
Definition: TMathBase.h:110
Int_t GetNdaughters() const
Definition: TGeoVolume.h:362
static Bool_t IsSameWithinTolerance(Double_t a, Double_t b)
Check if two numbers differ with less than a tolerance.
Definition: TGeoShape.cxx:325
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
Definition: TObject.cxx:732
virtual TBuffer3D * MakeBuffer3D() const
Creates a TBuffer3D describing this shape.
Definition: TGeoPcon.cxx:862
TObjArray * GetNodes()
Definition: TGeoVolume.h:183
static Double_t Tolerance()
Definition: TGeoShape.h:101
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:218
virtual void DistFromOutside_v(const Double_t *points, const Double_t *dirs, Double_t *dists, Int_t vecsize, Double_t *step) const
Compute distance from array of input points having directions specisied by dirs. Store output in dist...
Definition: TGeoPcon.cxx:1426
const char * Data() const
Definition: TString.h:349
virtual void Fatal(const char *method, const char *msgfmt,...) const
Issue fatal error message.
Definition: TObject.cxx:946
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.
Definition: TGeoPcon.cxx:1062
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.
Definition: TGeoCone.cxx:2182
Double_t fDZ
Definition: TGeoBBox.h:35
void Class()
Definition: Class.C:29
void AddVolume(TGeoVolume *vol)
Add a volume with valid shape to the list of volumes.
virtual void Contains_v(const Double_t *points, Bool_t *inside, Int_t vecsize) const
Check the inside status for each of the points in the array.
Definition: TGeoPcon.cxx:1400
Double_t * fPnts
Definition: TBuffer3D.h:114
virtual void InspectShape() const
print shape parameters
Definition: TGeoPcon.cxx:846
virtual void DistFromInside_v(const Double_t *points, const Double_t *dirs, Double_t *dists, Int_t vecsize, Double_t *step) const
Compute distance from array of input points having directions specisied by dirs. Store output in dist...
Definition: TGeoPcon.cxx:1418
Double_t ATan2(Double_t, Double_t)
Definition: TMath.h:454
virtual void SavePrimitive(std::ostream &out, Option_t *option="")
Save a primitive as a C++ statement(s) on output stream "out".
Definition: TGeoPcon.cxx:1182
Double_t fCm
Sine of phi1+dphi.
Definition: TGeoPcon.h:46
XFontStruct * id
Definition: TGX11.cxx:108
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition: TObject.cxx:918
char * out
Definition: TBase64.cxx:29
void SetSectionsValid(UInt_t mask)
Definition: TBuffer3D.h:67
Int_t * fPols
Definition: TBuffer3D.h:116
Bool_t fLocalFrame
Definition: TBuffer3D.h:92
point * points
Definition: X3DBuffer.c:20
void TransformPoints(Double_t *points, UInt_t NbPoints) const
Tranform a set of points (LocalToMaster)
Definition: TGeoShape.cxx:550
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...
Definition: TGeoTube.cxx:1514
Double_t GetDphi() const
Definition: TGeoPcon.h:86
float ymax
Definition: THbookFile.cxx:93
TNamed & operator=(const TNamed &rhs)
TNamed assignment operator.
Definition: TNamed.cxx:40
Int_t IndexOf(const TObject *obj) const
Definition: TObjArray.cxx:551
virtual void GetMeshNumbers(Int_t &nvert, Int_t &nsegs, Int_t &npols) const
Returns numbers of vertices, segments and polygons composing the shape mesh.
Definition: TGeoPcon.cxx:1325
Bool_t fFullPhi
Definition: TGeoPcon.h:41
ROOT::R::TRInterface & r
Definition: Object.C:4
virtual Double_t DistFromOutside(const Double_t *point, const Double_t *dir, Int_t iact=1, Double_t step=TGeoShape::Big(), Double_t *safe=0) const
compute distance from outside point to surface of the tube
Definition: TGeoPcon.cxx:570
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:271
virtual Double_t GetAxisRange(Int_t iaxis, Double_t &xlo, Double_t &xhi) const
Get range of shape for a given axis.
Definition: TGeoPcon.cxx:764
virtual const char * GetAxisName(Int_t iaxis) const
Returns name of axis IAXIS.
Definition: TGeoPcon.cxx:747
virtual TGeoVolume * Divide(TGeoVolume *voldiv, const char *divname, Int_t iaxis, Int_t ndiv, Double_t start, Double_t step)
— Divide this polycone shape belonging to volume "voldiv" into ndiv volumes called divname...
Definition: TGeoPcon.cxx:663
virtual const char * ClassName() const
Returns name of class to which the object belongs.
Definition: TObject.cxx:187
Double_t fPhi1
Definition: TGeoPcon.h:36
virtual Double_t Capacity() const
Computes capacity of the shape in [length^3].
Definition: TGeoCone.cxx:1286
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:530
Int_t fNz
Definition: TGeoPcon.h:35
Bool_t TestBit(UInt_t f) const
Definition: TObject.h:173
TMarker * m
Definition: textangle.C:8
virtual void ComputeBBox()
compute bounding box of the pcon Check if the sections are in increasing Z order
Definition: TGeoPcon.cxx:282
Double_t * GetZ() const
Definition: TGeoPcon.h:93
Double_t E()
Definition: TMath.h:54
Bool_t SetRawSizes(UInt_t reqPnts, UInt_t reqPntsCapacity, UInt_t reqSegs, UInt_t reqSegsCapacity, UInt_t reqPols, UInt_t reqPolsCapacity)
Set kRaw tessellation section of buffer with supplied sizes.
Definition: TBuffer3D.cxx:357
Generic 3D primitive description class.
Definition: TBuffer3D.h:19
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:230
float xmax
Definition: THbookFile.cxx:93
virtual const TBuffer3D & GetBuffer3D(Int_t reqSections, Bool_t localFrame) const
Fills a static 3D buffer and returns a reference.
Definition: TGeoPcon.cxx:1338
void SetDivIndex(Int_t index)
virtual const char * GetName() const
Get the shape name.
Definition: TGeoShape.cxx:247
Double_t Cos(Double_t)
Definition: TMath.h:424
Double_t * fZ
Definition: TGeoPcon.h:40
virtual void Safety_v(const Double_t *points, const Bool_t *inside, Double_t *safe, Int_t vecsize) const
Compute safe distance from each of the points in the input array.
Definition: TGeoPcon.cxx:1436
Double_t Pi()
Definition: TMath.h:44
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:851
virtual Int_t ReadClassBuffer(const TClass *cl, void *pointer, const TClass *onfile_class=0)=0
virtual Double_t Safety(const Double_t *point, Bool_t in=kTRUE) const
computes the closest distance from given point to this shape, according to option.
Definition: TGeoPcon.cxx:1095
virtual void GetBoundingCylinder(Double_t *param) const
— Fill vector param[4] with the bounding cylinder parameters.
Definition: TGeoPcon.cxx:788
virtual void InspectShape() const
Prints shape parameters.
Definition: TGeoBBox.cxx:749
Double_t * GetRmin() const
Definition: TGeoPcon.h:89
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...
Definition: TGeoTube.cxx:1449
R__EXTERN TGeoManager * gGeoManager
Definition: TGeoManager.h:556
double Double_t
Definition: RtypesCore.h:55
virtual void FillBuffer3D(TBuffer3D &buffer, Int_t reqSections, Bool_t localFrame) const
Fills the supplied buffer, with sections in desired frame See TBuffer3D.h for explanation of sections...
Definition: TGeoBBox.cxx:989
ClassImp(TMCParticle) void TMCParticle printf(": p=(%7.3f,%7.3f,%9.3f) ;", fPx, fPy, fPz)
Int_t ShapeDistancetoPrimitive(Int_t numpoints, Int_t px, Int_t py) const
Returns distance to shape primitive mesh.
Definition: TGeoShape.cxx:258
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.
Definition: TGeoTube.cxx:2096
const char * GetPointerName() const
Provide a pointer name containing uid.
Definition: TGeoShape.cxx:697
static Double_t Big()
Definition: TGeoShape.h:98
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.
Definition: TGeoCone.cxx:1402
Double_t fDY
Definition: TGeoBBox.h:34
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
Definition: TGeoCone.cxx:1541
#define name(a, b)
Definition: linkTestLib0.cpp:5
void SetShapeBit(UInt_t f, Bool_t set)
Equivalent of TObject::SetBit.
Definition: TGeoShape.cxx:522
Int_t * fSegs
Definition: TBuffer3D.h:115
virtual void SetSegsAndPols(TBuffer3D &buff) const
Fill TBuffer3D structure for segments and polygons.
Definition: TGeoPcon.cxx:890
Double_t * GetRmax() const
Definition: TGeoPcon.h:91
virtual Int_t GetNmeshVertices() const
Return number of vertices of the mesh representation.
Definition: TGeoPcon.cxx:1298
UInt_t NbPnts() const
Definition: TBuffer3D.h:82
TGeoMedium * GetMedium() const
Definition: TGeoVolume.h:189
virtual Double_t Capacity() const
Computes capacity of the shape in [length^3].
Definition: TGeoPcon.cxx:259
Short_t Max(Short_t a, Short_t b)
Definition: TMathBase.h:202
virtual void Sizeof3D() const
Definition: TGeoPcon.cxx:1318
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:332
Double_t * fRmax
Definition: TGeoPcon.h:39
Double_t Sin(Double_t)
Definition: TMath.h:421
virtual Double_t DistFromInside(const Double_t *point, const Double_t *dir, Int_t iact=1, Double_t step=TGeoShape::Big(), Double_t *safe=0) const
compute distance from inside point to surface of the polycone
Definition: TGeoPcon.cxx:466
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:615
#define NULL
Definition: Rtypes.h:82
Double_t fDX
Definition: TGeoBBox.h:33
ClassImp(TGeoPcon) TGeoPcon
dummy ctor
Definition: TGeoPcon.cxx:59
virtual void ComputeNormal_v(const Double_t *points, const Double_t *dirs, Double_t *norms, Int_t vecsize)
Compute the normal for an array o points so that norm.dot.dir is positive Input: Arrays of point coor...
Definition: TGeoPcon.cxx:1410
Double_t Sqrt(Double_t x)
Definition: TMath.h:464
TObject * At(Int_t idx) const
Definition: TObjArray.h:167
Long64_t LocMin(Long64_t n, const T *a)
Definition: TMath.h:695
const Bool_t kTRUE
Definition: Rtypes.h:91
Double_t * fRmin
Definition: TGeoPcon.h:38
double norm(double *x, double *p)
Definition: unuranDistr.cxx:40
const Int_t n
Definition: legend1.C:16
Double_t fSm
Cosine of (phi1+phi2)/2.
Definition: TGeoPcon.h:47
Long64_t BinarySearch(Long64_t n, const T *array, T value)
Definition: TMath.h:944
Double_t fCdphi
Sine of (phi1+phi2)/2.
Definition: TGeoPcon.h:48
unsigned int r2[N_CITIES]
Definition: simanTSP.cxx:322
Int_t GetNz() const
Definition: TGeoPcon.h:87
Bool_t SectionsValid(UInt_t mask) const
Definition: TBuffer3D.h:69
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition: TObject.cxx:904