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