ROOT  6.06/09
Reference Guide
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 
175 void TGeoCone::ComputeNormal(const Double_t *point, const Double_t *dir, Double_t *norm)
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 
218 void TGeoCone::ComputeNormalS(const Double_t *point, const Double_t *dir, Double_t *norm,
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 
506 void TGeoCone::DistToCone(const Double_t *point, const Double_t *dir, Double_t dz, Double_t r1, Double_t r2,
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  saf[2] = TGeoShape::SafetySeg(r,point[2], rmin1, -dz, rmin2, dz, in);
902  saf[3] = TGeoShape::SafetySeg(r,point[2], rmax1, -dz, rmax2, dz, !in);
903  return saf[TMath::LocMin(4,saf)];
904 }
905 
906 ////////////////////////////////////////////////////////////////////////////////
907 /// Save a primitive as a C++ statement(s) on output stream "out".
908 
909 void TGeoCone::SavePrimitive(std::ostream &out, Option_t * /*option*/ /*= ""*/)
910 {
911  if (TObject::TestBit(kGeoSavePrimitive)) return;
912  out << " // Shape: " << GetName() << " type: " << ClassName() << std::endl;
913  out << " dz = " << fDz << ";" << std::endl;
914  out << " rmin1 = " << fRmin1 << ";" << std::endl;
915  out << " rmax1 = " << fRmax1 << ";" << std::endl;
916  out << " rmin2 = " << fRmin2 << ";" << std::endl;
917  out << " rmax2 = " << fRmax2 << ";" << std::endl;
918  out << " TGeoShape *" << GetPointerName() << " = new TGeoCone(\"" << GetName() << "\", dz,rmin1,rmax1,rmin2,rmax2);" << std::endl;
920 }
921 
922 ////////////////////////////////////////////////////////////////////////////////
923 /// Set cone dimensions.
924 
926  Double_t rmin2, Double_t rmax2)
927 {
928  if (rmin1>=0) {
929  if (rmax1>0) {
930  if (rmin1<=rmax1) {
931  // normal rmin/rmax
932  fRmin1 = rmin1;
933  fRmax1 = rmax1;
934  } else {
935  fRmin1 = rmax1;
936  fRmax1 = rmin1;
937  Warning("SetConeDimensions", "rmin1>rmax1 Switch rmin1<->rmax1");
939  }
940  } else {
941  // run-time
942  fRmin1 = rmin1;
943  fRmax1 = rmax1;
944  }
945  } else {
946  // run-time
947  fRmin1 = rmin1;
948  fRmax1 = rmax1;
949  }
950  if (rmin2>=0) {
951  if (rmax2>0) {
952  if (rmin2<=rmax2) {
953  // normal rmin/rmax
954  fRmin2 = rmin2;
955  fRmax2 = rmax2;
956  } else {
957  fRmin2 = rmax2;
958  fRmax2 = rmin2;
959  Warning("SetConeDimensions", "rmin2>rmax2 Switch rmin2<->rmax2");
961  }
962  } else {
963  // run-time
964  fRmin2 = rmin2;
965  fRmax2 = rmax2;
966  }
967  } else {
968  // run-time
969  fRmin2 = rmin2;
970  fRmax2 = rmax2;
971  }
972 
973  fDz = dz;
974 }
975 
976 ////////////////////////////////////////////////////////////////////////////////
977 /// Set cone dimensions from an array.
978 
980 {
981  Double_t dz = param[0];
982  Double_t rmin1 = param[1];
983  Double_t rmax1 = param[2];
984  Double_t rmin2 = param[3];
985  Double_t rmax2 = param[4];
986  SetConeDimensions(dz, rmin1, rmax1, rmin2, rmax2);
987 }
988 
989 ////////////////////////////////////////////////////////////////////////////////
990 /// Create cone mesh points.
991 
993 {
994  Double_t dz, phi, dphi;
995  Int_t j, n;
996 
997  n = gGeoManager->GetNsegments();
998  dphi = 360./n;
999  dz = fDz;
1000  Int_t indx = 0;
1001 
1002  if (points) {
1003  for (j = 0; j < n; j++) {
1004  phi = j*dphi*TMath::DegToRad();
1005  points[indx++] = fRmin1 * TMath::Cos(phi);
1006  points[indx++] = fRmin1 * TMath::Sin(phi);
1007  points[indx++] = -dz;
1008  }
1009 
1010  for (j = 0; j < n; j++) {
1011  phi = j*dphi*TMath::DegToRad();
1012  points[indx++] = fRmax1 * TMath::Cos(phi);
1013  points[indx++] = fRmax1 * TMath::Sin(phi);
1014  points[indx++] = -dz;
1015  }
1016 
1017  for (j = 0; j < n; j++) {
1018  phi = j*dphi*TMath::DegToRad();
1019  points[indx++] = fRmin2 * TMath::Cos(phi);
1020  points[indx++] = fRmin2 * TMath::Sin(phi);
1021  points[indx++] = dz;
1022  }
1023 
1024  for (j = 0; j < n; j++) {
1025  phi = j*dphi*TMath::DegToRad();
1026  points[indx++] = fRmax2 * TMath::Cos(phi);
1027  points[indx++] = fRmax2 * TMath::Sin(phi);
1028  points[indx++] = dz;
1029  }
1030  }
1031 }
1032 
1033 ////////////////////////////////////////////////////////////////////////////////
1034 /// Create cone mesh points.
1035 
1037 {
1038  Double_t dz, phi, dphi;
1039  Int_t j, n;
1040 
1041  n = gGeoManager->GetNsegments();
1042  dphi = 360./n;
1043  dz = fDz;
1044  Int_t indx = 0;
1045 
1046  if (points) {
1047  for (j = 0; j < n; j++) {
1048  phi = j*dphi*TMath::DegToRad();
1049  points[indx++] = fRmin1 * TMath::Cos(phi);
1050  points[indx++] = fRmin1 * TMath::Sin(phi);
1051  points[indx++] = -dz;
1052  }
1053 
1054  for (j = 0; j < n; j++) {
1055  phi = j*dphi*TMath::DegToRad();
1056  points[indx++] = fRmax1 * TMath::Cos(phi);
1057  points[indx++] = fRmax1 * TMath::Sin(phi);
1058  points[indx++] = -dz;
1059  }
1060 
1061  for (j = 0; j < n; j++) {
1062  phi = j*dphi*TMath::DegToRad();
1063  points[indx++] = fRmin2 * TMath::Cos(phi);
1064  points[indx++] = fRmin2 * TMath::Sin(phi);
1065  points[indx++] = dz;
1066  }
1067 
1068  for (j = 0; j < n; j++) {
1069  phi = j*dphi*TMath::DegToRad();
1070  points[indx++] = fRmax2 * TMath::Cos(phi);
1071  points[indx++] = fRmax2 * TMath::Sin(phi);
1072  points[indx++] = dz;
1073  }
1074  }
1075 }
1076 
1077 ////////////////////////////////////////////////////////////////////////////////
1078 /// Returns numbers of vertices, segments and polygons composing the shape mesh.
1079 
1080 void TGeoCone::GetMeshNumbers(Int_t &nvert, Int_t &nsegs, Int_t &npols) const
1081 {
1083  nvert = n*4;
1084  nsegs = n*8;
1085  npols = n*4;
1086 }
1087 
1088 ////////////////////////////////////////////////////////////////////////////////
1089 /// Return number of vertices of the mesh representation
1090 
1092 {
1094  Int_t numPoints = n*4;
1095  return numPoints;
1096 }
1097 
1098 ////////////////////////////////////////////////////////////////////////////////
1099 ////// fill size of this 3-D object
1100 //// TVirtualGeoPainter *painter = gGeoManager->GetGeomPainter();
1101 //// if (!painter) return;
1102 //// Int_t n = gGeoManager->GetNsegments();
1103 //// Int_t numPoints = n*4;
1104 //// Int_t numSegs = n*8;
1105 //// Int_t numPolys = n*4;
1106 //// painter->AddSize3D(numPoints, numSegs, numPolys);
1107 
1109 {
1110 }
1111 
1112 ////////////////////////////////////////////////////////////////////////////////
1113 /// Fills a static 3D buffer and returns a reference.
1114 
1115 const TBuffer3D & TGeoCone::GetBuffer3D(Int_t reqSections, Bool_t localFrame) const
1116 {
1117  static TBuffer3D buffer(TBuffer3DTypes::kGeneric);
1118 
1119  TGeoBBox::FillBuffer3D(buffer, reqSections, localFrame);
1120 
1121  if (reqSections & TBuffer3D::kRawSizes) {
1123  Int_t nbPnts = 4*n;
1124  Int_t nbSegs = 8*n;
1125  Int_t nbPols = 4*n;
1126  if (buffer.SetRawSizes(nbPnts, 3*nbPnts, nbSegs, 3*nbSegs, nbPols, 6*nbPols)) {
1127  buffer.SetSectionsValid(TBuffer3D::kRawSizes);
1128  }
1129  }
1130 
1131  // TODO: Can we push this as common down to TGeoShape?
1132  if ((reqSections & TBuffer3D::kRaw) && buffer.SectionsValid(TBuffer3D::kRawSizes)) {
1133  SetPoints(buffer.fPnts);
1134  if (!buffer.fLocalFrame) {
1135  TransformPoints(buffer.fPnts, buffer.NbPnts());
1136  }
1137 
1138  SetSegsAndPols(buffer);
1139  buffer.SetSectionsValid(TBuffer3D::kRaw);
1140  }
1141 
1142  return buffer;
1143 }
1144 
1145 ////////////////////////////////////////////////////////////////////////////////
1146 /// Check the inside status for each of the points in the array.
1147 /// Input: Array of point coordinates + vector size
1148 /// Output: Array of Booleans for the inside of each point
1149 
1150 void TGeoCone::Contains_v(const Double_t *points, Bool_t *inside, Int_t vecsize) const
1151 {
1152  for (Int_t i=0; i<vecsize; i++) inside[i] = Contains(&points[3*i]);
1153 }
1154 
1155 ////////////////////////////////////////////////////////////////////////////////
1156 /// Compute the normal for an array o points so that norm.dot.dir is positive
1157 /// Input: Arrays of point coordinates and directions + vector size
1158 /// Output: Array of normal directions
1159 
1160 void TGeoCone::ComputeNormal_v(const Double_t *points, const Double_t *dirs, Double_t *norms, Int_t vecsize)
1161 {
1162  for (Int_t i=0; i<vecsize; i++) ComputeNormal(&points[3*i], &dirs[3*i], &norms[3*i]);
1163 }
1164 
1165 ////////////////////////////////////////////////////////////////////////////////
1166 /// Compute distance from array of input points having directions specisied by dirs. Store output in dists
1167 
1168 void TGeoCone::DistFromInside_v(const Double_t *points, const Double_t *dirs, Double_t *dists, Int_t vecsize, Double_t* step) const
1169 {
1170  for (Int_t i=0; i<vecsize; i++) dists[i] = DistFromInside(&points[3*i], &dirs[3*i], 3, step[i]);
1171 }
1172 
1173 ////////////////////////////////////////////////////////////////////////////////
1174 /// Compute distance from array of input points having directions specisied by dirs. Store output in dists
1175 
1176 void TGeoCone::DistFromOutside_v(const Double_t *points, const Double_t *dirs, Double_t *dists, Int_t vecsize, Double_t* step) const
1177 {
1178  for (Int_t i=0; i<vecsize; i++) dists[i] = DistFromOutside(&points[3*i], &dirs[3*i], 3, step[i]);
1179 }
1180 
1181 ////////////////////////////////////////////////////////////////////////////////
1182 /// Compute safe distance from each of the points in the input array.
1183 /// Input: Array of point coordinates, array of statuses for these points, size of the arrays
1184 /// Output: Safety values
1185 
1186 void TGeoCone::Safety_v(const Double_t *points, const Bool_t *inside, Double_t *safe, Int_t vecsize) const
1187 {
1188  for (Int_t i=0; i<vecsize; i++) safe[i] = Safety(&points[3*i], inside[i]);
1189 }
1190 
1192 
1193 ////////////////////////////////////////////////////////////////////////////////
1194 /// Default constructor
1195 
1197  :TGeoCone(),
1198  fPhi1(0.), fPhi2(0.), fS1(0.), fC1(0.), fS2(0.), fC2(0.), fSm(0.), fCm(0.), fCdfi(0.)
1199 {
1200  SetShapeBit(TGeoShape::kGeoConeSeg);
1201  fPhi1 = fPhi2 = 0.0;
1202 }
1203 
1204 ////////////////////////////////////////////////////////////////////////////////
1205 
1207  Double_t rmin2, Double_t rmax2, Double_t phi1, Double_t phi2)
1208  :TGeoCone(dz, rmin1, rmax1, rmin2, rmax2),
1209  fPhi1(0.), fPhi2(0.), fS1(0.), fC1(0.), fS2(0.), fC2(0.), fSm(0.), fCm(0.), fCdfi(0.)
1210 
1211 {
1212 // Default constructor specifying minimum and maximum radius
1214  SetConsDimensions(dz, rmin1, rmax1, rmin2, rmax2, phi1, phi2);
1215  ComputeBBox();
1216 }
1217 
1218 ////////////////////////////////////////////////////////////////////////////////
1219 /// Default constructor specifying minimum and maximum radius
1220 
1222  Double_t rmin2, Double_t rmax2, Double_t phi1, Double_t phi2)
1223  :TGeoCone(name, dz, rmin1, rmax1, rmin2, rmax2),
1224  fPhi1(0.), fPhi2(0.), fS1(0.), fC1(0.), fS2(0.), fC2(0.), fSm(0.), fCm(0.), fCdfi(0.)
1225 {
1227  SetConsDimensions(dz, rmin1, rmax1, rmin2, rmax2, phi1, phi2);
1228  ComputeBBox();
1229 }
1230 
1231 ////////////////////////////////////////////////////////////////////////////////
1232 /// Default constructor specifying minimum and maximum radius
1233 /// param[0] = dz
1234 /// param[1] = Rmin1
1235 /// param[2] = Rmax1
1236 /// param[3] = Rmin2
1237 /// param[4] = Rmax2
1238 /// param[5] = phi1
1239 /// param[6] = phi2
1240 
1242  :TGeoCone(0,0,0,0,0),
1243  fPhi1(0.), fPhi2(0.), fS1(0.), fC1(0.), fS2(0.), fC2(0.), fSm(0.), fCm(0.), fCdfi(0.)
1244 {
1246  SetDimensions(param);
1247  ComputeBBox();
1248 }
1249 
1250 ////////////////////////////////////////////////////////////////////////////////
1251 /// destructor
1252 
1254 {
1255 }
1256 
1257 ////////////////////////////////////////////////////////////////////////////////
1258 /// Function called after streaming an object of this class.
1259 
1261 {
1262  InitTrigonometry();
1263 }
1264 
1265 ////////////////////////////////////////////////////////////////////////////////
1266 /// Init frequently used trigonometric values
1267 
1269 {
1270  Double_t phi1 = fPhi1*TMath::DegToRad();
1271  Double_t phi2 = fPhi2*TMath::DegToRad();
1272  fC1 = TMath::Cos(phi1);
1273  fS1 = TMath::Sin(phi1);
1274  fC2 = TMath::Cos(phi2);
1275  fS2 = TMath::Sin(phi2);
1276  Double_t fio = 0.5*(phi1+phi2);
1277  fCm = TMath::Cos(fio);
1278  fSm = TMath::Sin(fio);
1279  Double_t dfi = 0.5*(phi2-phi1);
1280  fCdfi = TMath::Cos(dfi);
1281 }
1282 
1283 ////////////////////////////////////////////////////////////////////////////////
1284 /// Computes capacity of the shape in [length^3]
1285 
1287 {
1289 }
1290 
1291 ////////////////////////////////////////////////////////////////////////////////
1292 /// Computes capacity of the shape in [length^3]
1293 
1295 {
1296  Double_t capacity = (TMath::Abs(phi2-phi1)*TMath::DegToRad()*dz/3.)*
1297  (rmax1*rmax1+rmax2*rmax2+rmax1*rmax2-
1298  rmin1*rmin1-rmin2*rmin2-rmin1*rmin2);
1299  return capacity;
1300 }
1301 
1302 ////////////////////////////////////////////////////////////////////////////////
1303 /// compute bounding box of the tube segment
1304 
1306 {
1307  Double_t rmin, rmax;
1308  rmin = TMath::Min(fRmin1, fRmin2);
1309  rmax = TMath::Max(fRmax1, fRmax2);
1310 
1311  Double_t xc[4];
1312  Double_t yc[4];
1313  xc[0] = rmax*fC1;
1314  yc[0] = rmax*fS1;
1315  xc[1] = rmax*fC2;
1316  yc[1] = rmax*fS2;
1317  xc[2] = rmin*fC1;
1318  yc[2] = rmin*fS1;
1319  xc[3] = rmin*fC2;
1320  yc[3] = rmin*fS2;
1321 
1322  Double_t xmin = xc[TMath::LocMin(4, &xc[0])];
1323  Double_t xmax = xc[TMath::LocMax(4, &xc[0])];
1324  Double_t ymin = yc[TMath::LocMin(4, &yc[0])];
1325  Double_t ymax = yc[TMath::LocMax(4, &yc[0])];
1326 
1327  Double_t dp = fPhi2-fPhi1;
1328  Double_t ddp = -fPhi1;
1329  if (ddp<0) ddp+= 360;
1330  if (ddp<=dp) xmax = rmax;
1331  ddp = 90-fPhi1;
1332  if (ddp<0) ddp+= 360;
1333  if (ddp<=dp) ymax = rmax;
1334  ddp = 180-fPhi1;
1335  if (ddp<0) ddp+= 360;
1336  if (ddp<=dp) xmin = -rmax;
1337  ddp = 270-fPhi1;
1338  if (ddp<0) ddp+= 360;
1339  if (ddp<=dp) ymin = -rmax;
1340  fOrigin[0] = (xmax+xmin)/2;
1341  fOrigin[1] = (ymax+ymin)/2;
1342  fOrigin[2] = 0;
1343  fDX = (xmax-xmin)/2;
1344  fDY = (ymax-ymin)/2;
1345  fDZ = fDz;
1346 }
1347 
1348 ////////////////////////////////////////////////////////////////////////////////
1349 /// Compute normal to closest surface from POINT.
1350 
1352 {
1353  Double_t saf[3];
1354  Double_t ro1 = 0.5*(fRmin1+fRmin2);
1355  Double_t tg1 = 0.5*(fRmin2-fRmin1)/fDz;
1356  Double_t cr1 = 1./TMath::Sqrt(1.+tg1*tg1);
1357  Double_t ro2 = 0.5*(fRmax1+fRmax2);
1358  Double_t tg2 = 0.5*(fRmax2-fRmax1)/fDz;
1359  Double_t cr2 = 1./TMath::Sqrt(1.+tg2*tg2);
1360 
1361  Double_t r=TMath::Sqrt(point[0]*point[0]+point[1]*point[1]);
1362  Double_t rin = tg1*point[2]+ro1;
1363  Double_t rout = tg2*point[2]+ro2;
1364  saf[0] = TMath::Abs(fDz-TMath::Abs(point[2]));
1365  saf[1] = (ro1>0)?(TMath::Abs((r-rin)*cr1)):TGeoShape::Big();
1366  saf[2] = TMath::Abs((rout-r)*cr2);
1367  Int_t i = TMath::LocMin(3,saf);
1368  if (((fPhi2-fPhi1)<360.) && TGeoShape::IsCloseToPhi(saf[i], point,fC1,fS1,fC2,fS2)) {
1369  TGeoShape::NormalPhi(point,dir,norm,fC1,fS1,fC2,fS2);
1370  return;
1371  }
1372  if (i==0) {
1373  norm[0] = norm[1] = 0.;
1374  norm[2] = TMath::Sign(1.,dir[2]);
1375  return;
1376  }
1377 
1378  Double_t phi = TMath::ATan2(point[1],point[0]);
1379  Double_t cphi = TMath::Cos(phi);
1380  Double_t sphi = TMath::Sin(phi);
1381 
1382  if (i==1) {
1383  norm[0] = cr1*cphi;
1384  norm[1] = cr1*sphi;
1385  norm[2] = -tg1*cr1;
1386  } else {
1387  norm[0] = cr2*cphi;
1388  norm[1] = cr2*sphi;
1389  norm[2] = -tg2*cr2;
1390  }
1391 
1392  if (norm[0]*dir[0]+norm[1]*dir[1]+norm[2]*dir[2]<0) {
1393  norm[0] = -norm[0];
1394  norm[1] = -norm[1];
1395  norm[2] = -norm[2];
1396  }
1397 }
1398 
1399 ////////////////////////////////////////////////////////////////////////////////
1400 /// Compute normal to closest surface from POINT.
1401 
1403  Double_t dz, Double_t rmin1, Double_t rmax1, Double_t rmin2, Double_t rmax2,
1405 {
1406  Double_t saf[2];
1407  Double_t ro1 = 0.5*(rmin1+rmin2);
1408  Double_t tg1 = 0.5*(rmin2-rmin1)/dz;
1409  Double_t cr1 = 1./TMath::Sqrt(1.+tg1*tg1);
1410  Double_t ro2 = 0.5*(rmax1+rmax2);
1411  Double_t tg2 = 0.5*(rmax2-rmax1)/dz;
1412  Double_t cr2 = 1./TMath::Sqrt(1.+tg2*tg2);
1413 
1414  Double_t r=TMath::Sqrt(point[0]*point[0]+point[1]*point[1]);
1415  Double_t rin = tg1*point[2]+ro1;
1416  Double_t rout = tg2*point[2]+ro2;
1417  saf[0] = (ro1>0)?(TMath::Abs((r-rin)*cr1)):TGeoShape::Big();
1418  saf[1] = TMath::Abs((rout-r)*cr2);
1419  Int_t i = TMath::LocMin(2,saf);
1420  if (TGeoShape::IsCloseToPhi(saf[i], point,c1,s1,c2,s2)) {
1421  TGeoShape::NormalPhi(point,dir,norm,c1,s1,c2,s2);
1422  return;
1423  }
1424 
1425  Double_t phi = TMath::ATan2(point[1],point[0]);
1426  Double_t cphi = TMath::Cos(phi);
1427  Double_t sphi = TMath::Sin(phi);
1428 
1429  if (i==0) {
1430  norm[0] = cr1*cphi;
1431  norm[1] = cr1*sphi;
1432  norm[2] = -tg1*cr1;
1433  } else {
1434  norm[0] = cr2*cphi;
1435  norm[1] = cr2*sphi;
1436  norm[2] = -tg2*cr2;
1437  }
1438 
1439  if (norm[0]*dir[0]+norm[1]*dir[1]+norm[2]*dir[2]<0) {
1440  norm[0] = -norm[0];
1441  norm[1] = -norm[1];
1442  norm[2] = -norm[2];
1443  }
1444 }
1445 
1446 ////////////////////////////////////////////////////////////////////////////////
1447 /// test if point is inside this sphere
1448 
1450 {
1451  if (!TGeoCone::Contains(point)) return kFALSE;
1452  Double_t dphi = fPhi2 - fPhi1;
1453  if (dphi >= 360.) return kTRUE;
1454  Double_t phi = TMath::ATan2(point[1], point[0]) * TMath::RadToDeg();
1455  if (phi < 0 ) phi+=360.;
1456  Double_t ddp = phi-fPhi1;
1457  if (ddp < 0) ddp+=360.;
1458 // if (ddp > 360) ddp-=360;
1459  if (ddp > dphi) return kFALSE;
1460  return kTRUE;
1461 }
1462 
1463 ////////////////////////////////////////////////////////////////////////////////
1464 /// Static method to compute distance to a conical surface with :
1465 /// - r1, z1 - radius and Z position of lower base
1466 /// - r2, z2 - radius and Z position of upper base
1467 /// - phi1, phi2 - phi limits
1468 
1470 {
1471  Double_t dz = z2-z1;
1472  if (dz<=0) {
1473  return TGeoShape::Big();
1474  }
1475 
1476  Double_t dphi = phi2 - phi1;
1477  Bool_t hasphi = kTRUE;
1478  if (dphi >= 360.) hasphi=kFALSE;
1479  if (dphi < 0) dphi+=360.;
1480 // printf("phi1=%f phi2=%f dphi=%f\n", phi1, phi2, dphi);
1481 
1482  Double_t ro0 = 0.5*(r1+r2);
1483  Double_t fz = (r2-r1)/dz;
1484  Double_t r0sq = point[0]*point[0] + point[1]*point[1];
1485  Double_t rc = ro0 + fz*(point[2]-0.5*(z1+z2));
1486 
1487  Double_t a = dir[0]*dir[0] + dir[1]*dir[1] - fz*fz*dir[2]*dir[2];
1488  Double_t b = point[0]*dir[0] + point[1]*dir[1] - fz*rc*dir[2];
1489  Double_t c = r0sq - rc*rc;
1490 
1491  if (a==0) return TGeoShape::Big();
1492  a = 1./a;
1493  b *= a;
1494  c *= a;
1495  Double_t delta = b*b - c;
1496  if (delta<0) return TGeoShape::Big();
1497  delta = TMath::Sqrt(delta);
1498 
1499  Double_t snxt = -b-delta;
1500  Double_t ptnew[3];
1501  Double_t ddp, phi;
1502  if (snxt>0) {
1503  // check Z range
1504  ptnew[2] = point[2] + snxt*dir[2];
1505  if (((ptnew[2]-z1)*(ptnew[2]-z2)) < 0) {
1506  // check phi range
1507  if (!hasphi) return snxt;
1508  ptnew[0] = point[0] + snxt*dir[0];
1509  ptnew[1] = point[1] + snxt*dir[1];
1510  phi = TMath::ATan2(ptnew[1], ptnew[0]) * TMath::RadToDeg();
1511  if (phi < 0 ) phi+=360.;
1512  ddp = phi-phi1;
1513  if (ddp < 0) ddp+=360.;
1514  // printf("snxt1=%f phi=%f ddp=%f\n", snxt, phi, ddp);
1515  if (ddp<=dphi) return snxt;
1516  }
1517  }
1518  snxt = -b+delta;
1519  if (snxt>0) {
1520  // check Z range
1521  ptnew[2] = point[2] + snxt*dir[2];
1522  if (((ptnew[2]-z1)*(ptnew[2]-z2)) < 0) {
1523  // check phi range
1524  if (!hasphi) return snxt;
1525  ptnew[0] = point[0] + snxt*dir[0];
1526  ptnew[1] = point[1] + snxt*dir[1];
1527  phi = TMath::ATan2(ptnew[1], ptnew[0]) * TMath::RadToDeg();
1528  if (phi < 0 ) phi+=360.;
1529  ddp = phi-phi1;
1530  if (ddp < 0) ddp+=360.;
1531  // printf("snxt2=%f phi=%f ddp=%f\n", snxt, phi, ddp);
1532  if (ddp<=dphi) return snxt;
1533  }
1534  }
1535  return TGeoShape::Big();
1536 }
1537 
1538 ////////////////////////////////////////////////////////////////////////////////
1539 /// compute distance from inside point to surface of the tube segment
1540 
1542  Double_t rmin1, Double_t rmax1, Double_t rmin2, Double_t rmax2,
1543  Double_t c1, Double_t s1, Double_t c2, Double_t s2, Double_t cm, Double_t sm, Double_t cdfi)
1544 {
1545  if (dz<=0) return TGeoShape::Big();
1546  // Do Z
1547  Double_t scone = TGeoCone::DistFromInsideS(point,dir,dz,rmin1,rmax1,rmin2,rmax2);
1548  if (scone<=0) return 0.0;
1549  Double_t sfmin = TGeoShape::Big();
1550  Double_t rsq = point[0]*point[0]+point[1]*point[1];
1551  Double_t r = TMath::Sqrt(rsq);
1552  Double_t cpsi=point[0]*cm+point[1]*sm;
1553  if (cpsi>r*cdfi+TGeoShape::Tolerance()) {
1554  sfmin = TGeoShape::DistToPhiMin(point, dir, s1, c1, s2, c2, sm, cm);
1555  return TMath::Min(scone,sfmin);
1556  }
1557  // Point on the phi boundary or outside
1558  // which one: phi1 or phi2
1559  Double_t ddotn, xi, yi;
1560  if (TMath::Abs(point[1]-s1*r) < TMath::Abs(point[1]-s2*r)) {
1561  ddotn = s1*dir[0]-c1*dir[1];
1562  if (ddotn>=0) return 0.0;
1563  ddotn = -s2*dir[0]+c2*dir[1];
1564  if (ddotn<=0) return scone;
1565  sfmin = s2*point[0]-c2*point[1];
1566  if (sfmin<=0) return scone;
1567  sfmin /= ddotn;
1568  if (sfmin >= scone) return scone;
1569  xi = point[0]+sfmin*dir[0];
1570  yi = point[1]+sfmin*dir[1];
1571  if (yi*cm-xi*sm<0) return scone;
1572  return sfmin;
1573  }
1574  ddotn = -s2*dir[0]+c2*dir[1];
1575  if (ddotn>=0) return 0.0;
1576  ddotn = s1*dir[0]-c1*dir[1];
1577  if (ddotn<=0) return scone;
1578  sfmin = -s1*point[0]+c1*point[1];
1579  if (sfmin<=0) return scone;
1580  sfmin /= ddotn;
1581  if (sfmin >= scone) return scone;
1582  xi = point[0]+sfmin*dir[0];
1583  yi = point[1]+sfmin*dir[1];
1584  if (yi*cm-xi*sm>0) return scone;
1585  return sfmin;
1586 }
1587 
1588 ////////////////////////////////////////////////////////////////////////////////
1589 /// compute distance from inside point to surface of the tube segment
1590 
1591 Double_t TGeoConeSeg::DistFromInside(const Double_t *point, const Double_t *dir, Int_t iact, Double_t step, Double_t *safe) const
1592 {
1593  if (iact<3 && safe) {
1595  if (iact==0) return TGeoShape::Big();
1596  if ((iact==1) && (*safe>step)) return TGeoShape::Big();
1597  }
1598  if ((fPhi2-fPhi1)>=360.) return TGeoCone::DistFromInsideS(point,dir,fDz,fRmin1,fRmax1,fRmin2,fRmax2);
1599 
1600  // compute distance to surface
1602 }
1603 
1604 ////////////////////////////////////////////////////////////////////////////////
1605 /// compute distance from outside point to surface of arbitrary tube
1606 
1608  Double_t rmin1, Double_t rmax1, Double_t rmin2, Double_t rmax2,
1609  Double_t c1, Double_t s1, Double_t c2, Double_t s2, Double_t cm, Double_t sm, Double_t cdfi)
1610 {
1611  if (dz<=0) return TGeoShape::Big();
1612  Double_t r2, cpsi;
1613  // check Z planes
1614  Double_t xi, yi, zi;
1615  Double_t b,delta;
1616  zi = dz - TMath::Abs(point[2]);
1617  Double_t rin,rout;
1618  Double_t s = TGeoShape::Big();
1619  Double_t snxt=TGeoShape::Big();
1620  Bool_t in = kFALSE;
1621  Bool_t inz = (zi<0)?kFALSE:kTRUE;
1622  if (!inz) {
1623  if (point[2]*dir[2]>=0) return TGeoShape::Big();
1624  s = -zi/TMath::Abs(dir[2]);
1625  xi = point[0]+s*dir[0];
1626  yi = point[1]+s*dir[1];
1627  r2=xi*xi+yi*yi;
1628  if (dir[2]>0) {
1629  rin = rmin1;
1630  rout = rmax1;
1631  } else {
1632  rin = rmin2;
1633  rout = rmax2;
1634  }
1635  if ((rin*rin<=r2) && (r2<=rout*rout)) {
1636  cpsi=xi*cm+yi*sm;
1637  if (cpsi>=(cdfi*TMath::Sqrt(r2))) return s;
1638  }
1639  }
1640  Double_t zinv = 1./dz;
1641  Double_t rsq = point[0]*point[0]+point[1]*point[1];
1642  Double_t r = TMath::Sqrt(rsq);
1643  Double_t ro1=0.5*(rmin1+rmin2);
1644  Bool_t hasrmin = (ro1>0)?kTRUE:kFALSE;
1645  Double_t tg1 = 0.0;
1646  Bool_t inrmin = kFALSE;
1647  rin = 0.0;
1648  if (hasrmin) {
1649  tg1=0.5*(rmin2-rmin1)*zinv;
1650  rin = ro1+tg1*point[2];
1651  if (rsq > rin*(rin-TGeoShape::Tolerance())) inrmin=kTRUE;
1652  } else {
1653  inrmin = kTRUE;
1654  }
1655  Double_t ro2=0.5*(rmax1+rmax2);
1656  Double_t tg2=0.5*(rmax2-rmax1)*zinv;
1657  rout = ro2+tg2*point[2];
1658  Bool_t inrmax = kFALSE;
1659  if (r < rout+TGeoShape::Tolerance()) inrmax = kTRUE;
1660  Bool_t inphi = kFALSE;
1661  cpsi=point[0]*cm+point[1]*sm;
1662  if (cpsi>r*cdfi-TGeoShape::Tolerance()) inphi = kTRUE;
1663  in = inz & inrmin & inrmax & inphi;
1664  // If inside, we are most likely on a boundary within machine precision.
1665  if (in) {
1666  Double_t safphi = (cpsi-r*cdfi)*TMath::Sqrt(1.-cdfi*cdfi);
1667  Double_t safrmin = (hasrmin)?TMath::Abs(r-rin):(TGeoShape::Big());
1668  Double_t safrmax = TMath::Abs(r-rout);
1669  // check if on Z boundaries
1670  if (zi<safrmax && zi<safrmin && zi<safphi) {
1671  if (point[2]*dir[2]<0) return 0.0;
1672  return TGeoShape::Big();
1673  }
1674  // check if on Rmax boundary
1675  if (safrmax<safrmin && safrmax<safphi) {
1676  Double_t ddotn = point[0]*dir[0]+point[1]*dir[1]-tg2*dir[2]*r;
1677  if (ddotn<=0) return 0.0;
1678  return TGeoShape::Big();
1679  }
1680  // check if on phi boundary
1681  if (safphi<safrmin) {
1682  // We may cross again a phi of rmin boundary
1683  // check first if we are on phi1 or phi2
1684  Double_t un;
1685  if (TMath::Abs(point[1]-s1*r) < TMath::Abs(point[1]-s2*r)) {
1686  un = dir[0]*s1-dir[1]*c1;
1687  if (un < 0) return 0.0;
1688  if (cdfi>=0) return TGeoShape::Big();
1689  un = -dir[0]*s2+dir[1]*c2;
1690  if (un<0) {
1691  s = -point[0]*s2+point[1]*c2;
1692  if (s>0) {
1693  s /= (-un);
1694  zi = point[2]+s*dir[2];
1695  if (TMath::Abs(zi)<=dz) {
1696  xi = point[0]+s*dir[0];
1697  yi = point[1]+s*dir[1];
1698  if ((yi*cm-xi*sm)>0) {
1699  r2=xi*xi+yi*yi;
1700  rin = ro1+tg1*zi;
1701  rout = ro2+tg2*zi;
1702  if ((rin*rin<=r2) && (rout*rout>=r2)) return s;
1703  }
1704  }
1705  }
1706  }
1707  } else {
1708  un = -dir[0]*s2+dir[1]*c2;
1709  if (un < 0) return 0.0;
1710  if (cdfi>=0) return TGeoShape::Big();
1711  un = dir[0]*s1-dir[1]*c1;
1712  if (un<0) {
1713  s = point[0]*s1-point[1]*c1;
1714  if (s>0) {
1715  s /= (-un);
1716  zi = point[2]+s*dir[2];
1717  if (TMath::Abs(zi)<=dz) {
1718  xi = point[0]+s*dir[0];
1719  yi = point[1]+s*dir[1];
1720  if ((yi*cm-xi*sm)<0) {
1721  r2=xi*xi+yi*yi;
1722  rin = ro1+tg1*zi;
1723  rout = ro2+tg2*zi;
1724  if ((rin*rin<=r2) && (rout*rout>=r2)) return s;
1725  }
1726  }
1727  }
1728  }
1729  }
1730  // We may also cross rmin, second solution coming from outside
1731  Double_t ddotn = point[0]*dir[0]+point[1]*dir[1]-tg1*dir[2]*r;
1732  if (ddotn>=0) return TGeoShape::Big();
1733  if (cdfi>=0) return TGeoShape::Big();
1734  TGeoCone::DistToCone(point, dir, dz, rmin1, rmin2, b, delta);
1735  if (delta<0) return TGeoShape::Big();
1736  snxt = -b-delta;
1737  if (snxt<0) return TGeoShape::Big();
1738  snxt = -b+delta;
1739  zi = point[2]+snxt*dir[2];
1740  if (TMath::Abs(zi)>dz) return TGeoShape::Big();
1741  xi = point[0]+snxt*dir[0];
1742  yi = point[1]+snxt*dir[1];
1743  r2=xi*xi+yi*yi;
1744  cpsi=xi*cm+yi*sm;
1745  if (cpsi>=(cdfi*TMath::Sqrt(r2))) return snxt;
1746  return TGeoShape::Big();
1747  }
1748  // We are on rmin boundary: we may cross again rmin or a phi facette
1749  Double_t ddotn = point[0]*dir[0]+point[1]*dir[1]-tg1*dir[2]*r;
1750  if (ddotn>=0) return 0.0;
1751  TGeoCone::DistToCone(point, dir, dz, rmin1, rmin2, b, delta);
1752  if (delta<0) return 0.0;
1753  snxt = -b+delta;
1754  if (snxt<0) return TGeoShape::Big();
1755  if (TMath::Abs(-b-delta)>snxt) return TGeoShape::Big();
1756  zi = point[2]+snxt*dir[2];
1757  if (TMath::Abs(zi)>dz) return TGeoShape::Big();
1758  // OK, we cross rmin at snxt - check if within phi range
1759  xi = point[0]+snxt*dir[0];
1760  yi = point[1]+snxt*dir[1];
1761  r2=xi*xi+yi*yi;
1762  cpsi=xi*cm+yi*sm;
1763  if (cpsi>=(cdfi*TMath::Sqrt(r2))) return snxt;
1764  // we cross rmin in the phi gap - we may cross a phi facette
1765  if (cdfi>=0) return TGeoShape::Big();
1766  Double_t un=-dir[0]*s1+dir[1]*c1;
1767  if (un > 0) {
1768  s=point[0]*s1-point[1]*c1;
1769  if (s>=0) {
1770  s /= un;
1771  zi=point[2]+s*dir[2];
1772  if (TMath::Abs(zi)<=dz) {
1773  xi=point[0]+s*dir[0];
1774  yi=point[1]+s*dir[1];
1775  if ((yi*cm-xi*sm)<=0) {
1776  r2=xi*xi+yi*yi;
1777  rin = ro1+tg1*zi;
1778  rout = ro2+tg2*zi;
1779  if ((rin*rin<=r2) && (rout*rout>=r2)) return s;
1780  }
1781  }
1782  }
1783  }
1784  un=dir[0]*s2-dir[1]*c2;
1785  if (un > 0) {
1786  s=(point[1]*c2-point[0]*s2)/un;
1787  if (s>=0) {
1788  zi=point[2]+s*dir[2];
1789  if (TMath::Abs(zi)<=dz) {
1790  xi=point[0]+s*dir[0];
1791  yi=point[1]+s*dir[1];
1792  if ((yi*cm-xi*sm)>=0) {
1793  r2=xi*xi+yi*yi;
1794  rin = ro1+tg1*zi;
1795  rout = ro2+tg2*zi;
1796  if ((rin*rin<=r2) && (rout*rout>=r2)) return s;
1797  }
1798  }
1799  }
1800  }
1801  return TGeoShape::Big();
1802  }
1803 
1804  // The point is really outside
1805  Double_t sr1 = TGeoShape::Big();
1806  if (!inrmax) {
1807  // check crossing with outer cone
1808  TGeoCone::DistToCone(point, dir, dz, rmax1, rmax2, b, delta);
1809  if (delta>=0) {
1810  s = -b-delta;
1811  if (s>0) {
1812  zi=point[2]+s*dir[2];
1813  if (TMath::Abs(zi)<=dz) {
1814  xi=point[0]+s*dir[0];
1815  yi=point[1]+s*dir[1];
1816  r2=xi*xi+yi*yi;
1817  cpsi=xi*cm+yi*sm;
1818  if (cpsi>=(cdfi*TMath::Sqrt(r2))) return s; // rmax crossing
1819  }
1820  }
1821  s = -b+delta;
1822  if (s>0) {
1823  zi=point[2]+s*dir[2];
1824  if (TMath::Abs(zi)<=dz) {
1825  xi=point[0]+s*dir[0];
1826  yi=point[1]+s*dir[1];
1827  r2=xi*xi+yi*yi;
1828  cpsi=xi*cm+yi*sm;
1829  if (cpsi>=(cdfi*TMath::Sqrt(r2))) sr1=s;
1830  }
1831  }
1832  }
1833  }
1834  // check crossing with inner cone
1835  Double_t sr2 = TGeoShape::Big();
1836  TGeoCone::DistToCone(point, dir, dz, rmin1, rmin2, b, delta);
1837  if (delta>=0) {
1838  s = -b-delta;
1839  if (s>0) {
1840  zi=point[2]+s*dir[2];
1841  if (TMath::Abs(zi)<=dz) {
1842  xi=point[0]+s*dir[0];
1843  yi=point[1]+s*dir[1];
1844  r2=xi*xi+yi*yi;
1845  cpsi=xi*cm+yi*sm;
1846  if (cpsi>=(cdfi*TMath::Sqrt(r2))) sr2=s;
1847  }
1848  }
1849  if (sr2>1E10) {
1850  s = -b+delta;
1851  if (s>0) {
1852  zi=point[2]+s*dir[2];
1853  if (TMath::Abs(zi)<=dz) {
1854  xi=point[0]+s*dir[0];
1855  yi=point[1]+s*dir[1];
1856  r2=xi*xi+yi*yi;
1857  cpsi=xi*cm+yi*sm;
1858  if (cpsi>=(cdfi*TMath::Sqrt(r2))) sr2=s;
1859  }
1860  }
1861  }
1862  }
1863  snxt = TMath::Min(sr1,sr2);
1864  // Check phi crossing
1865  s = TGeoShape::DistToPhiMin(point,dir,s1,c1,s2,c2,sm,cm,kFALSE);
1866  if (s>snxt) return snxt;
1867  zi=point[2]+s*dir[2];
1868  if (TMath::Abs(zi)>dz) return snxt;
1869  xi=point[0]+s*dir[0];
1870  yi=point[1]+s*dir[1];
1871  r2=xi*xi+yi*yi;
1872  rout = ro2+tg2*zi;
1873  if (r2>rout*rout) return snxt;
1874  rin = ro1+tg1*zi;
1875  if (r2>=rin*rin) return s; // phi crossing
1876  return snxt;
1877 }
1878 
1879 ////////////////////////////////////////////////////////////////////////////////
1880 /// compute distance from outside point to surface of the tube
1881 /// compute safe radius
1882 
1883 Double_t TGeoConeSeg::DistFromOutside(const Double_t *point, const Double_t *dir, Int_t iact, Double_t step, Double_t *safe) const
1884 {
1885  if (iact<3 && safe) {
1886  *safe = Safety(point, kFALSE);
1887  if (iact==0) return TGeoShape::Big();
1888  if ((iact==1) && (*safe>step)) return TGeoShape::Big();
1889  }
1890 // Check if the bounding box is crossed within the requested distance
1891  Double_t sdist = TGeoBBox::DistFromOutside(point,dir, fDX, fDY, fDZ, fOrigin, step);
1892  if (sdist>=step) return TGeoShape::Big();
1893  if ((fPhi2-fPhi1)>=360.) return TGeoCone::DistFromOutsideS(point,dir,fDz,fRmin1,fRmax1,fRmin2,fRmax2);
1895 }
1896 
1897 ////////////////////////////////////////////////////////////////////////////////
1898 /// compute closest distance from point px,py to each corner
1899 
1901 {
1903  const Int_t numPoints = 4*n;
1904  return ShapeDistancetoPrimitive(numPoints, px, py);
1905 }
1906 
1907 ////////////////////////////////////////////////////////////////////////////////
1908 ///--- Divide this cone segment shape belonging to volume "voldiv" into ndiv volumes
1909 /// called divname, from start position with the given step. Returns pointer
1910 /// to created division cell volume in case of Z divisions. For Z division
1911 /// creates all volumes with different shapes and returns pointer to volume that
1912 /// was divided. In case a wrong division axis is supplied, returns pointer to
1913 /// volume that was divided.
1914 
1915 TGeoVolume *TGeoConeSeg::Divide(TGeoVolume *voldiv, const char *divname, Int_t iaxis, Int_t ndiv,
1916  Double_t start, Double_t step)
1917 {
1918  TGeoShape *shape; //--- shape to be created
1919  TGeoVolume *vol; //--- division volume to be created
1920  TGeoVolumeMulti *vmulti; //--- generic divided volume
1921  TGeoPatternFinder *finder; //--- finder to be attached
1922  TString opt = ""; //--- option to be attached
1923  Double_t dphi;
1924  Int_t id;
1925  Double_t end = start+ndiv*step;
1926  switch (iaxis) {
1927  case 1: //--- R division
1928  Error("Divide","division of a cone segment on R not implemented");
1929  return 0;
1930  case 2: //--- Phi division
1931  dphi = fPhi2-fPhi1;
1932  if (dphi<0) dphi+=360.;
1933  finder = new TGeoPatternCylPhi(voldiv, ndiv, start, end);
1934  voldiv->SetFinder(finder);
1935  finder->SetDivIndex(voldiv->GetNdaughters());
1936  shape = new TGeoConeSeg(fDz, fRmin1, fRmax1, fRmin2, fRmax2, -step/2, step/2);
1937  vol = new TGeoVolume(divname, shape, voldiv->GetMedium());
1938  vmulti = gGeoManager->MakeVolumeMulti(divname, voldiv->GetMedium());
1939  vmulti->AddVolume(vol);
1940  opt = "Phi";
1941  for (id=0; id<ndiv; id++) {
1942  voldiv->AddNodeOffset(vol, id, start+id*step+step/2, opt.Data());
1943  ((TGeoNodeOffset*)voldiv->GetNodes()->At(voldiv->GetNdaughters()-1))->SetFinder(finder);
1944  }
1945  return vmulti;
1946  case 3: //--- Z division
1947  finder = new TGeoPatternZ(voldiv, ndiv, start, end);
1948  vmulti = gGeoManager->MakeVolumeMulti(divname, voldiv->GetMedium());
1949  voldiv->SetFinder(finder);
1950  finder->SetDivIndex(voldiv->GetNdaughters());
1951  for (id=0; id<ndiv; id++) {
1952  Double_t z1 = start+id*step;
1953  Double_t z2 = start+(id+1)*step;
1954  Double_t rmin1n = 0.5*(fRmin1*(fDz-z1)+fRmin2*(fDz+z1))/fDz;
1955  Double_t rmax1n = 0.5*(fRmax1*(fDz-z1)+fRmax2*(fDz+z1))/fDz;
1956  Double_t rmin2n = 0.5*(fRmin1*(fDz-z2)+fRmin2*(fDz+z2))/fDz;
1957  Double_t rmax2n = 0.5*(fRmax1*(fDz-z2)+fRmax2*(fDz+z2))/fDz;
1958  shape = new TGeoConeSeg(step/2, rmin1n, rmax1n, rmin2n, rmax2n, fPhi1, fPhi2);
1959  vol = new TGeoVolume(divname, shape, voldiv->GetMedium());
1960  vmulti->AddVolume(vol);
1961  opt = "Z";
1962  voldiv->AddNodeOffset(vol, id, start+id*step+step/2, opt.Data());
1963  ((TGeoNodeOffset*)voldiv->GetNodes()->At(voldiv->GetNdaughters()-1))->SetFinder(finder);
1964  }
1965  return vmulti;
1966  default:
1967  Error("Divide", "Wrong axis type for division");
1968  return 0;
1969  }
1970 }
1971 
1972 ////////////////////////////////////////////////////////////////////////////////
1973 /// Get range of shape for a given axis.
1974 
1976 {
1977  xlo = 0;
1978  xhi = 0;
1979  Double_t dx = 0;
1980  switch (iaxis) {
1981  case 2:
1982  xlo = fPhi1;
1983  xhi = fPhi2;
1984  dx = xhi-xlo;
1985  return dx;
1986  case 3:
1987  xlo = -fDz;
1988  xhi = fDz;
1989  dx = xhi-xlo;
1990  return dx;
1991  }
1992  return dx;
1993 }
1994 
1995 ////////////////////////////////////////////////////////////////////////////////
1996 ///--- Fill vector param[4] with the bounding cylinder parameters. The order
1997 /// is the following : Rmin, Rmax, Phi1, Phi2
1998 
2000 {
2001  param[0] = TMath::Min(fRmin1, fRmin2); // Rmin
2002  param[0] *= param[0];
2003  param[1] = TMath::Max(fRmax1, fRmax2); // Rmax
2004  param[1] *= param[1];
2005  param[2] = (fPhi1<0)?(fPhi1+360.):fPhi1; // Phi1
2006  param[3] = fPhi2; // Phi2
2007  while (param[3]<param[2]) param[3]+=360.;
2008 }
2009 
2010 ////////////////////////////////////////////////////////////////////////////////
2011 /// in case shape has some negative parameters, these has to be computed
2012 /// in order to fit the mother
2013 
2015 {
2016  if (!TestShapeBit(kGeoRunTimeShape)) return 0;
2017  if (!mother->TestShapeBit(kGeoConeSeg)) {
2018  Error("GetMakeRuntimeShape", "invalid mother");
2019  return 0;
2020  }
2021  Double_t rmin1, rmax1, rmin2, rmax2, dz;
2022  rmin1 = fRmin1;
2023  rmax1 = fRmax1;
2024  rmin2 = fRmin2;
2025  rmax2 = fRmax2;
2026  dz = fDz;
2027  if (fDz<0) dz=((TGeoCone*)mother)->GetDz();
2028  if (fRmin1<0)
2029  rmin1 = ((TGeoCone*)mother)->GetRmin1();
2030  if ((fRmax1<0) || (fRmax1<fRmin1))
2031  rmax1 = ((TGeoCone*)mother)->GetRmax1();
2032  if (fRmin2<0)
2033  rmin2 = ((TGeoCone*)mother)->GetRmin2();
2034  if ((fRmax2<0) || (fRmax2<fRmin2))
2035  rmax2 = ((TGeoCone*)mother)->GetRmax2();
2036 
2037  return (new TGeoConeSeg(GetName(), dz, rmin1, rmax1, rmin2, rmax2, fPhi1, fPhi2));
2038 }
2039 
2040 ////////////////////////////////////////////////////////////////////////////////
2041 /// print shape parameters
2042 
2044 {
2045  printf("*** Shape %s: TGeoConeSeg ***\n", GetName());
2046  printf(" dz = %11.5f\n", fDz);
2047  printf(" Rmin1 = %11.5f\n", fRmin1);
2048  printf(" Rmax1 = %11.5f\n", fRmax1);
2049  printf(" Rmin2 = %11.5f\n", fRmin2);
2050  printf(" Rmax2 = %11.5f\n", fRmax2);
2051  printf(" phi1 = %11.5f\n", fPhi1);
2052  printf(" phi2 = %11.5f\n", fPhi2);
2053  printf(" Bounding box:\n");
2055 }
2056 
2057  ///////////////////////////////////////////////////////////////////////////////
2058  /// Creates a TBuffer3D describing *this* shape.
2059  /// Coordinates are in local reference frame.
2060 
2062 {
2064  Int_t nbPnts = 4*n;
2065  Int_t nbSegs = 2*nbPnts;
2066  Int_t nbPols = nbPnts-2;
2068  nbPnts, 3*nbPnts,
2069  nbSegs, 3*nbSegs,
2070  nbPols, 6*nbPols);
2071 
2072  if (buff)
2073  {
2074  SetPoints(buff->fPnts);
2075  SetSegsAndPols(*buff);
2076  }
2077 
2078  return buff;
2079 }
2080 
2081 ////////////////////////////////////////////////////////////////////////////////
2082 /// Fill TBuffer3D structure for segments and polygons.
2083 
2085 {
2086  Int_t i, j;
2088  Int_t c = GetBasicColor();
2089 
2090  memset(buffer.fSegs, 0, buffer.NbSegs()*3*sizeof(Int_t));
2091  for (i = 0; i < 4; i++) {
2092  for (j = 1; j < n; j++) {
2093  buffer.fSegs[(i*n+j-1)*3 ] = c;
2094  buffer.fSegs[(i*n+j-1)*3+1] = i*n+j-1;
2095  buffer.fSegs[(i*n+j-1)*3+2] = i*n+j;
2096  }
2097  }
2098  for (i = 4; i < 6; i++) {
2099  for (j = 0; j < n; j++) {
2100  buffer.fSegs[(i*n+j)*3 ] = c+1;
2101  buffer.fSegs[(i*n+j)*3+1] = (i-4)*n+j;
2102  buffer.fSegs[(i*n+j)*3+2] = (i-2)*n+j;
2103  }
2104  }
2105  for (i = 6; i < 8; i++) {
2106  for (j = 0; j < n; j++) {
2107  buffer.fSegs[(i*n+j)*3 ] = c;
2108  buffer.fSegs[(i*n+j)*3+1] = 2*(i-6)*n+j;
2109  buffer.fSegs[(i*n+j)*3+2] = (2*(i-6)+1)*n+j;
2110  }
2111  }
2112 
2113  Int_t indx = 0;
2114  memset(buffer.fPols, 0, buffer.NbPols()*6*sizeof(Int_t));
2115  i = 0;
2116  for (j = 0; j < n-1; j++) {
2117  buffer.fPols[indx++] = c;
2118  buffer.fPols[indx++] = 4;
2119  buffer.fPols[indx++] = (4+i)*n+j+1;
2120  buffer.fPols[indx++] = (2+i)*n+j;
2121  buffer.fPols[indx++] = (4+i)*n+j;
2122  buffer.fPols[indx++] = i*n+j;
2123  }
2124  i = 1;
2125  for (j = 0; j < n-1; j++) {
2126  buffer.fPols[indx++] = c;
2127  buffer.fPols[indx++] = 4;
2128  buffer.fPols[indx++] = i*n+j;
2129  buffer.fPols[indx++] = (4+i)*n+j;
2130  buffer.fPols[indx++] = (2+i)*n+j;
2131  buffer.fPols[indx++] = (4+i)*n+j+1;
2132  }
2133  i = 2;
2134  for (j = 0; j < n-1; j++) {
2135  buffer.fPols[indx++] = c+i;
2136  buffer.fPols[indx++] = 4;
2137  buffer.fPols[indx++] = (i-2)*2*n+j;
2138  buffer.fPols[indx++] = (4+i)*n+j;
2139  buffer.fPols[indx++] = ((i-2)*2+1)*n+j;
2140  buffer.fPols[indx++] = (4+i)*n+j+1;
2141  }
2142  i = 3;
2143  for (j = 0; j < n-1; j++) {
2144  buffer.fPols[indx++] = c+i;
2145  buffer.fPols[indx++] = 4;
2146  buffer.fPols[indx++] = (4+i)*n+j+1;
2147  buffer.fPols[indx++] = ((i-2)*2+1)*n+j;
2148  buffer.fPols[indx++] = (4+i)*n+j;
2149  buffer.fPols[indx++] = (i-2)*2*n+j;
2150  }
2151  buffer.fPols[indx++] = c+2;
2152  buffer.fPols[indx++] = 4;
2153  buffer.fPols[indx++] = 6*n;
2154  buffer.fPols[indx++] = 4*n;
2155  buffer.fPols[indx++] = 7*n;
2156  buffer.fPols[indx++] = 5*n;
2157  buffer.fPols[indx++] = c+2;
2158  buffer.fPols[indx++] = 4;
2159  buffer.fPols[indx++] = 6*n-1;
2160  buffer.fPols[indx++] = 8*n-1;
2161  buffer.fPols[indx++] = 5*n-1;
2162  buffer.fPols[indx++] = 7*n-1;
2163 }
2164 
2165 ////////////////////////////////////////////////////////////////////////////////
2166 /// computes the closest distance from given point to this shape, according
2167 /// to option. The matching point on the shape is stored in spoint.
2168 
2170 {
2171  Double_t safe = TGeoCone::Safety(point,in);
2172  if ((fPhi2-fPhi1)>=360.) return safe;
2173  Double_t safphi = TGeoShape::SafetyPhi(point, in, fPhi1, fPhi2);
2174  if (in) return TMath::Min(safe, safphi);
2175  if (safe>1.E10) return safphi;
2176  return TMath::Max(safe, safphi);
2177 }
2178 
2179 ////////////////////////////////////////////////////////////////////////////////
2180 /// Static method to compute the closest distance from given point to this shape.
2181 
2183  Double_t rmin2, Double_t rmax2, Double_t phi1, Double_t phi2, Int_t skipz)
2184 {
2185  Double_t safe = TGeoCone::SafetyS(point,in,dz,rmin1,rmax1,rmin2,rmax2,skipz);
2186  if ((phi2-phi1)>=360.) return safe;
2187  Double_t safphi = TGeoShape::SafetyPhi(point,in,phi1,phi2);
2188  if (in) return TMath::Min(safe, safphi);
2189  if (safe>1.E10) return safphi;
2190  return TMath::Max(safe, safphi);
2191 }
2192 
2193 ////////////////////////////////////////////////////////////////////////////////
2194 /// Save a primitive as a C++ statement(s) on output stream "out".
2195 
2196 void TGeoConeSeg::SavePrimitive(std::ostream &out, Option_t * /*option*/ /*= ""*/)
2197 {
2198  if (TObject::TestBit(kGeoSavePrimitive)) return;
2199  out << " // Shape: " << GetName() << " type: " << ClassName() << std::endl;
2200  out << " dz = " << fDz << ";" << std::endl;
2201  out << " rmin1 = " << fRmin1 << ";" << std::endl;
2202  out << " rmax1 = " << fRmax1 << ";" << std::endl;
2203  out << " rmin2 = " << fRmin2 << ";" << std::endl;
2204  out << " rmax2 = " << fRmax2 << ";" << std::endl;
2205  out << " phi1 = " << fPhi1 << ";" << std::endl;
2206  out << " phi2 = " << fPhi2 << ";" << std::endl;
2207  out << " TGeoShape *" << GetPointerName() << " = new TGeoConeSeg(\"" << GetName() << "\", dz,rmin1,rmax1,rmin2,rmax2,phi1,phi2);" << std::endl;
2209 }
2210 
2211 ////////////////////////////////////////////////////////////////////////////////
2212 /// Set dimensions of the cone segment.
2213 
2215  Double_t rmin2, Double_t rmax2, Double_t phi1, Double_t phi2)
2216 {
2217  fDz = dz;
2218  fRmin1 = rmin1;
2219  fRmax1 = rmax1;
2220  fRmin2 = rmin2;
2221  fRmax2 = rmax2;
2222  fPhi1 = phi1;
2223  while (fPhi1<0) fPhi1+=360.;
2224  fPhi2 = phi2;
2225  while (fPhi2<=fPhi1) fPhi2+=360.;
2226  if (TGeoShape::IsSameWithinTolerance(fPhi1,fPhi2)) Fatal("SetConsDimensions", "In shape %s invalid phi1=%g, phi2=%g\n", GetName(), fPhi1, fPhi2);
2227  InitTrigonometry();
2228 }
2229 
2230 ////////////////////////////////////////////////////////////////////////////////
2231 /// Set dimensions of the cone segment from an array.
2232 
2234 {
2235  Double_t dz = param[0];
2236  Double_t rmin1 = param[1];
2237  Double_t rmax1 = param[2];
2238  Double_t rmin2 = param[3];
2239  Double_t rmax2 = param[4];
2240  Double_t phi1 = param[5];
2241  Double_t phi2 = param[6];
2242  SetConsDimensions(dz, rmin1, rmax1,rmin2, rmax2, phi1, phi2);
2243 }
2244 
2245 ////////////////////////////////////////////////////////////////////////////////
2246 /// Create cone segment mesh points.
2247 
2249 {
2250  Int_t j, n;
2251  Float_t dphi,phi,phi1, phi2,dz;
2252 
2253  n = gGeoManager->GetNsegments()+1;
2254  dz = fDz;
2255  phi1 = fPhi1;
2256  phi2 = fPhi2;
2257 
2258  dphi = (phi2-phi1)/(n-1);
2259 
2260  Int_t indx = 0;
2261 
2262  if (points) {
2263  for (j = 0; j < n; j++) {
2264  phi = (fPhi1+j*dphi)*TMath::DegToRad();
2265  points[indx++] = fRmin1 * TMath::Cos(phi);
2266  points[indx++] = fRmin1 * TMath::Sin(phi);
2267  points[indx++] = -dz;
2268  }
2269  for (j = 0; j < n; j++) {
2270  phi = (fPhi1+j*dphi)*TMath::DegToRad();
2271  points[indx++] = fRmax1 * TMath::Cos(phi);
2272  points[indx++] = fRmax1 * TMath::Sin(phi);
2273  points[indx++] = -dz;
2274  }
2275  for (j = 0; j < n; j++) {
2276  phi = (fPhi1+j*dphi)*TMath::DegToRad();
2277  points[indx++] = fRmin2 * TMath::Cos(phi);
2278  points[indx++] = fRmin2 * TMath::Sin(phi);
2279  points[indx++] = dz;
2280  }
2281  for (j = 0; j < n; j++) {
2282  phi = (fPhi1+j*dphi)*TMath::DegToRad();
2283  points[indx++] = fRmax2 * TMath::Cos(phi);
2284  points[indx++] = fRmax2 * TMath::Sin(phi);
2285  points[indx++] = dz;
2286  }
2287  }
2288 }
2289 
2290 ////////////////////////////////////////////////////////////////////////////////
2291 /// Create cone segment mesh points.
2292 
2294 {
2295  Int_t j, n;
2296  Float_t dphi,phi,phi1, phi2,dz;
2297 
2298  n = gGeoManager->GetNsegments()+1;
2299  dz = fDz;
2300  phi1 = fPhi1;
2301  phi2 = fPhi2;
2302 
2303  dphi = (phi2-phi1)/(n-1);
2304 
2305  Int_t indx = 0;
2306 
2307  if (points) {
2308  for (j = 0; j < n; j++) {
2309  phi = (fPhi1+j*dphi)*TMath::DegToRad();
2310  points[indx++] = fRmin1 * TMath::Cos(phi);
2311  points[indx++] = fRmin1 * TMath::Sin(phi);
2312  points[indx++] = -dz;
2313  }
2314  for (j = 0; j < n; j++) {
2315  phi = (fPhi1+j*dphi)*TMath::DegToRad();
2316  points[indx++] = fRmax1 * TMath::Cos(phi);
2317  points[indx++] = fRmax1 * TMath::Sin(phi);
2318  points[indx++] = -dz;
2319  }
2320  for (j = 0; j < n; j++) {
2321  phi = (fPhi1+j*dphi)*TMath::DegToRad();
2322  points[indx++] = fRmin2 * TMath::Cos(phi);
2323  points[indx++] = fRmin2 * TMath::Sin(phi);
2324  points[indx++] = dz;
2325  }
2326  for (j = 0; j < n; j++) {
2327  phi = (fPhi1+j*dphi)*TMath::DegToRad();
2328  points[indx++] = fRmax2 * TMath::Cos(phi);
2329  points[indx++] = fRmax2 * TMath::Sin(phi);
2330  points[indx++] = dz;
2331  }
2332  }
2333 }
2334 
2335 ////////////////////////////////////////////////////////////////////////////////
2336 /// Returns numbers of vertices, segments and polygons composing the shape mesh.
2337 
2338 void TGeoConeSeg::GetMeshNumbers(Int_t &nvert, Int_t &nsegs, Int_t &npols) const
2339 {
2341  nvert = n*4;
2342  nsegs = n*8;
2343  npols = n*4-2;
2344 }
2345 
2346 ////////////////////////////////////////////////////////////////////////////////
2347 /// Return number of vertices of the mesh representation
2348 
2350 {
2352  Int_t numPoints = n*4;
2353  return numPoints;
2354 }
2355 
2356 ////////////////////////////////////////////////////////////////////////////////
2357 ////// fill size of this 3-D object
2358 //// TVirtualGeoPainter *painter = gGeoManager->GetGeomPainter();
2359 //// if (!painter) return;
2360 ////
2361 //// Int_t n = gGeoManager->GetNsegments()+1;
2362 ////
2363 //// Int_t numPoints = n*4;
2364 //// Int_t numSegs = n*8;
2365 //// Int_t numPolys = n*4-2;
2366 //// painter->AddSize3D(numPoints, numSegs, numPolys);
2367 
2369 {
2370 }
2371 
2372 ////////////////////////////////////////////////////////////////////////////////
2373 /// Fills a static 3D buffer and returns a reference.
2374 
2375 const TBuffer3D & TGeoConeSeg::GetBuffer3D(Int_t reqSections, Bool_t localFrame) const
2376 {
2377  static TBuffer3D buffer(TBuffer3DTypes::kGeneric);
2378 
2379  TGeoBBox::FillBuffer3D(buffer, reqSections, localFrame);
2380 
2381  if (reqSections & TBuffer3D::kRawSizes) {
2383  Int_t nbPnts = 4*n;
2384  Int_t nbSegs = 2*nbPnts;
2385  Int_t nbPols = nbPnts-2;
2386  if (buffer.SetRawSizes(nbPnts, 3*nbPnts, nbSegs, 3*nbSegs, nbPols, 6*nbPols)) {
2387  buffer.SetSectionsValid(TBuffer3D::kRawSizes);
2388  }
2389  }
2390  if ((reqSections & TBuffer3D::kRaw) && buffer.SectionsValid(TBuffer3D::kRawSizes)) {
2391  SetPoints(buffer.fPnts);
2392  if (!buffer.fLocalFrame) {
2393  TransformPoints(buffer.fPnts, buffer.NbPnts());
2394  }
2395 
2396  SetSegsAndPols(buffer);
2397  buffer.SetSectionsValid(TBuffer3D::kRaw);
2398  }
2399 
2400  return buffer;
2401 }
2402 
2403 ////////////////////////////////////////////////////////////////////////////////
2404 /// Fills array with n random points located on the line segments of the shape mesh.
2405 /// The output array must be provided with a length of minimum 3*npoints. Returns
2406 /// true if operation is implemented.
2407 
2409 {
2410  if (npoints > (npoints/2)*2) {
2411  Error("GetPointsOnSegments","Npoints must be even number");
2412  return kFALSE;
2413  }
2414  Int_t nc = (Int_t)TMath::Sqrt(0.5*npoints);
2415  Double_t dphi = (fPhi2-fPhi1)*TMath::DegToRad()/(nc-1);
2416  Double_t phi = 0;
2417  Double_t phi1 = fPhi1 * TMath::DegToRad();
2418  Int_t ntop = npoints/2 - nc*(nc-1);
2419  Double_t dz = 2*fDz/(nc-1);
2420  Double_t z = 0;
2421  Double_t rmin = 0.;
2422  Double_t rmax = 0.;
2423  Int_t icrt = 0;
2424  Int_t nphi = nc;
2425  // loop z sections
2426  for (Int_t i=0; i<nc; i++) {
2427  if (i == (nc-1)) {
2428  nphi = ntop;
2429  dphi = (fPhi2-fPhi1)*TMath::DegToRad()/(nphi-1);
2430  }
2431  z = -fDz + i*dz;
2432  rmin = 0.5*(fRmin1+fRmin2) + 0.5*(fRmin2-fRmin1)*z/fDz;
2433  rmax = 0.5*(fRmax1+fRmax2) + 0.5*(fRmax2-fRmax1)*z/fDz;
2434  // loop points on circle sections
2435  for (Int_t j=0; j<nphi; j++) {
2436  phi = phi1 + j*dphi;
2437  array[icrt++] = rmin * TMath::Cos(phi);
2438  array[icrt++] = rmin * TMath::Sin(phi);
2439  array[icrt++] = z;
2440  array[icrt++] = rmax * TMath::Cos(phi);
2441  array[icrt++] = rmax * TMath::Sin(phi);
2442  array[icrt++] = z;
2443  }
2444  }
2445  return kTRUE;
2446 }
2447 
2448 ////////////////////////////////////////////////////////////////////////////////
2449 /// Check the inside status for each of the points in the array.
2450 /// Input: Array of point coordinates + vector size
2451 /// Output: Array of Booleans for the inside of each point
2452 
2453 void TGeoConeSeg::Contains_v(const Double_t *points, Bool_t *inside, Int_t vecsize) const
2454 {
2455  for (Int_t i=0; i<vecsize; i++) inside[i] = Contains(&points[3*i]);
2456 }
2457 
2458 ////////////////////////////////////////////////////////////////////////////////
2459 /// Compute the normal for an array o points so that norm.dot.dir is positive
2460 /// Input: Arrays of point coordinates and directions + vector size
2461 /// Output: Array of normal directions
2462 
2463 void TGeoConeSeg::ComputeNormal_v(const Double_t *points, const Double_t *dirs, Double_t *norms, Int_t vecsize)
2464 {
2465  for (Int_t i=0; i<vecsize; i++) ComputeNormal(&points[3*i], &dirs[3*i], &norms[3*i]);
2466 }
2467 
2468 ////////////////////////////////////////////////////////////////////////////////
2469 /// Compute distance from array of input points having directions specisied by dirs. Store output in dists
2470 
2471 void TGeoConeSeg::DistFromInside_v(const Double_t *points, const Double_t *dirs, Double_t *dists, Int_t vecsize, Double_t* step) const
2472 {
2473  for (Int_t i=0; i<vecsize; i++) dists[i] = DistFromInside(&points[3*i], &dirs[3*i], 3, step[i]);
2474 }
2475 
2476 ////////////////////////////////////////////////////////////////////////////////
2477 /// Compute distance from array of input points having directions specisied by dirs. Store output in dists
2478 
2479 void TGeoConeSeg::DistFromOutside_v(const Double_t *points, const Double_t *dirs, Double_t *dists, Int_t vecsize, Double_t* step) const
2480 {
2481  for (Int_t i=0; i<vecsize; i++) dists[i] = DistFromOutside(&points[3*i], &dirs[3*i], 3, step[i]);
2482 }
2483 
2484 ////////////////////////////////////////////////////////////////////////////////
2485 /// Compute safe distance from each of the points in the input array.
2486 /// Input: Array of point coordinates, array of statuses for these points, size of the arrays
2487 /// Output: Safety values
2488 
2489 void TGeoConeSeg::Safety_v(const Double_t *points, const Bool_t *inside, Double_t *safe, Int_t vecsize) const
2490 {
2491  for (Int_t i=0; i<vecsize; i++) safe[i] = Safety(&points[3*i], inside[i]);
2492 }
TGeoVolumeMulti * MakeVolumeMulti(const char *name, TGeoMedium *medium)
Make a TGeoVolumeMulti handling a list of volumes.
virtual ~TGeoConeSeg()
destructor
Definition: TGeoCone.cxx:1253
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:1108
float xmin
Definition: THbookFile.cxx:93
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:1607
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:992
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
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:1305
Int_t GetBasicColor() const
Get the basic color (0-7).
Definition: TGeoShape.cxx:671
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:1176
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:1915
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:2248
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:1186
Double_t fRmax1
Definition: TGeoCone.h:37
virtual void InspectShape() const
print shape parameters
Definition: TGeoCone.cxx:2043
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:2338
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:979
Double_t fPhi1
Definition: TGeoCone.h:125
void InitTrigonometry()
cos(0.5*(phi1-phi2))
Definition: TGeoCone.cxx:1268
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:1160
static Double_t SafetyS(const Double_t *point, Bool_t in, Double_t dz, Double_t rmin1, Double_t rmax1, Double_t rmin2, Double_t rmax2, Double_t phi1, Double_t phi2, Int_t skipz=0)
Static method to compute the closest distance from given point to this shape.
Definition: TGeoCone.cxx:2182
Double_t fDZ
Definition: TGeoBBox.h:35
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:2471
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:2408
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:1883
virtual void AfterStreamer()
Function called after streaming an object of this class.
Definition: TGeoCone.cxx:1260
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:1150
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:909
virtual TBuffer3D * MakeBuffer3D() const
Creates a TBuffer3D describing this shape.
Definition: TGeoCone.cxx:2061
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:550
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:2233
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:2349
virtual Double_t Capacity() const
Computes capacity of the shape in [length^3].
Definition: TGeoCone.cxx:1286
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:1080
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:2368
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:2479
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:1975
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:1115
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:2453
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:1469
Double_t Pi()
Definition: TMath.h:44
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:1351
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
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:2196
ClassImp(TMCParticle) void TMCParticle printf(": p=(%7.3f,%7.3f,%9.3f) ;", fPx, fPy, fPz)
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:1900
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:1999
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:2489
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:2014
const char * GetPointerName() const
Provide a pointer name containing uid.
Definition: TGeoShape.cxx:697
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:1402
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:2463
static Double_t DistFromInsideS(const Double_t *point, const Double_t *dir, Double_t dz, Double_t rmin1, Double_t rmax1, Double_t rmin2, Double_t rmax2, Double_t c1, Double_t s1, Double_t c2, Double_t s2, Double_t cm, Double_t sm, Double_t cdfi)
compute distance from inside point to surface of the tube segment
Definition: TGeoCone.cxx:1541
#define name(a, b)
Definition: linkTestLib0.cpp:5
virtual ~TGeoCone()
destructor
Definition: TGeoCone.cxx:158
void SetShapeBit(UInt_t f, Bool_t set)
Equivalent of TObject::SetBit.
Definition: TGeoShape.cxx:522
void SetConeDimensions(Double_t dz, Double_t rmin1, Double_t rmax1, Double_t rmin2, Double_t rmax2)
Set cone dimensions.
Definition: TGeoCone.cxx:925
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:2214
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:1449
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:1091
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:2375
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:2169
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:1591
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:1168
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:2084
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition: TObject.cxx:904