ROOT  6.07/01
Reference Guide
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
TGeoCone.cxx
Go to the documentation of this file.
1 // @(#)root/geom:$Id$
2 // Author: Andrei Gheata 31/01/02
3 // TGeoCone::Contains() and DistFromInside() 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 // TGeoCone - conical tube class. It has 5 parameters :
15 // dz - half length in z
16 // Rmin1, Rmax1 - inside and outside radii at -dz
17 // Rmin2, Rmax2 - inside and outside radii at +dz
18 //
19 //--------------------------------------------------------------------------
20 //Begin_Html
21 /*
22 <img src="gif/t_cone.gif">
23 */
24 //End_Html
25 //
26 //Begin_Html
27 /*
28 <img src="gif/t_conedivR.gif">
29 */
30 //End_Html
31 //
32 //Begin_Html
33 /*
34 <img src="gif/t_conedivPHI.gif">
35 */
36 //End_Html
37 //Begin_Html
38 /*
39 <img src="gif/t_conedivZ.gif">
40 */
41 //End_Html
42 
43 //--------------------------------------------------------------------------
44 // TGeoConeSeg - a phi segment of a conical tube. Has 7 parameters :
45 // - the same 5 as a cone;
46 // - first phi limit (in degrees)
47 // - second phi limit
48 //
49 //--------------------------------------------------------------------------
50 //
51 //Begin_Html
52 /*
53 <img src="gif/t_coneseg.gif">
54 */
55 //End_Html
56 //
57 //Begin_Html
58 /*
59 <img src="gif/t_conesegdivstepZ.gif">
60 */
61 //End_Html
62 
63 #include "Riostream.h"
64 
65 #include "TGeoManager.h"
66 #include "TGeoVolume.h"
67 #include "TVirtualGeoPainter.h"
68 #include "TGeoCone.h"
69 #include "TVirtualPad.h"
70 #include "TBuffer3D.h"
71 #include "TBuffer3DTypes.h"
72 #include "TMath.h"
73 
75 
76 ////////////////////////////////////////////////////////////////////////////////
77 /// Default constructor
78 
80 {
81  SetShapeBit(TGeoShape::kGeoCone);
82  fDz = 0.0;
83  fRmin1 = 0.0;
84  fRmax1 = 0.0;
85  fRmin2 = 0.0;
86  fRmax2 = 0.0;
87 }
88 
89 ////////////////////////////////////////////////////////////////////////////////
90 /// Default constructor specifying minimum and maximum radius
91 
93  Double_t rmin2, Double_t rmax2)
94  :TGeoBBox(0, 0, 0)
95 {
97  SetConeDimensions(dz, rmin1, rmax1, rmin2, rmax2);
98  if ((dz<0) || (rmin1<0) || (rmax1<0) || (rmin2<0) || (rmax2<0)) {
100  }
101  else ComputeBBox();
102 }
103 
104 ////////////////////////////////////////////////////////////////////////////////
105 /// Default constructor specifying minimum and maximum radius
106 
107 TGeoCone::TGeoCone(const char *name, Double_t dz, Double_t rmin1, Double_t rmax1,
108  Double_t rmin2, Double_t rmax2)
109  :TGeoBBox(name, 0, 0, 0)
110 {
112  SetConeDimensions(dz, rmin1, rmax1, rmin2, rmax2);
113  if ((dz<0) || (rmin1<0) || (rmax1<0) || (rmin2<0) || (rmax2<0)) {
115  }
116  else ComputeBBox();
117 }
118 
119 ////////////////////////////////////////////////////////////////////////////////
120 /// Default constructor specifying minimum and maximum radius
121 /// param[0] = dz
122 /// param[1] = Rmin1
123 /// param[2] = Rmax1
124 /// param[3] = Rmin2
125 /// param[4] = Rmax2
126 
128  :TGeoBBox(0, 0, 0)
129 {
131  SetDimensions(param);
132  if ((fDz<0) || (fRmin1<0) || (fRmax1<0) || (fRmin2<0) || (fRmax2<0))
134  else ComputeBBox();
135 }
136 
137 ////////////////////////////////////////////////////////////////////////////////
138 /// Computes capacity of the shape in [length^3]
139 
141 {
143 }
144 
145 ////////////////////////////////////////////////////////////////////////////////
146 /// Computes capacity of the shape in [length^3]
147 
149 {
150  Double_t capacity = (2.*dz*TMath::Pi()/3.)*(rmax1*rmax1+rmax2*rmax2+rmax1*rmax2-
151  rmin1*rmin1-rmin2*rmin2-rmin1*rmin2);
152  return capacity;
153 }
154 
155 ////////////////////////////////////////////////////////////////////////////////
156 /// destructor
157 
159 {
160 }
161 
162 ////////////////////////////////////////////////////////////////////////////////
163 /// compute bounding box of the sphere
164 
166 {
167  TGeoBBox *box = (TGeoBBox*)this;
169  memset(fOrigin, 0, 3*sizeof(Double_t));
170 }
171 
172 ////////////////////////////////////////////////////////////////////////////////
173 /// Compute normal to closest surface from POINT.
174 
176 {
177  Double_t safr,safe,phi;
178  memset(norm,0,3*sizeof(Double_t));
179  phi = TMath::ATan2(point[1],point[0]);
180  Double_t cphi = TMath::Cos(phi);
181  Double_t sphi = TMath::Sin(phi);
182  Double_t ro1 = 0.5*(fRmin1+fRmin2);
183  Double_t tg1 = 0.5*(fRmin2-fRmin1)/fDz;
184  Double_t cr1 = 1./TMath::Sqrt(1.+tg1*tg1);
185  Double_t ro2 = 0.5*(fRmax1+fRmax2);
186  Double_t tg2 = 0.5*(fRmax2-fRmax1)/fDz;
187  Double_t cr2 = 1./TMath::Sqrt(1.+tg2*tg2);
188 
189  Double_t r=TMath::Sqrt(point[0]*point[0]+point[1]*point[1]);
190  Double_t rin = tg1*point[2]+ro1;
191  Double_t rout = tg2*point[2]+ro2;
192  safe = TMath::Abs(fDz-TMath::Abs(point[2]));
193  norm[2] = 1;
194 
195  safr = (ro1>0)?(TMath::Abs((r-rin)*cr1)):TGeoShape::Big();
196  if (safr<safe) {
197  safe = safr;
198  norm[0] = cr1*cphi;
199  norm[1] = cr1*sphi;
200  norm[2] = -tg1*cr1;
201  }
202  safr = TMath::Abs((rout-r)*cr2);
203  if (safr<safe) {
204  norm[0] = cr2*cphi;
205  norm[1] = cr2*sphi;
206  norm[2] = -tg2*cr2;
207  }
208  if (norm[0]*dir[0]+norm[1]*dir[1]+norm[2]*dir[2]<0) {
209  norm[0] = -norm[0];
210  norm[1] = -norm[1];
211  norm[2] = -norm[2];
212  }
213 }
214 
215 ////////////////////////////////////////////////////////////////////////////////
216 /// Compute normal to closest surface from POINT.
217 
219  Double_t dz, Double_t rmin1, Double_t rmax1, Double_t rmin2, Double_t rmax2)
220 {
221  Double_t safe,phi;
222  memset(norm,0,3*sizeof(Double_t));
223  phi = TMath::ATan2(point[1],point[0]);
224  Double_t cphi = TMath::Cos(phi);
225  Double_t sphi = TMath::Sin(phi);
226  Double_t ro1 = 0.5*(rmin1+rmin2);
227  Double_t tg1 = 0.5*(rmin2-rmin1)/dz;
228  Double_t cr1 = 1./TMath::Sqrt(1.+tg1*tg1);
229  Double_t ro2 = 0.5*(rmax1+rmax2);
230  Double_t tg2 = 0.5*(rmax2-rmax1)/dz;
231  Double_t cr2 = 1./TMath::Sqrt(1.+tg2*tg2);
232 
233  Double_t r=TMath::Sqrt(point[0]*point[0]+point[1]*point[1]);
234  Double_t rin = tg1*point[2]+ro1;
235  Double_t rout = tg2*point[2]+ro2;
236  safe = (ro1>0)?(TMath::Abs((r-rin)*cr1)):TGeoShape::Big();
237  norm[0] = cr1*cphi;
238  norm[1] = cr1*sphi;
239  norm[2] = -tg1*cr1;
240  if (TMath::Abs((rout-r)*cr2)<safe) {
241  norm[0] = cr2*cphi;
242  norm[1] = cr2*sphi;
243  norm[2] = -tg2*cr2;
244  }
245  if (norm[0]*dir[0]+norm[1]*dir[1]+norm[2]*dir[2]<0) {
246  norm[0] = -norm[0];
247  norm[1] = -norm[1];
248  norm[2] = -norm[2];
249  }
250 }
251 
252 ////////////////////////////////////////////////////////////////////////////////
253 /// test if point is inside this cone
254 
255 Bool_t TGeoCone::Contains(const Double_t *point) const
256 {
257  if (TMath::Abs(point[2]) > fDz) return kFALSE;
258  Double_t r2 = point[0]*point[0]+point[1]*point[1];
259  Double_t rl = 0.5*(fRmin2*(point[2]+fDz)+fRmin1*(fDz-point[2]))/fDz;
260  Double_t rh = 0.5*(fRmax2*(point[2]+fDz)+fRmax1*(fDz-point[2]))/fDz;
261  if ((r2<rl*rl) || (r2>rh*rh)) return kFALSE;
262  return kTRUE;
263 }
264 
265 ////////////////////////////////////////////////////////////////////////////////
266 /// Compute distance from inside point to surface of the cone (static)
267 /// Boundary safe algorithm.
268 
270  Double_t rmin1, Double_t rmax1, Double_t rmin2, Double_t rmax2)
271 {
272  if (dz<=0) return TGeoShape::Big();
273  // compute distance to surface
274  // Do Z
275  Double_t sz = TGeoShape::Big();
276  if (dir[2]) {
277  sz = (TMath::Sign(dz, dir[2])-point[2])/dir[2];
278  if (sz<=0) return 0.0;
279  }
280  Double_t rsq=point[0]*point[0]+point[1]*point[1];
281  Double_t zinv = 1./dz;
282  Double_t rin = 0.5*(rmin1+rmin2+(rmin2-rmin1)*point[2]*zinv);
283  // Do Rmin
284  Double_t sr = TGeoShape::Big();
285  Double_t b,delta,zi;
286  if (rin>0) {
287  // Protection in case point is actually outside the cone
288  if (rsq < rin*(rin+TGeoShape::Tolerance())) {
289  Double_t ddotn = point[0]*dir[0]+point[1]*dir[1]+0.5*(rmin1-rmin2)*dir[2]*zinv*TMath::Sqrt(rsq);
290  if (ddotn<=0) return 0.0;
291  } else {
292  TGeoCone::DistToCone(point, dir, dz, rmin1, rmin2, b, delta);
293  if (delta>0) {
294  sr = -b-delta;
295  if (sr>0) {
296  zi = point[2]+sr*dir[2];
297  if (TMath::Abs(zi)<=dz) return TMath::Min(sz,sr);
298  }
299  sr = -b+delta;
300  if (sr>0) {
301  zi = point[2]+sr*dir[2];
302  if (TMath::Abs(zi)<=dz) return TMath::Min(sz,sr);
303  }
304  }
305  }
306  }
307  // Do Rmax
308  Double_t rout = 0.5*(rmax1+rmax2+(rmax2-rmax1)*point[2]*zinv);
309  if (rsq > rout*(rout-TGeoShape::Tolerance())) {
310  Double_t ddotn = point[0]*dir[0]+point[1]*dir[1]+0.5*(rmax1-rmax2)*dir[2]*zinv*TMath::Sqrt(rsq);
311  if (ddotn>=0) return 0.0;
312  TGeoCone::DistToCone(point, dir, dz, rmax1, rmax2, b, delta);
313  if (delta<0) return 0.0;
314  sr = -b+delta;
315  if (sr<0) return sz;
316  if (TMath::Abs(-b-delta)>sr) return sz;
317  zi = point[2]+sr*dir[2];
318  if (TMath::Abs(zi)<=dz) return TMath::Min(sz,sr);
319  return sz;
320  }
321  TGeoCone::DistToCone(point, dir, dz, rmax1, rmax2, b, delta);
322  if (delta>0) {
323  sr = -b-delta;
324  if (sr>0) {
325  zi = point[2]+sr*dir[2];
326  if (TMath::Abs(zi)<=dz) return TMath::Min(sz,sr);
327  }
328  sr = -b+delta;
329  if (sr>TGeoShape::Tolerance()) {
330  zi = point[2]+sr*dir[2];
331  if (TMath::Abs(zi)<=dz) return TMath::Min(sz,sr);
332  }
333  }
334  return sz;
335 }
336 
337 ////////////////////////////////////////////////////////////////////////////////
338 /// Compute distance from inside point to surface of the cone
339 /// Boundary safe algorithm.
340 
341 Double_t TGeoCone::DistFromInside(const Double_t *point, const Double_t *dir, Int_t iact, Double_t step, Double_t *safe) const
342 {
343  if (iact<3 && safe) {
344  *safe = Safety(point, kTRUE);
345  if (iact==0) return TGeoShape::Big();
346  if ((iact==1) && (*safe>step)) return TGeoShape::Big();
347  }
348  // compute distance to surface
349  return TGeoCone::DistFromInsideS(point, dir, fDz, fRmin1, fRmax1, fRmin2, fRmax2);
350 }
351 
352 ////////////////////////////////////////////////////////////////////////////////
353 /// Compute distance from outside point to surface of the tube
354 /// Boundary safe algorithm.
355 /// compute distance to Z planes
356 
358  Double_t rmin1, Double_t rmax1, Double_t rmin2, Double_t rmax2)
359 {
360  if (dz<=0) return TGeoShape::Big();
361  Double_t snxt;
362  Double_t xp, yp, zp;
363  Bool_t inz = kTRUE;
364 
365  if (point[2]<=-dz) {
366  if (dir[2]<=0) return TGeoShape::Big();
367  snxt = (-dz-point[2])/dir[2];
368  xp = point[0]+snxt*dir[0];
369  yp = point[1]+snxt*dir[1];
370  Double_t r2 = xp*xp+yp*yp;
371  if ((r2>=rmin1*rmin1) && (r2<=rmax1*rmax1)) return snxt;
372  inz = kFALSE;
373  } else {
374  if (point[2]>=dz) {
375  if (dir[2]>=0) return TGeoShape::Big();
376  snxt = (dz-point[2])/dir[2];
377  xp = point[0]+snxt*dir[0];
378  yp = point[1]+snxt*dir[1];
379  Double_t r2 = xp*xp+yp*yp;
380  if ((r2>=rmin2*rmin2) && (r2<=rmax2*rmax2)) return snxt;
381  inz = kFALSE;
382  }
383  }
384 
385  Double_t rsq = point[0]*point[0]+point[1]*point[1];
386  Double_t dzinv = 1./dz;
387  Double_t ro1=0.5*(rmin1+rmin2);
388  Bool_t hasrmin = (ro1>0)?kTRUE:kFALSE;
389  Double_t tg1 = 0.;
390  Double_t rin = 0.;
391  Bool_t inrmin = kTRUE; // r>=rmin
392  if (hasrmin) {
393  tg1=0.5*(rmin2-rmin1)*dzinv;
394  rin=ro1+tg1*point[2];
395  if (rin>0 && rsq<rin*(rin-TGeoShape::Tolerance())) inrmin=kFALSE;
396  }
397  Double_t ro2=0.5*(rmax1+rmax2);
398  Double_t tg2=0.5*(rmax2-rmax1)*dzinv;
399  Double_t rout=tg2*point[2]+ro2;
400  Bool_t inrmax = kFALSE;
401  if (rout>0 && rsq<rout*(rout+TGeoShape::Tolerance())) inrmax=kTRUE;
402  Bool_t in = inz & inrmin & inrmax;
403  Double_t b,delta;
404  // If inside cone, we are most likely on a boundary within machine precision.
405  if (in) {
406  Double_t r=TMath::Sqrt(rsq);
407  Double_t safz = dz-TMath::Abs(point[2]); // positive
408  Double_t safrmin = (hasrmin)?(r-rin):TGeoShape::Big();
409  Double_t safrmax = rout - r;
410  if (safz<=safrmin && safz<=safrmax) {
411  // on Z boundary
412  if (point[2]*dir[2]<0) return 0.0;
413  return TGeoShape::Big();
414  }
415  if (safrmax<safrmin) {
416  // on rmax boundary
417  Double_t ddotn = point[0]*dir[0]+point[1]*dir[1]-tg2*dir[2]*r;
418  if (ddotn<=0) return 0.0;
419  return TGeoShape::Big();
420  }
421  // on rmin boundary
422  Double_t ddotn = point[0]*dir[0]+point[1]*dir[1]-tg1*dir[2]*r;
423  if (ddotn>=0) return 0.0;
424  // we can cross (+) solution of rmin
425  TGeoCone::DistToCone(point, dir, dz, rmin1, rmin2, b, delta);
426 
427  if (delta<0) return 0.0;
428  snxt = -b+delta;
429  if (snxt<0) return TGeoShape::Big();
430  if (TMath::Abs(-b-delta)>snxt) return TGeoShape::Big();
431  zp = point[2]+snxt*dir[2];
432  if (TMath::Abs(zp)<=dz) return snxt;
433  return TGeoShape::Big();
434  }
435 
436  // compute distance to inner cone
437  snxt = TGeoShape::Big();
438  if (!inrmin) {
439  // ray can cross inner cone (but not only!)
440  TGeoCone::DistToCone(point, dir, dz, rmin1, rmin2, b, delta);
441  if (delta<0) return TGeoShape::Big();
442  snxt = -b+delta;
443  if (snxt>0) {
444  zp = point[2]+snxt*dir[2];
445  if (TMath::Abs(zp)<=dz) return snxt;
446  }
447  snxt = -b-delta;
448  if (snxt>0) {
449  zp = point[2]+snxt*dir[2];
450  if (TMath::Abs(zp)<=dz) return snxt;
451  }
452  snxt = TGeoShape::Big();
453  } else {
454  if (hasrmin) {
455  TGeoCone::DistToCone(point, dir, dz, rmin1, rmin2, b, delta);
456  if (delta>0) {
457  Double_t din = -b+delta;
458  if (din>0) {
459  zp = point[2]+din*dir[2];
460  if (TMath::Abs(zp)<=dz) snxt = din;
461  }
462  }
463  }
464  }
465 
466  if (inrmax) return snxt;
467  // We can cross outer cone, both solutions possible
468  // compute distance to outer cone
469  TGeoCone::DistToCone(point, dir, dz, rmax1, rmax2, b, delta);
470  if (delta<0) return snxt;
471  Double_t dout = -b-delta;
472  if (dout>0 && dout<snxt) {
473  zp = point[2]+dout*dir[2];
474  if (TMath::Abs(zp)<=dz) return dout;
475  }
476  dout = -b+delta;
477  if (dout<=0 || dout>snxt) return snxt;
478  zp = point[2]+dout*dir[2];
479  if (TMath::Abs(zp)<=dz) return dout;
480  return snxt;
481 }
482 
483 ////////////////////////////////////////////////////////////////////////////////
484 /// compute distance from outside point to surface of the tube
485 /// compute safe radius
486 
487 Double_t TGeoCone::DistFromOutside(const Double_t *point, const Double_t *dir, Int_t iact, Double_t step, Double_t *safe) const
488 {
489  if (iact<3 && safe) {
490  *safe = Safety(point, kFALSE);
491  if (iact==0) return TGeoShape::Big();
492  if ((iact==1) && (*safe>step)) return TGeoShape::Big();
493  }
494 // Check if the bounding box is crossed within the requested distance
495  Double_t sdist = TGeoBBox::DistFromOutside(point,dir, fDX, fDY, fDZ, fOrigin, step);
496  if (sdist>=step) return TGeoShape::Big();
497  // compute distance to Z planes
498  return TGeoCone::DistFromOutsideS(point, dir, fDz, fRmin1, fRmax1, fRmin2, fRmax2);
499 }
500 
501 ////////////////////////////////////////////////////////////////////////////////
502 /// Static method to compute distance to a conical surface with :
503 /// - r1, z1 - radius and Z position of lower base
504 /// - r2, z2 - radius and Z position of upper base
505 
507  Double_t &b, Double_t &delta)
508 {
509  delta = -1.;
510  if (dz<0) return;
511  Double_t ro0 = 0.5*(r1+r2);
512  Double_t tz = 0.5*(r2-r1)/dz;
513  Double_t rsq = point[0]*point[0] + point[1]*point[1];
514  Double_t rc = ro0 + point[2]*tz;
515 
516  Double_t a = dir[0]*dir[0] + dir[1]*dir[1] - tz*tz*dir[2]*dir[2];
517  b = point[0]*dir[0] + point[1]*dir[1] - tz*rc*dir[2];
518  Double_t c = rsq - rc*rc;
519 
520  if (TMath::Abs(a)<TGeoShape::Tolerance()) {
521  if (TMath::Abs(b)<TGeoShape::Tolerance()) return;
522  b = 0.5*c/b;
523  delta = 0.;
524  return;
525  }
526  a = 1./a;
527  b *= a;
528  c *= a;
529  delta = b*b - c;
530  if (delta>0) {
531  delta = TMath::Sqrt(delta);
532  } else {
533  delta = -1.;
534  }
535 }
536 
537 ////////////////////////////////////////////////////////////////////////////////
538 /// compute closest distance from point px,py to each corner
539 
541 {
543  const Int_t numPoints = 4*n;
544  return ShapeDistancetoPrimitive(numPoints, px, py);
545 }
546 
547 ////////////////////////////////////////////////////////////////////////////////
548 ///--- Divide this cone shape belonging to volume "voldiv" into ndiv volumes
549 /// called divname, from start position with the given step. Returns pointer
550 /// to created division cell volume in case of Z divisions. For Z division
551 /// creates all volumes with different shapes and returns pointer to volume that
552 /// was divided. In case a wrong division axis is supplied, returns pointer to
553 /// volume that was divided.
554 
555 TGeoVolume *TGeoCone::Divide(TGeoVolume *voldiv, const char *divname, Int_t iaxis, Int_t ndiv,
556  Double_t start, Double_t step)
557 {
558  TGeoShape *shape; //--- shape to be created
559  TGeoVolume *vol; //--- division volume to be created
560  TGeoVolumeMulti *vmulti; //--- generic divided volume
561  TGeoPatternFinder *finder; //--- finder to be attached
562  TString opt = ""; //--- option to be attached
563  Int_t id;
564  Double_t end = start+ndiv*step;
565  switch (iaxis) {
566  case 1: //--- R division
567  Error("Divide","division of a cone on R not implemented");
568  return 0;
569  case 2: // --- Phi division
570  finder = new TGeoPatternCylPhi(voldiv, ndiv, start, end);
571  voldiv->SetFinder(finder);
572  finder->SetDivIndex(voldiv->GetNdaughters());
573  shape = new TGeoConeSeg(fDz, fRmin1, fRmax1, fRmin2, fRmax2, -step/2, step/2);
574  vol = new TGeoVolume(divname, shape, voldiv->GetMedium());
575  vmulti = gGeoManager->MakeVolumeMulti(divname, voldiv->GetMedium());
576  vmulti->AddVolume(vol);
577  opt = "Phi";
578  for (id=0; id<ndiv; id++) {
579  voldiv->AddNodeOffset(vol, id, start+id*step+step/2, opt.Data());
580  ((TGeoNodeOffset*)voldiv->GetNodes()->At(voldiv->GetNdaughters()-1))->SetFinder(finder);
581  }
582  return vmulti;
583  case 3: //--- Z division
584  vmulti = gGeoManager->MakeVolumeMulti(divname, voldiv->GetMedium());
585  finder = new TGeoPatternZ(voldiv, ndiv, start, end);
586  voldiv->SetFinder(finder);
587  finder->SetDivIndex(voldiv->GetNdaughters());
588  for (id=0; id<ndiv; id++) {
589  Double_t z1 = start+id*step;
590  Double_t z2 = start+(id+1)*step;
591  Double_t rmin1n = 0.5*(fRmin1*(fDz-z1)+fRmin2*(fDz+z1))/fDz;
592  Double_t rmax1n = 0.5*(fRmax1*(fDz-z1)+fRmax2*(fDz+z1))/fDz;
593  Double_t rmin2n = 0.5*(fRmin1*(fDz-z2)+fRmin2*(fDz+z2))/fDz;
594  Double_t rmax2n = 0.5*(fRmax1*(fDz-z2)+fRmax2*(fDz+z2))/fDz;
595  shape = new TGeoCone(0.5*step,rmin1n, rmax1n, rmin2n, rmax2n);
596  vol = new TGeoVolume(divname, shape, voldiv->GetMedium());
597  vmulti->AddVolume(vol);
598  opt = "Z";
599  voldiv->AddNodeOffset(vol, id, start+id*step+step/2, opt.Data());
600  ((TGeoNodeOffset*)voldiv->GetNodes()->At(voldiv->GetNdaughters()-1))->SetFinder(finder);
601  }
602  return vmulti;
603  default:
604  Error("Divide", "Wrong axis type for division");
605  return 0;
606  }
607 }
608 
609 ////////////////////////////////////////////////////////////////////////////////
610 /// Returns name of axis IAXIS.
611 
612 const char *TGeoCone::GetAxisName(Int_t iaxis) const
613 {
614  switch (iaxis) {
615  case 1:
616  return "R";
617  case 2:
618  return "PHI";
619  case 3:
620  return "Z";
621  default:
622  return "undefined";
623  }
624 }
625 
626 ////////////////////////////////////////////////////////////////////////////////
627 /// Get range of shape for a given axis.
628 
630 {
631  xlo = 0;
632  xhi = 0;
633  Double_t dx = 0;
634  switch (iaxis) {
635  case 2:
636  xlo = 0.;
637  xhi = 360.;
638  return 360.;
639  case 3:
640  xlo = -fDz;
641  xhi = fDz;
642  dx = xhi-xlo;
643  return dx;
644  }
645  return dx;
646 }
647 
648 ////////////////////////////////////////////////////////////////////////////////
649 ///--- Fill vector param[4] with the bounding cylinder parameters. The order
650 /// is the following : Rmin, Rmax, Phi1, Phi2, dZ
651 
653 {
654  param[0] = TMath::Min(fRmin1, fRmin2); // Rmin
655  param[0] *= param[0];
656  param[1] = TMath::Max(fRmax1, fRmax2); // Rmax
657  param[1] *= param[1];
658  param[2] = 0.; // Phi1
659  param[3] = 360.; // Phi1
660 }
661 
662 ////////////////////////////////////////////////////////////////////////////////
663 /// in case shape has some negative parameters, these has to be computed
664 /// in order to fit the mother
665 
667 {
668  if (!TestShapeBit(kGeoRunTimeShape)) return 0;
669  if (!mother->TestShapeBit(kGeoCone)) {
670  Error("GetMakeRuntimeShape", "invalid mother");
671  return 0;
672  }
673  Double_t rmin1, rmax1, rmin2, rmax2, dz;
674  rmin1 = fRmin1;
675  rmax1 = fRmax1;
676  rmin2 = fRmin2;
677  rmax2 = fRmax2;
678  dz = fDz;
679  if (fDz<0) dz=((TGeoCone*)mother)->GetDz();
680  if (fRmin1<0)
681  rmin1 = ((TGeoCone*)mother)->GetRmin1();
682  if (fRmax1<0)
683  rmax1 = ((TGeoCone*)mother)->GetRmax1();
684  if (fRmin2<0)
685  rmin2 = ((TGeoCone*)mother)->GetRmin2();
686  if (fRmax2<0)
687  rmax2 = ((TGeoCone*)mother)->GetRmax2();
688 
689  return (new TGeoCone(GetName(), dz, rmin1, rmax1, rmin2, rmax2));
690 }
691 
692 ////////////////////////////////////////////////////////////////////////////////
693 /// Fills array with n random points located on the line segments of the shape mesh.
694 /// The output array must be provided with a length of minimum 3*npoints. Returns
695 /// true if operation is implemented.
696 
698 {
699  if (npoints > (npoints/2)*2) {
700  Error("GetPointsOnSegments","Npoints must be even number");
701  return kFALSE;
702  }
703  Bool_t hasrmin = (fRmin1>0 || fRmin2>0)?kTRUE:kFALSE;
704  Int_t nc = 0;
705  if (hasrmin) nc = (Int_t)TMath::Sqrt(0.5*npoints);
706  else nc = (Int_t)TMath::Sqrt(1.*npoints);
707  Double_t dphi = TMath::TwoPi()/nc;
708  Double_t phi = 0;
709  Int_t ntop = 0;
710  if (hasrmin) ntop = npoints/2 - nc*(nc-1);
711  else ntop = npoints - nc*(nc-1);
712  Double_t dz = 2*fDz/(nc-1);
713  Double_t z = 0;
714  Int_t icrt = 0;
715  Int_t nphi = nc;
716  Double_t rmin = 0.;
717  Double_t rmax = 0.;
718  // loop z sections
719  for (Int_t i=0; i<nc; i++) {
720  if (i == (nc-1)) nphi = ntop;
721  z = -fDz + i*dz;
722  if (hasrmin) rmin = 0.5*(fRmin1+fRmin2) + 0.5*(fRmin2-fRmin1)*z/fDz;
723  rmax = 0.5*(fRmax1+fRmax2) + 0.5*(fRmax2-fRmax1)*z/fDz;
724  // loop points on circle sections
725  for (Int_t j=0; j<nphi; j++) {
726  phi = j*dphi;
727  if (hasrmin) {
728  array[icrt++] = rmin * TMath::Cos(phi);
729  array[icrt++] = rmin * TMath::Sin(phi);
730  array[icrt++] = z;
731  }
732  array[icrt++] = rmax * TMath::Cos(phi);
733  array[icrt++] = rmax * TMath::Sin(phi);
734  array[icrt++] = z;
735  }
736  }
737  return kTRUE;
738 }
739 
740 
741 ////////////////////////////////////////////////////////////////////////////////
742 /// print shape parameters
743 
745 {
746  printf("*** Shape %s TGeoCone ***\n", GetName());
747  printf(" dz =: %11.5f\n", fDz);
748  printf(" Rmin1 = %11.5f\n", fRmin1);
749  printf(" Rmax1 = %11.5f\n", fRmax1);
750  printf(" Rmin2 = %11.5f\n", fRmin2);
751  printf(" Rmax2 = %11.5f\n", fRmax2);
752  printf(" Bounding box:\n");
754 }
755 
756 ////////////////////////////////////////////////////////////////////////////////
757 /// Creates a TBuffer3D describing *this* shape.
758 /// Coordinates are in local reference frame.
759 
761 {
763  Int_t nbPnts = 4*n;
764  Int_t nbSegs = 8*n;
765  Int_t nbPols = 4*n;
767  nbPnts, 3*nbPnts,
768  nbSegs, 3*nbSegs,
769  nbPols, 6*nbPols);
770 
771  if (buff)
772  {
773  SetPoints(buff->fPnts);
774  SetSegsAndPols(*buff);
775  }
776  return buff;
777 }
778 
779 ////////////////////////////////////////////////////////////////////////////////
780 /// Fill TBuffer3D structure for segments and polygons.
781 
783 {
784  Int_t i,j;
786  Int_t c = GetBasicColor();
787 
788  for (i = 0; i < 4; i++) {
789  for (j = 0; j < n; j++) {
790  buffer.fSegs[(i*n+j)*3 ] = c;
791  buffer.fSegs[(i*n+j)*3+1] = i*n+j;
792  buffer.fSegs[(i*n+j)*3+2] = i*n+j+1;
793  }
794  buffer.fSegs[(i*n+j-1)*3+2] = i*n;
795  }
796  for (i = 4; i < 6; i++) {
797  for (j = 0; j < n; j++) {
798  buffer.fSegs[(i*n+j)*3 ] = c+1;
799  buffer.fSegs[(i*n+j)*3+1] = (i-4)*n+j;
800  buffer.fSegs[(i*n+j)*3+2] = (i-2)*n+j;
801  }
802  }
803  for (i = 6; i < 8; i++) {
804  for (j = 0; j < n; j++) {
805  buffer.fSegs[(i*n+j)*3 ] = c;
806  buffer.fSegs[(i*n+j)*3+1] = 2*(i-6)*n+j;
807  buffer.fSegs[(i*n+j)*3+2] = (2*(i-6)+1)*n+j;
808  }
809  }
810 
811  Int_t indx = 0;
812  i=0;
813  for (j = 0; j < n; j++) {
814  indx = 6*(i*n+j);
815  buffer.fPols[indx ] = c;
816  buffer.fPols[indx+1] = 4;
817  buffer.fPols[indx+5] = i*n+j;
818  buffer.fPols[indx+4] = (4+i)*n+j;
819  buffer.fPols[indx+3] = (2+i)*n+j;
820  buffer.fPols[indx+2] = (4+i)*n+j+1;
821  }
822  buffer.fPols[indx+2] = (4+i)*n;
823  i=1;
824  for (j = 0; j < n; j++) {
825  indx = 6*(i*n+j);
826  buffer.fPols[indx ] = c;
827  buffer.fPols[indx+1] = 4;
828  buffer.fPols[indx+2] = i*n+j;
829  buffer.fPols[indx+3] = (4+i)*n+j;
830  buffer.fPols[indx+4] = (2+i)*n+j;
831  buffer.fPols[indx+5] = (4+i)*n+j+1;
832  }
833  buffer.fPols[indx+5] = (4+i)*n;
834  i=2;
835  for (j = 0; j < n; j++) {
836  indx = 6*(i*n+j);
837  buffer.fPols[indx ] = c+i;
838  buffer.fPols[indx+1] = 4;
839  buffer.fPols[indx+2] = (i-2)*2*n+j;
840  buffer.fPols[indx+3] = (4+i)*n+j;
841  buffer.fPols[indx+4] = ((i-2)*2+1)*n+j;
842  buffer.fPols[indx+5] = (4+i)*n+j+1;
843  }
844  buffer.fPols[indx+5] = (4+i)*n;
845  i=3;
846  for (j = 0; j < n; j++) {
847  indx = 6*(i*n+j);
848  buffer.fPols[indx ] = c+i;
849  buffer.fPols[indx+1] = 4;
850  buffer.fPols[indx+5] = (i-2)*2*n+j;
851  buffer.fPols[indx+4] = (4+i)*n+j;
852  buffer.fPols[indx+3] = ((i-2)*2+1)*n+j;
853  buffer.fPols[indx+2] = (4+i)*n+j+1;
854  }
855  buffer.fPols[indx+2] = (4+i)*n;
856 }
857 
858 ////////////////////////////////////////////////////////////////////////////////
859 /// computes the closest distance from given point to this shape, according
860 /// to option. The matching point on the shape is stored in spoint.
861 
862 Double_t TGeoCone::Safety(const Double_t *point, Bool_t in) const
863 {
864  Double_t saf[4];
865  Double_t r=TMath::Sqrt(point[0]*point[0]+point[1]*point[1]);
866  saf[0] = TGeoShape::SafetySeg(r,point[2], fRmin1, -fDz, fRmax1, -fDz, !in);
867  saf[1] = TGeoShape::SafetySeg(r,point[2], fRmax2, fDz, fRmin2, fDz, !in);
868  saf[2] = TGeoShape::SafetySeg(r,point[2], fRmin2, fDz, fRmin1, -fDz, !in);
869  saf[3] = TGeoShape::SafetySeg(r,point[2], fRmax1, -fDz, fRmax2, fDz, !in);
870  return saf[TMath::LocMin(4,saf)];
871 }
872 
873 ////////////////////////////////////////////////////////////////////////////////
874 /// computes the closest distance from given point to this shape, according
875 /// to option. The matching point on the shape is stored in spoint.
876 
878  Double_t rmin2, Double_t rmax2, Int_t skipz)
879 {
880  Double_t saf[4];
881  Double_t r=TMath::Sqrt(point[0]*point[0]+point[1]*point[1]);
882 // Double_t rin = tg1*point[2]+ro1;
883 // Double_t rout = tg2*point[2]+ro2;
884  switch (skipz) {
885  case 1: // skip lower Z plane
886  saf[0] = TGeoShape::Big();
887  saf[1] = TGeoShape::SafetySeg(r,point[2], rmax2, dz, rmin2, dz, !in);
888  break;
889  case 2: // skip upper Z plane
890  saf[0] = TGeoShape::SafetySeg(r,point[2], rmin1, -dz, rmax1, -dz, !in);
891  saf[1] = TGeoShape::Big();
892  break;
893  case 3: // skip both
894  saf[0] = saf[1] = TGeoShape::Big();
895  break;
896  default:
897  saf[0] = TGeoShape::SafetySeg(r,point[2], rmin1, -dz, rmax1, -dz, !in);
898  saf[1] = TGeoShape::SafetySeg(r,point[2], rmax2, dz, rmin2, dz, !in);
899  }
900  // Safety to inner part
901  if (rmin1>0 || rmin2>0)
902  saf[2] = TGeoShape::SafetySeg(r,point[2], rmin2, dz, rmin1, -dz, !in);
903  else
904  saf[2] = TGeoShape::Big();
905  saf[3] = TGeoShape::SafetySeg(r,point[2], rmax1, -dz, rmax2, dz, !in);
906  return saf[TMath::LocMin(4,saf)];
907 }
908 
909 ////////////////////////////////////////////////////////////////////////////////
910 /// Save a primitive as a C++ statement(s) on output stream "out".
911 
912 void TGeoCone::SavePrimitive(std::ostream &out, Option_t * /*option*/ /*= ""*/)
913 {
914  if (TObject::TestBit(kGeoSavePrimitive)) return;
915  out << " // Shape: " << GetName() << " type: " << ClassName() << std::endl;
916  out << " dz = " << fDz << ";" << std::endl;
917  out << " rmin1 = " << fRmin1 << ";" << std::endl;
918  out << " rmax1 = " << fRmax1 << ";" << std::endl;
919  out << " rmin2 = " << fRmin2 << ";" << std::endl;
920  out << " rmax2 = " << fRmax2 << ";" << std::endl;
921  out << " TGeoShape *" << GetPointerName() << " = new TGeoCone(\"" << GetName() << "\", dz,rmin1,rmax1,rmin2,rmax2);" << std::endl;
923 }
924 
925 ////////////////////////////////////////////////////////////////////////////////
926 /// Set cone dimensions.
927 
929  Double_t rmin2, Double_t rmax2)
930 {
931  if (rmin1>=0) {
932  if (rmax1>0) {
933  if (rmin1<=rmax1) {
934  // normal rmin/rmax
935  fRmin1 = rmin1;
936  fRmax1 = rmax1;
937  } else {
938  fRmin1 = rmax1;
939  fRmax1 = rmin1;
940  Warning("SetConeDimensions", "rmin1>rmax1 Switch rmin1<->rmax1");
942  }
943  } else {
944  // run-time
945  fRmin1 = rmin1;
946  fRmax1 = rmax1;
947  }
948  } else {
949  // run-time
950  fRmin1 = rmin1;
951  fRmax1 = rmax1;
952  }
953  if (rmin2>=0) {
954  if (rmax2>0) {
955  if (rmin2<=rmax2) {
956  // normal rmin/rmax
957  fRmin2 = rmin2;
958  fRmax2 = rmax2;
959  } else {
960  fRmin2 = rmax2;
961  fRmax2 = rmin2;
962  Warning("SetConeDimensions", "rmin2>rmax2 Switch rmin2<->rmax2");
964  }
965  } else {
966  // run-time
967  fRmin2 = rmin2;
968  fRmax2 = rmax2;
969  }
970  } else {
971  // run-time
972  fRmin2 = rmin2;
973  fRmax2 = rmax2;
974  }
975 
976  fDz = dz;
977 }
978 
979 ////////////////////////////////////////////////////////////////////////////////
980 /// Set cone dimensions from an array.
981 
983 {
984  Double_t dz = param[0];
985  Double_t rmin1 = param[1];
986  Double_t rmax1 = param[2];
987  Double_t rmin2 = param[3];
988  Double_t rmax2 = param[4];
989  SetConeDimensions(dz, rmin1, rmax1, rmin2, rmax2);
990 }
991 
992 ////////////////////////////////////////////////////////////////////////////////
993 /// Create cone mesh points.
994 
996 {
997  Double_t dz, phi, dphi;
998  Int_t j, n;
999 
1000  n = gGeoManager->GetNsegments();
1001  dphi = 360./n;
1002  dz = fDz;
1003  Int_t indx = 0;
1004 
1005  if (points) {
1006  for (j = 0; j < n; j++) {
1007  phi = j*dphi*TMath::DegToRad();
1008  points[indx++] = fRmin1 * TMath::Cos(phi);
1009  points[indx++] = fRmin1 * TMath::Sin(phi);
1010  points[indx++] = -dz;
1011  }
1012 
1013  for (j = 0; j < n; j++) {
1014  phi = j*dphi*TMath::DegToRad();
1015  points[indx++] = fRmax1 * TMath::Cos(phi);
1016  points[indx++] = fRmax1 * TMath::Sin(phi);
1017  points[indx++] = -dz;
1018  }
1019 
1020  for (j = 0; j < n; j++) {
1021  phi = j*dphi*TMath::DegToRad();
1022  points[indx++] = fRmin2 * TMath::Cos(phi);
1023  points[indx++] = fRmin2 * TMath::Sin(phi);
1024  points[indx++] = dz;
1025  }
1026 
1027  for (j = 0; j < n; j++) {
1028  phi = j*dphi*TMath::DegToRad();
1029  points[indx++] = fRmax2 * TMath::Cos(phi);
1030  points[indx++] = fRmax2 * TMath::Sin(phi);
1031  points[indx++] = dz;
1032  }
1033  }
1034 }
1035 
1036 ////////////////////////////////////////////////////////////////////////////////
1037 /// Create cone mesh points.
1038 
1040 {
1041  Double_t dz, phi, dphi;
1042  Int_t j, n;
1043 
1044  n = gGeoManager->GetNsegments();
1045  dphi = 360./n;
1046  dz = fDz;
1047  Int_t indx = 0;
1048 
1049  if (points) {
1050  for (j = 0; j < n; j++) {
1051  phi = j*dphi*TMath::DegToRad();
1052  points[indx++] = fRmin1 * TMath::Cos(phi);
1053  points[indx++] = fRmin1 * TMath::Sin(phi);
1054  points[indx++] = -dz;
1055  }
1056 
1057  for (j = 0; j < n; j++) {
1058  phi = j*dphi*TMath::DegToRad();
1059  points[indx++] = fRmax1 * TMath::Cos(phi);
1060  points[indx++] = fRmax1 * TMath::Sin(phi);
1061  points[indx++] = -dz;
1062  }
1063 
1064  for (j = 0; j < n; j++) {
1065  phi = j*dphi*TMath::DegToRad();
1066  points[indx++] = fRmin2 * TMath::Cos(phi);
1067  points[indx++] = fRmin2 * TMath::Sin(phi);
1068  points[indx++] = dz;
1069  }
1070 
1071  for (j = 0; j < n; j++) {
1072  phi = j*dphi*TMath::DegToRad();
1073  points[indx++] = fRmax2 * TMath::Cos(phi);
1074  points[indx++] = fRmax2 * TMath::Sin(phi);
1075  points[indx++] = dz;
1076  }
1077  }
1078 }
1079 
1080 ////////////////////////////////////////////////////////////////////////////////
1081 /// Returns numbers of vertices, segments and polygons composing the shape mesh.
1082 
1083 void TGeoCone::GetMeshNumbers(Int_t &nvert, Int_t &nsegs, Int_t &npols) const
1084 {
1086  nvert = n*4;
1087  nsegs = n*8;
1088  npols = n*4;
1089 }
1090 
1091 ////////////////////////////////////////////////////////////////////////////////
1092 /// Return number of vertices of the mesh representation
1093 
1095 {
1097  Int_t numPoints = n*4;
1098  return numPoints;
1099 }
1100 
1101 ////////////////////////////////////////////////////////////////////////////////
1102 ////// fill size of this 3-D object
1103 //// TVirtualGeoPainter *painter = gGeoManager->GetGeomPainter();
1104 //// if (!painter) return;
1105 //// Int_t n = gGeoManager->GetNsegments();
1106 //// Int_t numPoints = n*4;
1107 //// Int_t numSegs = n*8;
1108 //// Int_t numPolys = n*4;
1109 //// painter->AddSize3D(numPoints, numSegs, numPolys);
1110 
1112 {
1113 }
1114 
1115 ////////////////////////////////////////////////////////////////////////////////
1116 /// Fills a static 3D buffer and returns a reference.
1117 
1118 const TBuffer3D & TGeoCone::GetBuffer3D(Int_t reqSections, Bool_t localFrame) const
1119 {
1121 
1122  TGeoBBox::FillBuffer3D(buffer, reqSections, localFrame);
1123 
1124  if (reqSections & TBuffer3D::kRawSizes) {
1126  Int_t nbPnts = 4*n;
1127  Int_t nbSegs = 8*n;
1128  Int_t nbPols = 4*n;
1129  if (buffer.SetRawSizes(nbPnts, 3*nbPnts, nbSegs, 3*nbSegs, nbPols, 6*nbPols)) {
1130  buffer.SetSectionsValid(TBuffer3D::kRawSizes);
1131  }
1132  }
1133 
1134  // TODO: Can we push this as common down to TGeoShape?
1135  if ((reqSections & TBuffer3D::kRaw) && buffer.SectionsValid(TBuffer3D::kRawSizes)) {
1136  SetPoints(buffer.fPnts);
1137  if (!buffer.fLocalFrame) {
1138  TransformPoints(buffer.fPnts, buffer.NbPnts());
1139  }
1140 
1141  SetSegsAndPols(buffer);
1142  buffer.SetSectionsValid(TBuffer3D::kRaw);
1143  }
1144 
1145  return buffer;
1146 }
1147 
1148 ////////////////////////////////////////////////////////////////////////////////
1149 /// Check the inside status for each of the points in the array.
1150 /// Input: Array of point coordinates + vector size
1151 /// Output: Array of Booleans for the inside of each point
1152 
1153 void TGeoCone::Contains_v(const Double_t *points, Bool_t *inside, Int_t vecsize) const
1154 {
1155  for (Int_t i=0; i<vecsize; i++) inside[i] = Contains(&points[3*i]);
1156 }
1157 
1158 ////////////////////////////////////////////////////////////////////////////////
1159 /// Compute the normal for an array o points so that norm.dot.dir is positive
1160 /// Input: Arrays of point coordinates and directions + vector size
1161 /// Output: Array of normal directions
1162 
1163 void TGeoCone::ComputeNormal_v(const Double_t *points, const Double_t *dirs, Double_t *norms, Int_t vecsize)
1164 {
1165  for (Int_t i=0; i<vecsize; i++) ComputeNormal(&points[3*i], &dirs[3*i], &norms[3*i]);
1166 }
1167 
1168 ////////////////////////////////////////////////////////////////////////////////
1169 /// Compute distance from array of input points having directions specisied by dirs. Store output in dists
1170 
1171 void TGeoCone::DistFromInside_v(const Double_t *points, const Double_t *dirs, Double_t *dists, Int_t vecsize, Double_t* step) const
1172 {
1173  for (Int_t i=0; i<vecsize; i++) dists[i] = DistFromInside(&points[3*i], &dirs[3*i], 3, step[i]);
1174 }
1175 
1176 ////////////////////////////////////////////////////////////////////////////////
1177 /// Compute distance from array of input points having directions specisied by dirs. Store output in dists
1178 
1179 void TGeoCone::DistFromOutside_v(const Double_t *points, const Double_t *dirs, Double_t *dists, Int_t vecsize, Double_t* step) const
1180 {
1181  for (Int_t i=0; i<vecsize; i++) dists[i] = DistFromOutside(&points[3*i], &dirs[3*i], 3, step[i]);
1182 }
1183 
1184 ////////////////////////////////////////////////////////////////////////////////
1185 /// Compute safe distance from each of the points in the input array.
1186 /// Input: Array of point coordinates, array of statuses for these points, size of the arrays
1187 /// Output: Safety values
1188 
1189 void TGeoCone::Safety_v(const Double_t *points, const Bool_t *inside, Double_t *safe, Int_t vecsize) const
1190 {
1191  for (Int_t i=0; i<vecsize; i++) safe[i] = Safety(&points[3*i], inside[i]);
1192 }
1193 
1195 
1196 ////////////////////////////////////////////////////////////////////////////////
1197 /// Default constructor
1198 
1200  :TGeoCone(),
1201  fPhi1(0.), fPhi2(0.), fS1(0.), fC1(0.), fS2(0.), fC2(0.), fSm(0.), fCm(0.), fCdfi(0.)
1202 {
1203  SetShapeBit(TGeoShape::kGeoConeSeg);
1204  fPhi1 = fPhi2 = 0.0;
1205 }
1206 
1207 ////////////////////////////////////////////////////////////////////////////////
1208 
1210  Double_t rmin2, Double_t rmax2, Double_t phi1, Double_t phi2)
1211  :TGeoCone(dz, rmin1, rmax1, rmin2, rmax2),
1212  fPhi1(0.), fPhi2(0.), fS1(0.), fC1(0.), fS2(0.), fC2(0.), fSm(0.), fCm(0.), fCdfi(0.)
1213 
1214 {
1215 // Default constructor specifying minimum and maximum radius
1217  SetConsDimensions(dz, rmin1, rmax1, rmin2, rmax2, phi1, phi2);
1218  ComputeBBox();
1219 }
1220 
1221 ////////////////////////////////////////////////////////////////////////////////
1222 /// Default constructor specifying minimum and maximum radius
1223 
1225  Double_t rmin2, Double_t rmax2, Double_t phi1, Double_t phi2)
1226  :TGeoCone(name, dz, rmin1, rmax1, rmin2, rmax2),
1227  fPhi1(0.), fPhi2(0.), fS1(0.), fC1(0.), fS2(0.), fC2(0.), fSm(0.), fCm(0.), fCdfi(0.)
1228 {
1230  SetConsDimensions(dz, rmin1, rmax1, rmin2, rmax2, phi1, phi2);
1231  ComputeBBox();
1232 }
1233 
1234 ////////////////////////////////////////////////////////////////////////////////
1235 /// Default constructor specifying minimum and maximum radius
1236 /// param[0] = dz
1237 /// param[1] = Rmin1
1238 /// param[2] = Rmax1
1239 /// param[3] = Rmin2
1240 /// param[4] = Rmax2
1241 /// param[5] = phi1
1242 /// param[6] = phi2
1243 
1245  :TGeoCone(0,0,0,0,0),
1246  fPhi1(0.), fPhi2(0.), fS1(0.), fC1(0.), fS2(0.), fC2(0.), fSm(0.), fCm(0.), fCdfi(0.)
1247 {
1249  SetDimensions(param);
1250  ComputeBBox();
1251 }
1252 
1253 ////////////////////////////////////////////////////////////////////////////////
1254 /// destructor
1255 
1257 {
1258 }
1259 
1260 ////////////////////////////////////////////////////////////////////////////////
1261 /// Function called after streaming an object of this class.
1262 
1264 {
1265  InitTrigonometry();
1266 }
1267 
1268 ////////////////////////////////////////////////////////////////////////////////
1269 /// Init frequently used trigonometric values
1270 
1272 {
1273  Double_t phi1 = fPhi1*TMath::DegToRad();
1274  Double_t phi2 = fPhi2*TMath::DegToRad();
1275  fC1 = TMath::Cos(phi1);
1276  fS1 = TMath::Sin(phi1);
1277  fC2 = TMath::Cos(phi2);
1278  fS2 = TMath::Sin(phi2);
1279  Double_t fio = 0.5*(phi1+phi2);
1280  fCm = TMath::Cos(fio);
1281  fSm = TMath::Sin(fio);
1282  Double_t dfi = 0.5*(phi2-phi1);
1283  fCdfi = TMath::Cos(dfi);
1284 }
1285 
1286 ////////////////////////////////////////////////////////////////////////////////
1287 /// Computes capacity of the shape in [length^3]
1288 
1290 {
1292 }
1293 
1294 ////////////////////////////////////////////////////////////////////////////////
1295 /// Computes capacity of the shape in [length^3]
1296 
1298 {
1299  Double_t capacity = (TMath::Abs(phi2-phi1)*TMath::DegToRad()*dz/3.)*
1300  (rmax1*rmax1+rmax2*rmax2+rmax1*rmax2-
1301  rmin1*rmin1-rmin2*rmin2-rmin1*rmin2);
1302  return capacity;
1303 }
1304 
1305 ////////////////////////////////////////////////////////////////////////////////
1306 /// compute bounding box of the tube segment
1307 
1309 {
1310  Double_t rmin, rmax;
1311  rmin = TMath::Min(fRmin1, fRmin2);
1312  rmax = TMath::Max(fRmax1, fRmax2);
1313 
1314  Double_t xc[4];
1315  Double_t yc[4];
1316  xc[0] = rmax*fC1;
1317  yc[0] = rmax*fS1;
1318  xc[1] = rmax*fC2;
1319  yc[1] = rmax*fS2;
1320  xc[2] = rmin*fC1;
1321  yc[2] = rmin*fS1;
1322  xc[3] = rmin*fC2;
1323  yc[3] = rmin*fS2;
1324 
1325  Double_t xmin = xc[TMath::LocMin(4, &xc[0])];
1326  Double_t xmax = xc[TMath::LocMax(4, &xc[0])];
1327  Double_t ymin = yc[TMath::LocMin(4, &yc[0])];
1328  Double_t ymax = yc[TMath::LocMax(4, &yc[0])];
1329 
1330  Double_t dp = fPhi2-fPhi1;
1331  Double_t ddp = -fPhi1;
1332  if (ddp<0) ddp+= 360;
1333  if (ddp<=dp) xmax = rmax;
1334  ddp = 90-fPhi1;
1335  if (ddp<0) ddp+= 360;
1336  if (ddp<=dp) ymax = rmax;
1337  ddp = 180-fPhi1;
1338  if (ddp<0) ddp+= 360;
1339  if (ddp<=dp) xmin = -rmax;
1340  ddp = 270-fPhi1;
1341  if (ddp<0) ddp+= 360;
1342  if (ddp<=dp) ymin = -rmax;
1343  fOrigin[0] = (xmax+xmin)/2;
1344  fOrigin[1] = (ymax+ymin)/2;
1345  fOrigin[2] = 0;
1346  fDX = (xmax-xmin)/2;
1347  fDY = (ymax-ymin)/2;
1348  fDZ = fDz;
1349 }
1350 
1351 ////////////////////////////////////////////////////////////////////////////////
1352 /// Compute normal to closest surface from POINT.
1353 
1355 {
1356  Double_t saf[3];
1357  Double_t ro1 = 0.5*(fRmin1+fRmin2);
1358  Double_t tg1 = 0.5*(fRmin2-fRmin1)/fDz;
1359  Double_t cr1 = 1./TMath::Sqrt(1.+tg1*tg1);
1360  Double_t ro2 = 0.5*(fRmax1+fRmax2);
1361  Double_t tg2 = 0.5*(fRmax2-fRmax1)/fDz;
1362  Double_t cr2 = 1./TMath::Sqrt(1.+tg2*tg2);
1363 
1364  Double_t r=TMath::Sqrt(point[0]*point[0]+point[1]*point[1]);
1365  Double_t rin = tg1*point[2]+ro1;
1366  Double_t rout = tg2*point[2]+ro2;
1367  saf[0] = TMath::Abs(fDz-TMath::Abs(point[2]));
1368  saf[1] = (ro1>0)?(TMath::Abs((r-rin)*cr1)):TGeoShape::Big();
1369  saf[2] = TMath::Abs((rout-r)*cr2);
1370  Int_t i = TMath::LocMin(3,saf);
1371  if (((fPhi2-fPhi1)<360.) && TGeoShape::IsCloseToPhi(saf[i], point,fC1,fS1,fC2,fS2)) {
1372  TGeoShape::NormalPhi(point,dir,norm,fC1,fS1,fC2,fS2);
1373  return;
1374  }
1375  if (i==0) {
1376  norm[0] = norm[1] = 0.;
1377  norm[2] = TMath::Sign(1.,dir[2]);
1378  return;
1379  }
1380 
1381  Double_t phi = TMath::ATan2(point[1],point[0]);
1382  Double_t cphi = TMath::Cos(phi);
1383  Double_t sphi = TMath::Sin(phi);
1384 
1385  if (i==1) {
1386  norm[0] = cr1*cphi;
1387  norm[1] = cr1*sphi;
1388  norm[2] = -tg1*cr1;
1389  } else {
1390  norm[0] = cr2*cphi;
1391  norm[1] = cr2*sphi;
1392  norm[2] = -tg2*cr2;
1393  }
1394 
1395  if (norm[0]*dir[0]+norm[1]*dir[1]+norm[2]*dir[2]<0) {
1396  norm[0] = -norm[0];
1397  norm[1] = -norm[1];
1398  norm[2] = -norm[2];
1399  }
1400 }
1401 
1402 ////////////////////////////////////////////////////////////////////////////////
1403 /// Compute normal to closest surface from POINT.
1404 
1406  Double_t dz, Double_t rmin1, Double_t rmax1, Double_t rmin2, Double_t rmax2,
1408 {
1409  Double_t saf[2];
1410  Double_t ro1 = 0.5*(rmin1+rmin2);
1411  Double_t tg1 = 0.5*(rmin2-rmin1)/dz;
1412  Double_t cr1 = 1./TMath::Sqrt(1.+tg1*tg1);
1413  Double_t ro2 = 0.5*(rmax1+rmax2);
1414  Double_t tg2 = 0.5*(rmax2-rmax1)/dz;
1415  Double_t cr2 = 1./TMath::Sqrt(1.+tg2*tg2);
1416 
1417  Double_t r=TMath::Sqrt(point[0]*point[0]+point[1]*point[1]);
1418  Double_t rin = tg1*point[2]+ro1;
1419  Double_t rout = tg2*point[2]+ro2;
1420  saf[0] = (ro1>0)?(TMath::Abs((r-rin)*cr1)):TGeoShape::Big();
1421  saf[1] = TMath::Abs((rout-r)*cr2);
1422  Int_t i = TMath::LocMin(2,saf);
1423  if (TGeoShape::IsCloseToPhi(saf[i], point,c1,s1,c2,s2)) {
1424  TGeoShape::NormalPhi(point,dir,norm,c1,s1,c2,s2);
1425  return;
1426  }
1427 
1428  Double_t phi = TMath::ATan2(point[1],point[0]);
1429  Double_t cphi = TMath::Cos(phi);
1430  Double_t sphi = TMath::Sin(phi);
1431 
1432  if (i==0) {
1433  norm[0] = cr1*cphi;
1434  norm[1] = cr1*sphi;
1435  norm[2] = -tg1*cr1;
1436  } else {
1437  norm[0] = cr2*cphi;
1438  norm[1] = cr2*sphi;
1439  norm[2] = -tg2*cr2;
1440  }
1441 
1442  if (norm[0]*dir[0]+norm[1]*dir[1]+norm[2]*dir[2]<0) {
1443  norm[0] = -norm[0];
1444  norm[1] = -norm[1];
1445  norm[2] = -norm[2];
1446  }
1447 }
1448 
1449 ////////////////////////////////////////////////////////////////////////////////
1450 /// test if point is inside this sphere
1451 
1453 {
1454  if (!TGeoCone::Contains(point)) return kFALSE;
1455  Double_t dphi = fPhi2 - fPhi1;
1456  if (dphi >= 360.) return kTRUE;
1457  Double_t phi = TMath::ATan2(point[1], point[0]) * TMath::RadToDeg();
1458  if (phi < 0 ) phi+=360.;
1459  Double_t ddp = phi-fPhi1;
1460  if (ddp < 0) ddp+=360.;
1461 // if (ddp > 360) ddp-=360;
1462  if (ddp > dphi) return kFALSE;
1463  return kTRUE;
1464 }
1465 
1466 ////////////////////////////////////////////////////////////////////////////////
1467 /// Static method to compute distance to a conical surface with :
1468 /// - r1, z1 - radius and Z position of lower base
1469 /// - r2, z2 - radius and Z position of upper base
1470 /// - phi1, phi2 - phi limits
1471 
1473 {
1474  Double_t dz = z2-z1;
1475  if (dz<=0) {
1476  return TGeoShape::Big();
1477  }
1478 
1479  Double_t dphi = phi2 - phi1;
1480  Bool_t hasphi = kTRUE;
1481  if (dphi >= 360.) hasphi=kFALSE;
1482  if (dphi < 0) dphi+=360.;
1483 // printf("phi1=%f phi2=%f dphi=%f\n", phi1, phi2, dphi);
1484 
1485  Double_t ro0 = 0.5*(r1+r2);
1486  Double_t fz = (r2-r1)/dz;
1487  Double_t r0sq = point[0]*point[0] + point[1]*point[1];
1488  Double_t rc = ro0 + fz*(point[2]-0.5*(z1+z2));
1489 
1490  Double_t a = dir[0]*dir[0] + dir[1]*dir[1] - fz*fz*dir[2]*dir[2];
1491  Double_t b = point[0]*dir[0] + point[1]*dir[1] - fz*rc*dir[2];
1492  Double_t c = r0sq - rc*rc;
1493 
1494  if (a==0) return TGeoShape::Big();
1495  a = 1./a;
1496  b *= a;
1497  c *= a;
1498  Double_t delta = b*b - c;
1499  if (delta<0) return TGeoShape::Big();
1500  delta = TMath::Sqrt(delta);
1501 
1502  Double_t snxt = -b-delta;
1503  Double_t ptnew[3];
1504  Double_t ddp, phi;
1505  if (snxt>0) {
1506  // check Z range
1507  ptnew[2] = point[2] + snxt*dir[2];
1508  if (((ptnew[2]-z1)*(ptnew[2]-z2)) < 0) {
1509  // check phi range
1510  if (!hasphi) return snxt;
1511  ptnew[0] = point[0] + snxt*dir[0];
1512  ptnew[1] = point[1] + snxt*dir[1];
1513  phi = TMath::ATan2(ptnew[1], ptnew[0]) * TMath::RadToDeg();
1514  if (phi < 0 ) phi+=360.;
1515  ddp = phi-phi1;
1516  if (ddp < 0) ddp+=360.;
1517  // printf("snxt1=%f phi=%f ddp=%f\n", snxt, phi, ddp);
1518  if (ddp<=dphi) return snxt;
1519  }
1520  }
1521  snxt = -b+delta;
1522  if (snxt>0) {
1523  // check Z range
1524  ptnew[2] = point[2] + snxt*dir[2];
1525  if (((ptnew[2]-z1)*(ptnew[2]-z2)) < 0) {
1526  // check phi range
1527  if (!hasphi) return snxt;
1528  ptnew[0] = point[0] + snxt*dir[0];
1529  ptnew[1] = point[1] + snxt*dir[1];
1530  phi = TMath::ATan2(ptnew[1], ptnew[0]) * TMath::RadToDeg();
1531  if (phi < 0 ) phi+=360.;
1532  ddp = phi-phi1;
1533  if (ddp < 0) ddp+=360.;
1534  // printf("snxt2=%f phi=%f ddp=%f\n", snxt, phi, ddp);
1535  if (ddp<=dphi) return snxt;
1536  }
1537  }
1538  return TGeoShape::Big();
1539 }
1540 
1541 ////////////////////////////////////////////////////////////////////////////////
1542 /// compute distance from inside point to surface of the tube segment
1543 
1545  Double_t rmin1, Double_t rmax1, Double_t rmin2, Double_t rmax2,
1547 {
1548  if (dz<=0) return TGeoShape::Big();
1549  // Do Z
1550  Double_t scone = TGeoCone::DistFromInsideS(point,dir,dz,rmin1,rmax1,rmin2,rmax2);
1551  if (scone<=0) return 0.0;
1552  Double_t sfmin = TGeoShape::Big();
1553  Double_t rsq = point[0]*point[0]+point[1]*point[1];
1554  Double_t r = TMath::Sqrt(rsq);
1555  Double_t cpsi=point[0]*cm+point[1]*sm;
1556  if (cpsi>r*cdfi+TGeoShape::Tolerance()) {
1557  sfmin = TGeoShape::DistToPhiMin(point, dir, s1, c1, s2, c2, sm, cm);
1558  return TMath::Min(scone,sfmin);
1559  }
1560  // Point on the phi boundary or outside
1561  // which one: phi1 or phi2
1562  Double_t ddotn, xi, yi;
1563  if (TMath::Abs(point[1]-s1*r) < TMath::Abs(point[1]-s2*r)) {
1564  ddotn = s1*dir[0]-c1*dir[1];
1565  if (ddotn>=0) return 0.0;
1566  ddotn = -s2*dir[0]+c2*dir[1];
1567  if (ddotn<=0) return scone;
1568  sfmin = s2*point[0]-c2*point[1];
1569  if (sfmin<=0) return scone;
1570  sfmin /= ddotn;
1571  if (sfmin >= scone) return scone;
1572  xi = point[0]+sfmin*dir[0];
1573  yi = point[1]+sfmin*dir[1];
1574  if (yi*cm-xi*sm<0) return scone;
1575  return sfmin;
1576  }
1577  ddotn = -s2*dir[0]+c2*dir[1];
1578  if (ddotn>=0) return 0.0;
1579  ddotn = s1*dir[0]-c1*dir[1];
1580  if (ddotn<=0) return scone;
1581  sfmin = -s1*point[0]+c1*point[1];
1582  if (sfmin<=0) return scone;
1583  sfmin /= ddotn;
1584  if (sfmin >= scone) return scone;
1585  xi = point[0]+sfmin*dir[0];
1586  yi = point[1]+sfmin*dir[1];
1587  if (yi*cm-xi*sm>0) return scone;
1588  return sfmin;
1589 }
1590 
1591 ////////////////////////////////////////////////////////////////////////////////
1592 /// compute distance from inside point to surface of the tube segment
1593 
1594 Double_t TGeoConeSeg::DistFromInside(const Double_t *point, const Double_t *dir, Int_t iact, Double_t step, Double_t *safe) const
1595 {
1596  if (iact<3 && safe) {
1598  if (iact==0) return TGeoShape::Big();
1599  if ((iact==1) && (*safe>step)) return TGeoShape::Big();
1600  }
1601  if ((fPhi2-fPhi1)>=360.) return TGeoCone::DistFromInsideS(point,dir,fDz,fRmin1,fRmax1,fRmin2,fRmax2);
1602 
1603  // compute distance to surface
1605 }
1606 
1607 ////////////////////////////////////////////////////////////////////////////////
1608 /// compute distance from outside point to surface of arbitrary tube
1609 
1611  Double_t rmin1, Double_t rmax1, Double_t rmin2, Double_t rmax2,
1613 {
1614  if (dz<=0) return TGeoShape::Big();
1615  Double_t r2, cpsi;
1616  // check Z planes
1617  Double_t xi, yi, zi;
1618  Double_t b,delta;
1619  zi = dz - TMath::Abs(point[2]);
1620  Double_t rin,rout;
1621  Double_t s = TGeoShape::Big();
1622  Double_t snxt=TGeoShape::Big();
1623  Bool_t in = kFALSE;
1624  Bool_t inz = (zi<0)?kFALSE:kTRUE;
1625  if (!inz) {
1626  if (point[2]*dir[2]>=0) return TGeoShape::Big();
1627  s = -zi/TMath::Abs(dir[2]);
1628  xi = point[0]+s*dir[0];
1629  yi = point[1]+s*dir[1];
1630  r2=xi*xi+yi*yi;
1631  if (dir[2]>0) {
1632  rin = rmin1;
1633  rout = rmax1;
1634  } else {
1635  rin = rmin2;
1636  rout = rmax2;
1637  }
1638  if ((rin*rin<=r2) && (r2<=rout*rout)) {
1639  cpsi=xi*cm+yi*sm;
1640  if (cpsi>=(cdfi*TMath::Sqrt(r2))) return s;
1641  }
1642  }
1643  Double_t zinv = 1./dz;
1644  Double_t rsq = point[0]*point[0]+point[1]*point[1];
1645  Double_t r = TMath::Sqrt(rsq);
1646  Double_t ro1=0.5*(rmin1+rmin2);
1647  Bool_t hasrmin = (ro1>0)?kTRUE:kFALSE;
1648  Double_t tg1 = 0.0;
1649  Bool_t inrmin = kFALSE;
1650  rin = 0.0;
1651  if (hasrmin) {
1652  tg1=0.5*(rmin2-rmin1)*zinv;
1653  rin = ro1+tg1*point[2];
1654  if (rsq > rin*(rin-TGeoShape::Tolerance())) inrmin=kTRUE;
1655  } else {
1656  inrmin = kTRUE;
1657  }
1658  Double_t ro2=0.5*(rmax1+rmax2);
1659  Double_t tg2=0.5*(rmax2-rmax1)*zinv;
1660  rout = ro2+tg2*point[2];
1661  Bool_t inrmax = kFALSE;
1662  if (r < rout+TGeoShape::Tolerance()) inrmax = kTRUE;
1663  Bool_t inphi = kFALSE;
1664  cpsi=point[0]*cm+point[1]*sm;
1665  if (cpsi>r*cdfi-TGeoShape::Tolerance()) inphi = kTRUE;
1666  in = inz & inrmin & inrmax & inphi;
1667  // If inside, we are most likely on a boundary within machine precision.
1668  if (in) {
1669  Double_t safphi = (cpsi-r*cdfi)*TMath::Sqrt(1.-cdfi*cdfi);
1670  Double_t safrmin = (hasrmin)?TMath::Abs(r-rin):(TGeoShape::Big());
1671  Double_t safrmax = TMath::Abs(r-rout);
1672  // check if on Z boundaries
1673  if (zi<safrmax && zi<safrmin && zi<safphi) {
1674  if (point[2]*dir[2]<0) return 0.0;
1675  return TGeoShape::Big();
1676  }
1677  // check if on Rmax boundary
1678  if (safrmax<safrmin && safrmax<safphi) {
1679  Double_t ddotn = point[0]*dir[0]+point[1]*dir[1]-tg2*dir[2]*r;
1680  if (ddotn<=0) return 0.0;
1681  return TGeoShape::Big();
1682  }
1683  // check if on phi boundary
1684  if (safphi<safrmin) {
1685  // We may cross again a phi of rmin boundary
1686  // check first if we are on phi1 or phi2
1687  Double_t un;
1688  if (TMath::Abs(point[1]-s1*r) < TMath::Abs(point[1]-s2*r)) {
1689  un = dir[0]*s1-dir[1]*c1;
1690  if (un < 0) return 0.0;
1691  if (cdfi>=0) return TGeoShape::Big();
1692  un = -dir[0]*s2+dir[1]*c2;
1693  if (un<0) {
1694  s = -point[0]*s2+point[1]*c2;
1695  if (s>0) {
1696  s /= (-un);
1697  zi = point[2]+s*dir[2];
1698  if (TMath::Abs(zi)<=dz) {
1699  xi = point[0]+s*dir[0];
1700  yi = point[1]+s*dir[1];
1701  if ((yi*cm-xi*sm)>0) {
1702  r2=xi*xi+yi*yi;
1703  rin = ro1+tg1*zi;
1704  rout = ro2+tg2*zi;
1705  if ((rin*rin<=r2) && (rout*rout>=r2)) return s;
1706  }
1707  }
1708  }
1709  }
1710  } else {
1711  un = -dir[0]*s2+dir[1]*c2;
1712  if (un < 0) return 0.0;
1713  if (cdfi>=0) return TGeoShape::Big();
1714  un = dir[0]*s1-dir[1]*c1;
1715  if (un<0) {
1716  s = point[0]*s1-point[1]*c1;
1717  if (s>0) {
1718  s /= (-un);
1719  zi = point[2]+s*dir[2];
1720  if (TMath::Abs(zi)<=dz) {
1721  xi = point[0]+s*dir[0];
1722  yi = point[1]+s*dir[1];
1723  if ((yi*cm-xi*sm)<0) {
1724  r2=xi*xi+yi*yi;
1725  rin = ro1+tg1*zi;
1726  rout = ro2+tg2*zi;
1727  if ((rin*rin<=r2) && (rout*rout>=r2)) return s;
1728  }
1729  }
1730  }
1731  }
1732  }
1733  // We may also cross rmin, second solution coming from outside
1734  Double_t ddotn = point[0]*dir[0]+point[1]*dir[1]-tg1*dir[2]*r;
1735  if (ddotn>=0) return TGeoShape::Big();
1736  if (cdfi>=0) return TGeoShape::Big();
1737  TGeoCone::DistToCone(point, dir, dz, rmin1, rmin2, b, delta);
1738  if (delta<0) return TGeoShape::Big();
1739  snxt = -b-delta;
1740  if (snxt<0) return TGeoShape::Big();
1741  snxt = -b+delta;
1742  zi = point[2]+snxt*dir[2];
1743  if (TMath::Abs(zi)>dz) return TGeoShape::Big();
1744  xi = point[0]+snxt*dir[0];
1745  yi = point[1]+snxt*dir[1];
1746  r2=xi*xi+yi*yi;
1747  cpsi=xi*cm+yi*sm;
1748  if (cpsi>=(cdfi*TMath::Sqrt(r2))) return snxt;
1749  return TGeoShape::Big();
1750  }
1751  // We are on rmin boundary: we may cross again rmin or a phi facette
1752  Double_t ddotn = point[0]*dir[0]+point[1]*dir[1]-tg1*dir[2]*r;
1753  if (ddotn>=0) return 0.0;
1754  TGeoCone::DistToCone(point, dir, dz, rmin1, rmin2, b, delta);
1755  if (delta<0) return 0.0;
1756  snxt = -b+delta;
1757  if (snxt<0) return TGeoShape::Big();
1758  if (TMath::Abs(-b-delta)>snxt) return TGeoShape::Big();
1759  zi = point[2]+snxt*dir[2];
1760  if (TMath::Abs(zi)>dz) return TGeoShape::Big();
1761  // OK, we cross rmin at snxt - check if within phi range
1762  xi = point[0]+snxt*dir[0];
1763  yi = point[1]+snxt*dir[1];
1764  r2=xi*xi+yi*yi;
1765  cpsi=xi*cm+yi*sm;
1766  if (cpsi>=(cdfi*TMath::Sqrt(r2))) return snxt;
1767  // we cross rmin in the phi gap - we may cross a phi facette
1768  if (cdfi>=0) return TGeoShape::Big();
1769  Double_t un=-dir[0]*s1+dir[1]*c1;
1770  if (un > 0) {
1771  s=point[0]*s1-point[1]*c1;
1772  if (s>=0) {
1773  s /= un;
1774  zi=point[2]+s*dir[2];
1775  if (TMath::Abs(zi)<=dz) {
1776  xi=point[0]+s*dir[0];
1777  yi=point[1]+s*dir[1];
1778  if ((yi*cm-xi*sm)<=0) {
1779  r2=xi*xi+yi*yi;
1780  rin = ro1+tg1*zi;
1781  rout = ro2+tg2*zi;
1782  if ((rin*rin<=r2) && (rout*rout>=r2)) return s;
1783  }
1784  }
1785  }
1786  }
1787  un=dir[0]*s2-dir[1]*c2;
1788  if (un > 0) {
1789  s=(point[1]*c2-point[0]*s2)/un;
1790  if (s>=0) {
1791  zi=point[2]+s*dir[2];
1792  if (TMath::Abs(zi)<=dz) {
1793  xi=point[0]+s*dir[0];
1794  yi=point[1]+s*dir[1];
1795  if ((yi*cm-xi*sm)>=0) {
1796  r2=xi*xi+yi*yi;
1797  rin = ro1+tg1*zi;
1798  rout = ro2+tg2*zi;
1799  if ((rin*rin<=r2) && (rout*rout>=r2)) return s;
1800  }
1801  }
1802  }
1803  }
1804  return TGeoShape::Big();
1805  }
1806 
1807  // The point is really outside
1808  Double_t sr1 = TGeoShape::Big();
1809  if (!inrmax) {
1810  // check crossing with outer cone
1811  TGeoCone::DistToCone(point, dir, dz, rmax1, rmax2, b, delta);
1812  if (delta>=0) {
1813  s = -b-delta;
1814  if (s>0) {
1815  zi=point[2]+s*dir[2];
1816  if (TMath::Abs(zi)<=dz) {
1817  xi=point[0]+s*dir[0];
1818  yi=point[1]+s*dir[1];
1819  r2=xi*xi+yi*yi;
1820  cpsi=xi*cm+yi*sm;
1821  if (cpsi>=(cdfi*TMath::Sqrt(r2))) return s; // rmax crossing
1822  }
1823  }
1824  s = -b+delta;
1825  if (s>0) {
1826  zi=point[2]+s*dir[2];
1827  if (TMath::Abs(zi)<=dz) {
1828  xi=point[0]+s*dir[0];
1829  yi=point[1]+s*dir[1];
1830  r2=xi*xi+yi*yi;
1831  cpsi=xi*cm+yi*sm;
1832  if (cpsi>=(cdfi*TMath::Sqrt(r2))) sr1=s;
1833  }
1834  }
1835  }
1836  }
1837  // check crossing with inner cone
1838  Double_t sr2 = TGeoShape::Big();
1839  TGeoCone::DistToCone(point, dir, dz, rmin1, rmin2, b, delta);
1840  if (delta>=0) {
1841  s = -b-delta;
1842  if (s>0) {
1843  zi=point[2]+s*dir[2];
1844  if (TMath::Abs(zi)<=dz) {
1845  xi=point[0]+s*dir[0];
1846  yi=point[1]+s*dir[1];
1847  r2=xi*xi+yi*yi;
1848  cpsi=xi*cm+yi*sm;
1849  if (cpsi>=(cdfi*TMath::Sqrt(r2))) sr2=s;
1850  }
1851  }
1852  if (sr2>1E10) {
1853  s = -b+delta;
1854  if (s>0) {
1855  zi=point[2]+s*dir[2];
1856  if (TMath::Abs(zi)<=dz) {
1857  xi=point[0]+s*dir[0];
1858  yi=point[1]+s*dir[1];
1859  r2=xi*xi+yi*yi;
1860  cpsi=xi*cm+yi*sm;
1861  if (cpsi>=(cdfi*TMath::Sqrt(r2))) sr2=s;
1862  }
1863  }
1864  }
1865  }
1866  snxt = TMath::Min(sr1,sr2);
1867  // Check phi crossing
1868  s = TGeoShape::DistToPhiMin(point,dir,s1,c1,s2,c2,sm,cm,kFALSE);
1869  if (s>snxt) return snxt;
1870  zi=point[2]+s*dir[2];
1871  if (TMath::Abs(zi)>dz) return snxt;
1872  xi=point[0]+s*dir[0];
1873  yi=point[1]+s*dir[1];
1874  r2=xi*xi+yi*yi;
1875  rout = ro2+tg2*zi;
1876  if (r2>rout*rout) return snxt;
1877  rin = ro1+tg1*zi;
1878  if (r2>=rin*rin) return s; // phi crossing
1879  return snxt;
1880 }
1881 
1882 ////////////////////////////////////////////////////////////////////////////////
1883 /// compute distance from outside point to surface of the tube
1884 /// compute safe radius
1885 
1886 Double_t TGeoConeSeg::DistFromOutside(const Double_t *point, const Double_t *dir, Int_t iact, Double_t step, Double_t *safe) const
1887 {
1888  if (iact<3 && safe) {
1889  *safe = Safety(point, kFALSE);
1890  if (iact==0) return TGeoShape::Big();
1891  if ((iact==1) && (*safe>step)) return TGeoShape::Big();
1892  }
1893 // Check if the bounding box is crossed within the requested distance
1894  Double_t sdist = TGeoBBox::DistFromOutside(point,dir, fDX, fDY, fDZ, fOrigin, step);
1895  if (sdist>=step) return TGeoShape::Big();
1896  if ((fPhi2-fPhi1)>=360.) return TGeoCone::DistFromOutsideS(point,dir,fDz,fRmin1,fRmax1,fRmin2,fRmax2);
1898 }
1899 
1900 ////////////////////////////////////////////////////////////////////////////////
1901 /// compute closest distance from point px,py to each corner
1902 
1904 {
1906  const Int_t numPoints = 4*n;
1907  return ShapeDistancetoPrimitive(numPoints, px, py);
1908 }
1909 
1910 ////////////////////////////////////////////////////////////////////////////////
1911 ///--- Divide this cone segment shape belonging to volume "voldiv" into ndiv volumes
1912 /// called divname, from start position with the given step. Returns pointer
1913 /// to created division cell volume in case of Z divisions. For Z division
1914 /// creates all volumes with different shapes and returns pointer to volume that
1915 /// was divided. In case a wrong division axis is supplied, returns pointer to
1916 /// volume that was divided.
1917 
1918 TGeoVolume *TGeoConeSeg::Divide(TGeoVolume *voldiv, const char *divname, Int_t iaxis, Int_t ndiv,
1919  Double_t start, Double_t step)
1920 {
1921  TGeoShape *shape; //--- shape to be created
1922  TGeoVolume *vol; //--- division volume to be created
1923  TGeoVolumeMulti *vmulti; //--- generic divided volume
1924  TGeoPatternFinder *finder; //--- finder to be attached
1925  TString opt = ""; //--- option to be attached
1926  Double_t dphi;
1927  Int_t id;
1928  Double_t end = start+ndiv*step;
1929  switch (iaxis) {
1930  case 1: //--- R division
1931  Error("Divide","division of a cone segment on R not implemented");
1932  return 0;
1933  case 2: //--- Phi division
1934  dphi = fPhi2-fPhi1;
1935  if (dphi<0) dphi+=360.;
1936  finder = new TGeoPatternCylPhi(voldiv, ndiv, start, end);
1937  voldiv->SetFinder(finder);
1938  finder->SetDivIndex(voldiv->GetNdaughters());
1939  shape = new TGeoConeSeg(fDz, fRmin1, fRmax1, fRmin2, fRmax2, -step/2, step/2);
1940  vol = new TGeoVolume(divname, shape, voldiv->GetMedium());
1941  vmulti = gGeoManager->MakeVolumeMulti(divname, voldiv->GetMedium());
1942  vmulti->AddVolume(vol);
1943  opt = "Phi";
1944  for (id=0; id<ndiv; id++) {
1945  voldiv->AddNodeOffset(vol, id, start+id*step+step/2, opt.Data());
1946  ((TGeoNodeOffset*)voldiv->GetNodes()->At(voldiv->GetNdaughters()-1))->SetFinder(finder);
1947  }
1948  return vmulti;
1949  case 3: //--- Z division
1950  finder = new TGeoPatternZ(voldiv, ndiv, start, end);
1951  vmulti = gGeoManager->MakeVolumeMulti(divname, voldiv->GetMedium());
1952  voldiv->SetFinder(finder);
1953  finder->SetDivIndex(voldiv->GetNdaughters());
1954  for (id=0; id<ndiv; id++) {
1955  Double_t z1 = start+id*step;
1956  Double_t z2 = start+(id+1)*step;
1957  Double_t rmin1n = 0.5*(fRmin1*(fDz-z1)+fRmin2*(fDz+z1))/fDz;
1958  Double_t rmax1n = 0.5*(fRmax1*(fDz-z1)+fRmax2*(fDz+z1))/fDz;
1959  Double_t rmin2n = 0.5*(fRmin1*(fDz-z2)+fRmin2*(fDz+z2))/fDz;
1960  Double_t rmax2n = 0.5*(fRmax1*(fDz-z2)+fRmax2*(fDz+z2))/fDz;
1961  shape = new TGeoConeSeg(step/2, rmin1n, rmax1n, rmin2n, rmax2n, fPhi1, fPhi2);
1962  vol = new TGeoVolume(divname, shape, voldiv->GetMedium());
1963  vmulti->AddVolume(vol);
1964  opt = "Z";
1965  voldiv->AddNodeOffset(vol, id, start+id*step+step/2, opt.Data());
1966  ((TGeoNodeOffset*)voldiv->GetNodes()->At(voldiv->GetNdaughters()-1))->SetFinder(finder);
1967  }
1968  return vmulti;
1969  default:
1970  Error("Divide", "Wrong axis type for division");
1971  return 0;
1972  }
1973 }
1974 
1975 ////////////////////////////////////////////////////////////////////////////////
1976 /// Get range of shape for a given axis.
1977 
1979 {
1980  xlo = 0;
1981  xhi = 0;
1982  Double_t dx = 0;
1983  switch (iaxis) {
1984  case 2:
1985  xlo = fPhi1;
1986  xhi = fPhi2;
1987  dx = xhi-xlo;
1988  return dx;
1989  case 3:
1990  xlo = -fDz;
1991  xhi = fDz;
1992  dx = xhi-xlo;
1993  return dx;
1994  }
1995  return dx;
1996 }
1997 
1998 ////////////////////////////////////////////////////////////////////////////////
1999 ///--- Fill vector param[4] with the bounding cylinder parameters. The order
2000 /// is the following : Rmin, Rmax, Phi1, Phi2
2001 
2003 {
2004  param[0] = TMath::Min(fRmin1, fRmin2); // Rmin
2005  param[0] *= param[0];
2006  param[1] = TMath::Max(fRmax1, fRmax2); // Rmax
2007  param[1] *= param[1];
2008  param[2] = (fPhi1<0)?(fPhi1+360.):fPhi1; // Phi1
2009  param[3] = fPhi2; // Phi2
2010  while (param[3]<param[2]) param[3]+=360.;
2011 }
2012 
2013 ////////////////////////////////////////////////////////////////////////////////
2014 /// in case shape has some negative parameters, these has to be computed
2015 /// in order to fit the mother
2016 
2018 {
2019  if (!TestShapeBit(kGeoRunTimeShape)) return 0;
2020  if (!mother->TestShapeBit(kGeoConeSeg)) {
2021  Error("GetMakeRuntimeShape", "invalid mother");
2022  return 0;
2023  }
2024  Double_t rmin1, rmax1, rmin2, rmax2, dz;
2025  rmin1 = fRmin1;
2026  rmax1 = fRmax1;
2027  rmin2 = fRmin2;
2028  rmax2 = fRmax2;
2029  dz = fDz;
2030  if (fDz<0) dz=((TGeoCone*)mother)->GetDz();
2031  if (fRmin1<0)
2032  rmin1 = ((TGeoCone*)mother)->GetRmin1();
2033  if ((fRmax1<0) || (fRmax1<fRmin1))
2034  rmax1 = ((TGeoCone*)mother)->GetRmax1();
2035  if (fRmin2<0)
2036  rmin2 = ((TGeoCone*)mother)->GetRmin2();
2037  if ((fRmax2<0) || (fRmax2<fRmin2))
2038  rmax2 = ((TGeoCone*)mother)->GetRmax2();
2039 
2040  return (new TGeoConeSeg(GetName(), dz, rmin1, rmax1, rmin2, rmax2, fPhi1, fPhi2));
2041 }
2042 
2043 ////////////////////////////////////////////////////////////////////////////////
2044 /// print shape parameters
2045 
2047 {
2048  printf("*** Shape %s: TGeoConeSeg ***\n", GetName());
2049  printf(" dz = %11.5f\n", fDz);
2050  printf(" Rmin1 = %11.5f\n", fRmin1);
2051  printf(" Rmax1 = %11.5f\n", fRmax1);
2052  printf(" Rmin2 = %11.5f\n", fRmin2);
2053  printf(" Rmax2 = %11.5f\n", fRmax2);
2054  printf(" phi1 = %11.5f\n", fPhi1);
2055  printf(" phi2 = %11.5f\n", fPhi2);
2056  printf(" Bounding box:\n");
2058 }
2059 
2060  ///////////////////////////////////////////////////////////////////////////////
2061  /// Creates a TBuffer3D describing *this* shape.
2062  /// Coordinates are in local reference frame.
2063 
2065 {
2067  Int_t nbPnts = 4*n;
2068  Int_t nbSegs = 2*nbPnts;
2069  Int_t nbPols = nbPnts-2;
2071  nbPnts, 3*nbPnts,
2072  nbSegs, 3*nbSegs,
2073  nbPols, 6*nbPols);
2074 
2075  if (buff)
2076  {
2077  SetPoints(buff->fPnts);
2078  SetSegsAndPols(*buff);
2079  }
2080 
2081  return buff;
2082 }
2083 
2084 ////////////////////////////////////////////////////////////////////////////////
2085 /// Fill TBuffer3D structure for segments and polygons.
2086 
2088 {
2089  Int_t i, j;
2091  Int_t c = GetBasicColor();
2092 
2093  memset(buffer.fSegs, 0, buffer.NbSegs()*3*sizeof(Int_t));
2094  for (i = 0; i < 4; i++) {
2095  for (j = 1; j < n; j++) {
2096  buffer.fSegs[(i*n+j-1)*3 ] = c;
2097  buffer.fSegs[(i*n+j-1)*3+1] = i*n+j-1;
2098  buffer.fSegs[(i*n+j-1)*3+2] = i*n+j;
2099  }
2100  }
2101  for (i = 4; i < 6; i++) {
2102  for (j = 0; j < n; j++) {
2103  buffer.fSegs[(i*n+j)*3 ] = c+1;
2104  buffer.fSegs[(i*n+j)*3+1] = (i-4)*n+j;
2105  buffer.fSegs[(i*n+j)*3+2] = (i-2)*n+j;
2106  }
2107  }
2108  for (i = 6; i < 8; i++) {
2109  for (j = 0; j < n; j++) {
2110  buffer.fSegs[(i*n+j)*3 ] = c;
2111  buffer.fSegs[(i*n+j)*3+1] = 2*(i-6)*n+j;
2112  buffer.fSegs[(i*n+j)*3+2] = (2*(i-6)+1)*n+j;
2113  }
2114  }
2115 
2116  Int_t indx = 0;
2117  memset(buffer.fPols, 0, buffer.NbPols()*6*sizeof(Int_t));
2118  i = 0;
2119  for (j = 0; j < n-1; j++) {
2120  buffer.fPols[indx++] = c;
2121  buffer.fPols[indx++] = 4;
2122  buffer.fPols[indx++] = (4+i)*n+j+1;
2123  buffer.fPols[indx++] = (2+i)*n+j;
2124  buffer.fPols[indx++] = (4+i)*n+j;
2125  buffer.fPols[indx++] = i*n+j;
2126  }
2127  i = 1;
2128  for (j = 0; j < n-1; j++) {
2129  buffer.fPols[indx++] = c;
2130  buffer.fPols[indx++] = 4;
2131  buffer.fPols[indx++] = i*n+j;
2132  buffer.fPols[indx++] = (4+i)*n+j;
2133  buffer.fPols[indx++] = (2+i)*n+j;
2134  buffer.fPols[indx++] = (4+i)*n+j+1;
2135  }
2136  i = 2;
2137  for (j = 0; j < n-1; j++) {
2138  buffer.fPols[indx++] = c+i;
2139  buffer.fPols[indx++] = 4;
2140  buffer.fPols[indx++] = (i-2)*2*n+j;
2141  buffer.fPols[indx++] = (4+i)*n+j;
2142  buffer.fPols[indx++] = ((i-2)*2+1)*n+j;
2143  buffer.fPols[indx++] = (4+i)*n+j+1;
2144  }
2145  i = 3;
2146  for (j = 0; j < n-1; j++) {
2147  buffer.fPols[indx++] = c+i;
2148  buffer.fPols[indx++] = 4;
2149  buffer.fPols[indx++] = (4+i)*n+j+1;
2150  buffer.fPols[indx++] = ((i-2)*2+1)*n+j;
2151  buffer.fPols[indx++] = (4+i)*n+j;
2152  buffer.fPols[indx++] = (i-2)*2*n+j;
2153  }
2154  buffer.fPols[indx++] = c+2;
2155  buffer.fPols[indx++] = 4;
2156  buffer.fPols[indx++] = 6*n;
2157  buffer.fPols[indx++] = 4*n;
2158  buffer.fPols[indx++] = 7*n;
2159  buffer.fPols[indx++] = 5*n;
2160  buffer.fPols[indx++] = c+2;
2161  buffer.fPols[indx++] = 4;
2162  buffer.fPols[indx++] = 6*n-1;
2163  buffer.fPols[indx++] = 8*n-1;
2164  buffer.fPols[indx++] = 5*n-1;
2165  buffer.fPols[indx++] = 7*n-1;
2166 }
2167 
2168 ////////////////////////////////////////////////////////////////////////////////
2169 /// computes the closest distance from given point to this shape, according
2170 /// to option. The matching point on the shape is stored in spoint.
2171 
2173 {
2174  Double_t safe = TGeoCone::Safety(point,in);
2175  if ((fPhi2-fPhi1)>=360.) return safe;
2176  Double_t safphi = TGeoShape::SafetyPhi(point, in, fPhi1, fPhi2);
2177  if (in) return TMath::Min(safe, safphi);
2178  if (safe>1.E10) return safphi;
2179  return TMath::Max(safe, safphi);
2180 }
2181 
2182 ////////////////////////////////////////////////////////////////////////////////
2183 /// Static method to compute the closest distance from given point to this shape.
2184 
2186  Double_t rmin2, Double_t rmax2, Double_t phi1, Double_t phi2, Int_t skipz)
2187 {
2188  Double_t safe = TGeoCone::SafetyS(point,in,dz,rmin1,rmax1,rmin2,rmax2,skipz);
2189  if ((phi2-phi1)>=360.) return safe;
2190  Double_t safphi = TGeoShape::SafetyPhi(point,in,phi1,phi2);
2191  if (in) return TMath::Min(safe, safphi);
2192  if (safe>1.E10) return safphi;
2193  return TMath::Max(safe, safphi);
2194 }
2195 
2196 ////////////////////////////////////////////////////////////////////////////////
2197 /// Save a primitive as a C++ statement(s) on output stream "out".
2198 
2199 void TGeoConeSeg::SavePrimitive(std::ostream &out, Option_t * /*option*/ /*= ""*/)
2200 {
2201  if (TObject::TestBit(kGeoSavePrimitive)) return;
2202  out << " // Shape: " << GetName() << " type: " << ClassName() << std::endl;
2203  out << " dz = " << fDz << ";" << std::endl;
2204  out << " rmin1 = " << fRmin1 << ";" << std::endl;
2205  out << " rmax1 = " << fRmax1 << ";" << std::endl;
2206  out << " rmin2 = " << fRmin2 << ";" << std::endl;
2207  out << " rmax2 = " << fRmax2 << ";" << std::endl;
2208  out << " phi1 = " << fPhi1 << ";" << std::endl;
2209  out << " phi2 = " << fPhi2 << ";" << std::endl;
2210  out << " TGeoShape *" << GetPointerName() << " = new TGeoConeSeg(\"" << GetName() << "\", dz,rmin1,rmax1,rmin2,rmax2,phi1,phi2);" << std::endl;
2212 }
2213 
2214 ////////////////////////////////////////////////////////////////////////////////
2215 /// Set dimensions of the cone segment.
2216 
2218  Double_t rmin2, Double_t rmax2, Double_t phi1, Double_t phi2)
2219 {
2220  fDz = dz;
2221  fRmin1 = rmin1;
2222  fRmax1 = rmax1;
2223  fRmin2 = rmin2;
2224  fRmax2 = rmax2;
2225  fPhi1 = phi1;
2226  while (fPhi1<0) fPhi1+=360.;
2227  fPhi2 = phi2;
2228  while (fPhi2<=fPhi1) fPhi2+=360.;
2229  if (TGeoShape::IsSameWithinTolerance(fPhi1,fPhi2)) Fatal("SetConsDimensions", "In shape %s invalid phi1=%g, phi2=%g\n", GetName(), fPhi1, fPhi2);
2230  InitTrigonometry();
2231 }
2232 
2233 ////////////////////////////////////////////////////////////////////////////////
2234 /// Set dimensions of the cone segment from an array.
2235 
2237 {
2238  Double_t dz = param[0];
2239  Double_t rmin1 = param[1];
2240  Double_t rmax1 = param[2];
2241  Double_t rmin2 = param[3];
2242  Double_t rmax2 = param[4];
2243  Double_t phi1 = param[5];
2244  Double_t phi2 = param[6];
2245  SetConsDimensions(dz, rmin1, rmax1,rmin2, rmax2, phi1, phi2);
2246 }
2247 
2248 ////////////////////////////////////////////////////////////////////////////////
2249 /// Create cone segment mesh points.
2250 
2252 {
2253  Int_t j, n;
2254  Float_t dphi,phi,phi1, phi2,dz;
2255 
2256  n = gGeoManager->GetNsegments()+1;
2257  dz = fDz;
2258  phi1 = fPhi1;
2259  phi2 = fPhi2;
2260 
2261  dphi = (phi2-phi1)/(n-1);
2262 
2263  Int_t indx = 0;
2264 
2265  if (points) {
2266  for (j = 0; j < n; j++) {
2267  phi = (fPhi1+j*dphi)*TMath::DegToRad();
2268  points[indx++] = fRmin1 * TMath::Cos(phi);
2269  points[indx++] = fRmin1 * TMath::Sin(phi);
2270  points[indx++] = -dz;
2271  }
2272  for (j = 0; j < n; j++) {
2273  phi = (fPhi1+j*dphi)*TMath::DegToRad();
2274  points[indx++] = fRmax1 * TMath::Cos(phi);
2275  points[indx++] = fRmax1 * TMath::Sin(phi);
2276  points[indx++] = -dz;
2277  }
2278  for (j = 0; j < n; j++) {
2279  phi = (fPhi1+j*dphi)*TMath::DegToRad();
2280  points[indx++] = fRmin2 * TMath::Cos(phi);
2281  points[indx++] = fRmin2 * TMath::Sin(phi);
2282  points[indx++] = dz;
2283  }
2284  for (j = 0; j < n; j++) {
2285  phi = (fPhi1+j*dphi)*TMath::DegToRad();
2286  points[indx++] = fRmax2 * TMath::Cos(phi);
2287  points[indx++] = fRmax2 * TMath::Sin(phi);
2288  points[indx++] = dz;
2289  }
2290  }
2291 }
2292 
2293 ////////////////////////////////////////////////////////////////////////////////
2294 /// Create cone segment mesh points.
2295 
2297 {
2298  Int_t j, n;
2299  Float_t dphi,phi,phi1, phi2,dz;
2300 
2301  n = gGeoManager->GetNsegments()+1;
2302  dz = fDz;
2303  phi1 = fPhi1;
2304  phi2 = fPhi2;
2305 
2306  dphi = (phi2-phi1)/(n-1);
2307 
2308  Int_t indx = 0;
2309 
2310  if (points) {
2311  for (j = 0; j < n; j++) {
2312  phi = (fPhi1+j*dphi)*TMath::DegToRad();
2313  points[indx++] = fRmin1 * TMath::Cos(phi);
2314  points[indx++] = fRmin1 * TMath::Sin(phi);
2315  points[indx++] = -dz;
2316  }
2317  for (j = 0; j < n; j++) {
2318  phi = (fPhi1+j*dphi)*TMath::DegToRad();
2319  points[indx++] = fRmax1 * TMath::Cos(phi);
2320  points[indx++] = fRmax1 * TMath::Sin(phi);
2321  points[indx++] = -dz;
2322  }
2323  for (j = 0; j < n; j++) {
2324  phi = (fPhi1+j*dphi)*TMath::DegToRad();
2325  points[indx++] = fRmin2 * TMath::Cos(phi);
2326  points[indx++] = fRmin2 * TMath::Sin(phi);
2327  points[indx++] = dz;
2328  }
2329  for (j = 0; j < n; j++) {
2330  phi = (fPhi1+j*dphi)*TMath::DegToRad();
2331  points[indx++] = fRmax2 * TMath::Cos(phi);
2332  points[indx++] = fRmax2 * TMath::Sin(phi);
2333  points[indx++] = dz;
2334  }
2335  }
2336 }
2337 
2338 ////////////////////////////////////////////////////////////////////////////////
2339 /// Returns numbers of vertices, segments and polygons composing the shape mesh.
2340 
2341 void TGeoConeSeg::GetMeshNumbers(Int_t &nvert, Int_t &nsegs, Int_t &npols) const
2342 {
2344  nvert = n*4;
2345  nsegs = n*8;
2346  npols = n*4-2;
2347 }
2348 
2349 ////////////////////////////////////////////////////////////////////////////////
2350 /// Return number of vertices of the mesh representation
2351 
2353 {
2355  Int_t numPoints = n*4;
2356  return numPoints;
2357 }
2358 
2359 ////////////////////////////////////////////////////////////////////////////////
2360 ////// fill size of this 3-D object
2361 //// TVirtualGeoPainter *painter = gGeoManager->GetGeomPainter();
2362 //// if (!painter) return;
2363 ////
2364 //// Int_t n = gGeoManager->GetNsegments()+1;
2365 ////
2366 //// Int_t numPoints = n*4;
2367 //// Int_t numSegs = n*8;
2368 //// Int_t numPolys = n*4-2;
2369 //// painter->AddSize3D(numPoints, numSegs, numPolys);
2370 
2372 {
2373 }
2374 
2375 ////////////////////////////////////////////////////////////////////////////////
2376 /// Fills a static 3D buffer and returns a reference.
2377 
2378 const TBuffer3D & TGeoConeSeg::GetBuffer3D(Int_t reqSections, Bool_t localFrame) const
2379 {
2381 
2382  TGeoBBox::FillBuffer3D(buffer, reqSections, localFrame);
2383 
2384  if (reqSections & TBuffer3D::kRawSizes) {
2386  Int_t nbPnts = 4*n;
2387  Int_t nbSegs = 2*nbPnts;
2388  Int_t nbPols = nbPnts-2;
2389  if (buffer.SetRawSizes(nbPnts, 3*nbPnts, nbSegs, 3*nbSegs, nbPols, 6*nbPols)) {
2390  buffer.SetSectionsValid(TBuffer3D::kRawSizes);
2391  }
2392  }
2393  if ((reqSections & TBuffer3D::kRaw) && buffer.SectionsValid(TBuffer3D::kRawSizes)) {
2394  SetPoints(buffer.fPnts);
2395  if (!buffer.fLocalFrame) {
2396  TransformPoints(buffer.fPnts, buffer.NbPnts());
2397  }
2398 
2399  SetSegsAndPols(buffer);
2400  buffer.SetSectionsValid(TBuffer3D::kRaw);
2401  }
2402 
2403  return buffer;
2404 }
2405 
2406 ////////////////////////////////////////////////////////////////////////////////
2407 /// Fills array with n random points located on the line segments of the shape mesh.
2408 /// The output array must be provided with a length of minimum 3*npoints. Returns
2409 /// true if operation is implemented.
2410 
2412 {
2413  if (npoints > (npoints/2)*2) {
2414  Error("GetPointsOnSegments","Npoints must be even number");
2415  return kFALSE;
2416  }
2417  Int_t nc = (Int_t)TMath::Sqrt(0.5*npoints);
2418  Double_t dphi = (fPhi2-fPhi1)*TMath::DegToRad()/(nc-1);
2419  Double_t phi = 0;
2420  Double_t phi1 = fPhi1 * TMath::DegToRad();
2421  Int_t ntop = npoints/2 - nc*(nc-1);
2422  Double_t dz = 2*fDz/(nc-1);
2423  Double_t z = 0;
2424  Double_t rmin = 0.;
2425  Double_t rmax = 0.;
2426  Int_t icrt = 0;
2427  Int_t nphi = nc;
2428  // loop z sections
2429  for (Int_t i=0; i<nc; i++) {
2430  if (i == (nc-1)) {
2431  nphi = ntop;
2432  dphi = (fPhi2-fPhi1)*TMath::DegToRad()/(nphi-1);
2433  }
2434  z = -fDz + i*dz;
2435  rmin = 0.5*(fRmin1+fRmin2) + 0.5*(fRmin2-fRmin1)*z/fDz;
2436  rmax = 0.5*(fRmax1+fRmax2) + 0.5*(fRmax2-fRmax1)*z/fDz;
2437  // loop points on circle sections
2438  for (Int_t j=0; j<nphi; j++) {
2439  phi = phi1 + j*dphi;
2440  array[icrt++] = rmin * TMath::Cos(phi);
2441  array[icrt++] = rmin * TMath::Sin(phi);
2442  array[icrt++] = z;
2443  array[icrt++] = rmax * TMath::Cos(phi);
2444  array[icrt++] = rmax * TMath::Sin(phi);
2445  array[icrt++] = z;
2446  }
2447  }
2448  return kTRUE;
2449 }
2450 
2451 ////////////////////////////////////////////////////////////////////////////////
2452 /// Check the inside status for each of the points in the array.
2453 /// Input: Array of point coordinates + vector size
2454 /// Output: Array of Booleans for the inside of each point
2455 
2456 void TGeoConeSeg::Contains_v(const Double_t *points, Bool_t *inside, Int_t vecsize) const
2457 {
2458  for (Int_t i=0; i<vecsize; i++) inside[i] = Contains(&points[3*i]);
2459 }
2460 
2461 ////////////////////////////////////////////////////////////////////////////////
2462 /// Compute the normal for an array o points so that norm.dot.dir is positive
2463 /// Input: Arrays of point coordinates and directions + vector size
2464 /// Output: Array of normal directions
2465 
2466 void TGeoConeSeg::ComputeNormal_v(const Double_t *points, const Double_t *dirs, Double_t *norms, Int_t vecsize)
2467 {
2468  for (Int_t i=0; i<vecsize; i++) ComputeNormal(&points[3*i], &dirs[3*i], &norms[3*i]);
2469 }
2470 
2471 ////////////////////////////////////////////////////////////////////////////////
2472 /// Compute distance from array of input points having directions specisied by dirs. Store output in dists
2473 
2474 void TGeoConeSeg::DistFromInside_v(const Double_t *points, const Double_t *dirs, Double_t *dists, Int_t vecsize, Double_t* step) const
2475 {
2476  for (Int_t i=0; i<vecsize; i++) dists[i] = DistFromInside(&points[3*i], &dirs[3*i], 3, step[i]);
2477 }
2478 
2479 ////////////////////////////////////////////////////////////////////////////////
2480 /// Compute distance from array of input points having directions specisied by dirs. Store output in dists
2481 
2482 void TGeoConeSeg::DistFromOutside_v(const Double_t *points, const Double_t *dirs, Double_t *dists, Int_t vecsize, Double_t* step) const
2483 {
2484  for (Int_t i=0; i<vecsize; i++) dists[i] = DistFromOutside(&points[3*i], &dirs[3*i], 3, step[i]);
2485 }
2486 
2487 ////////////////////////////////////////////////////////////////////////////////
2488 /// Compute safe distance from each of the points in the input array.
2489 /// Input: Array of point coordinates, array of statuses for these points, size of the arrays
2490 /// Output: Safety values
2491 
2492 void TGeoConeSeg::Safety_v(const Double_t *points, const Bool_t *inside, Double_t *safe, Int_t vecsize) const
2493 {
2494  for (Int_t i=0; i<vecsize; i++) safe[i] = Safety(&points[3*i], inside[i]);
2495 }
TGeoVolumeMulti * MakeVolumeMulti(const char *name, TGeoMedium *medium)
Make a TGeoVolumeMulti handling a list of volumes.
virtual ~TGeoConeSeg()
destructor
Definition: TGeoCone.cxx:1256
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
virtual void Sizeof3D() const
Definition: TGeoCone.cxx:1111
float xmin
Definition: THbookFile.cxx:93
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
Int_t GetNsegments() const
Get number of segments approximating circles.
virtual const char * GetAxisName(Int_t iaxis) const
Returns name of axis IAXIS.
Definition: TGeoCone.cxx:612
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
virtual Bool_t Contains(const Double_t *point) const
test if point is inside this cone
Definition: TGeoCone.cxx:255
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
virtual TBuffer3D * MakeBuffer3D() const
Creates a TBuffer3D describing this shape.
Definition: TGeoCone.cxx:760
virtual void SetPoints(Double_t *points) const
Create cone mesh points.
Definition: TGeoCone.cxx:995
float Float_t
Definition: RtypesCore.h:53
Double_t fSm
cos(phi2)
Definition: TGeoCone.h:132
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
TCanvas * c1
Definition: legend1.C:2
float ymin
Definition: THbookFile.cxx:93
virtual void ComputeBBox()
compute bounding box of the tube segment
Definition: TGeoCone.cxx:1308
Int_t GetBasicColor() const
Get the basic color (0-7).
Definition: TGeoShape.cxx:672
Double_t DegToRad()
Definition: TMath.h:50
Double_t fS1
Definition: TGeoCone.h:128
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: TGeoCone.cxx:1179
virtual TGeoVolume * Divide(TGeoVolume *voldiv, const char *divname, Int_t iaxis, Int_t ndiv, Double_t start, Double_t step)
— Divide this cone segment shape belonging to volume "voldiv" into ndiv volumes called divname...
Definition: TGeoCone.cxx:1918
virtual void ComputeBBox()
compute bounding box of the sphere
Definition: TGeoCone.cxx:165
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 fRmin1
Definition: TGeoCone.h:36
Double_t fOrigin[3]
Definition: TGeoBBox.h:36
Double_t RadToDeg()
Definition: TMath.h:49
Basic string class.
Definition: TString.h:137
UInt_t NbSegs() const
Definition: TBuffer3D.h:83
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: TGeoCone.cxx:862
Short_t Min(Short_t a, Short_t b)
Definition: TMathBase.h:170
int Int_t
Definition: RtypesCore.h:41
bool Bool_t
Definition: RtypesCore.h:59
TArc * a
Definition: textangle.C:12
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
virtual void SetPoints(Double_t *points) const
Create cone segment mesh points.
Definition: TGeoCone.cxx:2251
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: TGeoCone.cxx:1189
Float_t py
Definition: hprod.C:33
Double_t fRmax1
Definition: TGeoCone.h:37
virtual void InspectShape() const
print shape parameters
Definition: TGeoCone.cxx:2046
void box(Int_t pat, Double_t x1, Double_t y1, Double_t x2, Double_t y2)
Definition: fillpatterns.C:1
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
Double_t fC2
sin(phi2)
Definition: TGeoCone.h:131
Short_t Abs(Short_t d)
Definition: TMathBase.h:110
Int_t GetNdaughters() const
Definition: TGeoVolume.h:362
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: TGeoCone.cxx:2341
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
TObjArray * GetNodes()
Definition: TGeoVolume.h:183
static Double_t Tolerance()
Definition: TGeoShape.h:101
virtual void SetDimensions(Double_t *param)
Set cone dimensions from an array.
Definition: TGeoCone.cxx:982
Double_t fPhi1
Definition: TGeoCone.h:125
TSocket * s1
Definition: hserv2.C:36
void InitTrigonometry()
cos(0.5*(phi1-phi2))
Definition: TGeoCone.cxx:1271
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
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
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: TGeoCone.cxx:1163
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
Double_t fC1
sin(phi1)
Definition: TGeoCone.h:129
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: TGeoCone.cxx:2474
virtual Bool_t GetPointsOnSegments(Int_t npoints, Double_t *array) const
Fills array with n random points located on the line segments of the shape mesh.
Definition: TGeoCone.cxx:2411
Double_t * fPnts
Definition: TBuffer3D.h:114
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 compute safe radius
Definition: TGeoCone.cxx:1886
virtual void AfterStreamer()
Function called after streaming an object of this class.
Definition: TGeoCone.cxx:1263
Double_t fRmin2
Definition: TGeoCone.h:38
Double_t ATan2(Double_t, Double_t)
Definition: TMath.h:454
XFontStruct * id
Definition: TGX11.cxx:108
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition: TObject.cxx:918
Double_t TwoPi()
Definition: TMath.h:45
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: TGeoCone.cxx:1153
Float_t z[5]
Definition: Ifit.C:16
Double_t fRmax2
Definition: TGeoCone.h:39
virtual void SavePrimitive(std::ostream &out, Option_t *option="")
Save a primitive as a C++ statement(s) on output stream "out".
Definition: TGeoCone.cxx:912
virtual TBuffer3D * MakeBuffer3D() const
Creates a TBuffer3D describing this shape.
Definition: TGeoCone.cxx:2064
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 cone Boundary safe algorithm.
Definition: TGeoCone.cxx:341
UInt_t NbPols() const
Definition: TBuffer3D.h:84
char * out
Definition: TBase64.cxx:29
void SetSectionsValid(UInt_t mask)
Definition: TBuffer3D.h:67
Double_t fS2
cos(phi1)
Definition: TGeoCone.h:130
Int_t * fPols
Definition: TBuffer3D.h:116
static Double_t SafetySeg(Double_t r, Double_t z, Double_t r1, Double_t z1, Double_t r2, Double_t z2, Bool_t outer)
Compute distance from point of coordinates (r,z) to segment (r1,z1):(r2,z2)
Definition: TGeoShape.cxx:493
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
virtual void SetSegsAndPols(TBuffer3D &buffer) const
Fill TBuffer3D structure for segments and polygons.
Definition: TGeoCone.cxx:782
virtual Int_t DistancetoPrimitive(Int_t px, Int_t py)
compute closest distance from point px,py to each corner
Definition: TGeoCone.cxx:540
float ymax
Definition: THbookFile.cxx:93
virtual void SetDimensions(Double_t *param)
Set dimensions of the cone segment from an array.
Definition: TGeoCone.cxx:2236
ROOT::R::TRInterface & r
Definition: Object.C:4
virtual void GetBoundingCylinder(Double_t *param) const
— Fill vector param[4] with the bounding cylinder parameters.
Definition: TGeoCone.cxx:652
virtual const char * ClassName() const
Returns name of class to which the object belongs.
Definition: TObject.cxx:187
unsigned int r1[N_CITIES]
Definition: simanTSP.cxx:321
static void DistToCone(const Double_t *point, const Double_t *dir, Double_t dz, Double_t r1, Double_t r2, Double_t &b, Double_t &delta)
Static method to compute distance to a conical surface with :
Definition: TGeoCone.cxx:506
virtual Int_t GetNmeshVertices() const
Return number of vertices of the mesh representation.
Definition: TGeoCone.cxx:2352
virtual Double_t Capacity() const
Computes capacity of the shape in [length^3].
Definition: TGeoCone.cxx:1289
virtual TGeoShape * GetMakeRuntimeShape(TGeoShape *mother, TGeoMatrix *mat) const
in case shape has some negative parameters, these has to be computed in order to fit the mother ...
Definition: TGeoCone.cxx:666
static Double_t DistToPhiMin(const Double_t *point, const Double_t *dir, Double_t s1, Double_t c1, Double_t s2, Double_t c2, Double_t sm, Double_t cm, Bool_t in=kTRUE)
compute distance from point (inside phi) to both phi planes. Return minimum.
Definition: TGeoShape.cxx:404
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: TGeoCone.cxx:1083
Bool_t TestBit(UInt_t f) const
Definition: TObject.h:173
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
virtual void Sizeof3D() const
Definition: TGeoCone.cxx:2371
Generic 3D primitive description class.
Definition: TBuffer3D.h:19
virtual Double_t Capacity() const
Computes capacity of the shape in [length^3].
Definition: TGeoCone.cxx:140
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: TGeoCone.cxx:2482
float xmax
Definition: THbookFile.cxx:93
virtual Double_t GetAxisRange(Int_t iaxis, Double_t &xlo, Double_t &xhi) const
Get range of shape for a given axis.
Definition: TGeoCone.cxx:1978
virtual TGeoVolume * Divide(TGeoVolume *voldiv, const char *divname, Int_t iaxis, Int_t ndiv, Double_t start, Double_t step)
— Divide this cone shape belonging to volume "voldiv" into ndiv volumes called divname, from start position with the given step.
Definition: TGeoCone.cxx:555
void SetDivIndex(Int_t index)
virtual const char * GetName() const
Get the shape name.
Definition: TGeoShape.cxx:247
virtual const TBuffer3D & GetBuffer3D(Int_t reqSections, Bool_t localFrame) const
Fills a static 3D buffer and returns a reference.
Definition: TGeoCone.cxx:1118
void SetBoxDimensions(Double_t dx, Double_t dy, Double_t dz, Double_t *origin=0)
Set parameters of the box.
Definition: TGeoBBox.cxx:856
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: TGeoCone.cxx:2456
Double_t Cos(Double_t)
Definition: TMath.h:424
virtual Bool_t GetPointsOnSegments(Int_t npoints, Double_t *array) const
Fills array with n random points located on the line segments of the shape mesh.
Definition: TGeoCone.cxx:697
static Double_t DistToCons(const Double_t *point, const Double_t *dir, Double_t r1, Double_t z1, Double_t r2, Double_t z2, Double_t phi1, Double_t phi2)
Static method to compute distance to a conical surface with :
Definition: TGeoCone.cxx:1472
Double_t Pi()
Definition: TMath.h:44
Float_t phi
Definition: shapesAnim.C:6
ClassImp(TGeoCone) TGeoCone
Default constructor.
Definition: TGeoCone.cxx:74
virtual void ComputeNormal(const Double_t *point, const Double_t *dir, Double_t *norm)
Compute normal to closest surface from POINT.
Definition: TGeoCone.cxx:1354
static Bool_t IsCloseToPhi(Double_t epsil, const Double_t *point, Double_t c1, Double_t s1, Double_t c2, Double_t s2)
True if point is closer than epsil to one of the phi planes defined by c1,s1 or c2,s2.
Definition: TGeoShape.cxx:268
virtual void InspectShape() const
Prints shape parameters.
Definition: TGeoBBox.cxx:749
return c2
Definition: legend2.C:14
TH1F * s2
Definition: threadsh2.C:15
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
virtual void SavePrimitive(std::ostream &out, Option_t *option="")
Save a primitive as a C++ statement(s) on output stream "out".
Definition: TGeoCone.cxx:2199
ClassImp(TMCParticle) void TMCParticle printf(": p=(%7.3f,%7.3f,%9.3f) ;", fPx, fPy, fPz)
void dir(char *path=0)
Definition: rootalias.C:30
Double_t fDz
Definition: TGeoCone.h:35
virtual Int_t DistancetoPrimitive(Int_t px, Int_t py)
compute closest distance from point px,py to each corner
Definition: TGeoCone.cxx:1903
Int_t ShapeDistancetoPrimitive(Int_t numpoints, Int_t px, Int_t py) const
Returns distance to shape primitive mesh.
Definition: TGeoShape.cxx:258
virtual void GetBoundingCylinder(Double_t *param) const
— Fill vector param[4] with the bounding cylinder parameters.
Definition: TGeoCone.cxx:2002
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: TGeoCone.cxx:2492
virtual TGeoShape * GetMakeRuntimeShape(TGeoShape *mother, TGeoMatrix *mat) const
in case shape has some negative parameters, these has to be computed in order to fit the mother ...
Definition: TGeoCone.cxx:2017
const char * GetPointerName() const
Provide a pointer name containing uid.
Definition: TGeoShape.cxx:698
static Double_t Big()
Definition: TGeoShape.h:98
virtual Double_t GetAxisRange(Int_t iaxis, Double_t &xlo, Double_t &xhi) const
Get range of shape for a given axis.
Definition: TGeoCone.cxx:629
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
virtual void ComputeNormal(const Double_t *point, const Double_t *dir, Double_t *norm)
Compute normal to closest surface from POINT.
Definition: TGeoCone.cxx:175
Double_t fDY
Definition: TGeoBBox.h:34
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: TGeoCone.cxx:2466
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
virtual ~TGeoCone()
destructor
Definition: TGeoCone.cxx:158
void SetShapeBit(UInt_t f, Bool_t set)
Equivalent of TObject::SetBit.
Definition: TGeoShape.cxx:523
void SetConeDimensions(Double_t dz, Double_t rmin1, Double_t rmax1, Double_t rmin2, Double_t rmax2)
Set cone dimensions.
Definition: TGeoCone.cxx:928
void SetConsDimensions(Double_t dz, Double_t rmin1, Double_t rmax1, Double_t rmin2, Double_t rmax2, Double_t phi1, Double_t phi2)
Set dimensions of the cone segment.
Definition: TGeoCone.cxx:2217
Float_t px
Definition: hprod.C:33
Int_t * fSegs
Definition: TBuffer3D.h:115
virtual Bool_t Contains(const Double_t *point) const
test if point is inside this sphere
Definition: TGeoCone.cxx:1452
Bool_t TestShapeBit(UInt_t f) const
Definition: TGeoShape.h:172
virtual void InspectShape() const
print shape parameters
Definition: TGeoCone.cxx:744
UInt_t NbPnts() const
Definition: TBuffer3D.h:82
TGeoMedium * GetMedium() const
Definition: TGeoVolume.h:189
Short_t Max(Short_t a, Short_t b)
Definition: TMathBase.h:202
Double_t Sin(Double_t)
Definition: TMath.h:421
virtual Int_t GetNmeshVertices() const
Return number of vertices of the mesh representation.
Definition: TGeoCone.cxx:1094
Double_t fDX
Definition: TGeoBBox.h:33
static void NormalPhi(const Double_t *point, const Double_t *dir, Double_t *norm, Double_t c1, Double_t s1, Double_t c2, Double_t s2)
Static method to compute normal to phi planes.
Definition: TGeoShape.cxx:436
Double_t fCdfi
cos(0.5*(phi1+phi2))
Definition: TGeoCone.h:134
Double_t fPhi2
Definition: TGeoCone.h:126
Double_t Sqrt(Double_t x)
Definition: TMath.h:464
virtual const TBuffer3D & GetBuffer3D(Int_t reqSections, Bool_t localFrame) const
Fills a static 3D buffer and returns a reference.
Definition: TGeoCone.cxx:2378
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
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: TGeoCone.cxx:2172
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 tube segment
Definition: TGeoCone.cxx:1594
Double_t fCm
sin(0.5*(phi1+phi2))
Definition: TGeoCone.h:133
double norm(double *x, double *p)
Definition: unuranDistr.cxx:40
const Int_t n
Definition: legend1.C:16
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 compute safe radius
Definition: TGeoCone.cxx:487
unsigned int r2[N_CITIES]
Definition: simanTSP.cxx:322
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: TGeoCone.cxx:1171
Bool_t SectionsValid(UInt_t mask) const
Definition: TBuffer3D.h:69
virtual void SetSegsAndPols(TBuffer3D &buffer) const
Fill TBuffer3D structure for segments and polygons.
Definition: TGeoCone.cxx:2087
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition: TObject.cxx:904