ROOT  6.07/01
Reference Guide
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
TGeoArb8.cxx
Go to the documentation of this file.
1 // @(#)root/geom:$Id$
2 // Author: Andrei Gheata 31/01/02
3 
4 /*************************************************************************
5  * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. *
6  * All rights reserved. *
7  * *
8  * For the licensing terms see $ROOTSYS/LICENSE. *
9  * For the list of contributors see $ROOTSYS/README/CREDITS. *
10  *************************************************************************/
11 
12 #include "TGeoArb8.h"
13 
14 #include "Riostream.h"
15 #include "TBuffer.h"
16 #include "TGeoManager.h"
17 #include "TGeoVolume.h"
18 #include "TGeoMatrix.h"
19 #include "TMath.h"
20 
22 
23 //________________________________________________________________________
24 // TGeoArb8 - a arbitrary trapezoid with less than 8 vertices standing on
25 // two paralel planes perpendicular to Z axis. Parameters :
26 // - dz - half length in Z;
27 // - xy[8][2] - vector of (x,y) coordinates of vertices
28 // - first four points (xy[i][j], i<4, j<2) are the (x,y)
29 // coordinates of the vertices sitting on the -dz plane;
30 // - last four points (xy[i][j], i>=4, j<2) are the (x,y)
31 // coordinates of the vertices sitting on the +dz plane;
32 // The order of defining the vertices of an arb8 is the following :
33 // - point 0 is connected with points 1,3,4
34 // - point 1 is connected with points 0,2,5
35 // - point 2 is connected with points 1,3,6
36 // - point 3 is connected with points 0,2,7
37 // - point 4 is connected with points 0,5,7
38 // - point 5 is connected with points 1,4,6
39 // - point 6 is connected with points 2,5,7
40 // - point 7 is connected with points 3,4,6
41 // Points can be identical in order to create shapes with less than
42 // 8 vertices.
43 //
44 
45 //Begin_Html
46 /*
47 <img src="gif/t_arb8.gif">
48 */
49 //End_Html
50 
51 ////////////////////////////////////////////////////////////////////////////
52 // //
53 // TGeoTrap //
54 // //
55 // TRAP is a general trapezoid, i.e. one for which the faces perpendicular//
56 // to z are trapezia and their centres are not the same x, y. It has 11 //
57 // parameters: the half length in z, the polar angles from the centre of //
58 // the face at low z to that at high z, H1 the half length in y at low z, //
59 // LB1 the half length in x at low z and y low edge, LB2 the half length //
60 // in x at low z and y high edge, TH1 the angle w.r.t. the y axis from the//
61 // centre of low y edge to the centre of the high y edge, and H2, LB2, //
62 // LH2, TH2, the corresponding quantities at high z. //
63 // //
64 ////////////////////////////////////////////////////////////////////////////
65 //Begin_Html
66 /*
67 <img src="gif/t_trap.gif">
68 */
69 //End_Html
70 //
71 //Begin_Html
72 /*
73 <img src="gif/t_trapdivZ.gif">
74 */
75 //End_Html
76 
77 ////////////////////////////////////////////////////////////////////////////
78 // //
79 // TGeoGtra //
80 // //
81 // Gtra is a twisted trapezoid, i.e. one for which the faces perpendicular//
82 // to z are trapezia and their centres are not the same x, y. It has 12 //
83 // parameters: the half length in z, the polar angles from the centre of //
84 // the face at low z to that at high z, twist, H1 the half length in y at low z, //
85 // LB1 the half length in x at low z and y low edge, LB2 the half length //
86 // in x at low z and y high edge, TH1 the angle w.r.t. the y axis from the//
87 // centre of low y edge to the centre of the high y edge, and H2, LB2, //
88 // LH2, TH2, the corresponding quantities at high z. //
89 // //
90 ////////////////////////////////////////////////////////////////////////////
91 //Begin_Html
92 /*
93 <img src="gif/t_gtra.gif">
94 */
95 //End_Html
96 //
97 //Begin_Html
98 /*
99 <img src="gif/t_gtradivstepZ.gif">
100 */
101 //End_Html
102 
103 
104 ////////////////////////////////////////////////////////////////////////////////
105 /// Default ctor.
106 
108 {
109  fDz = 0;
110  fTwist = 0;
111  for (Int_t i=0; i<8; i++) {
112  fXY[i][0] = 0.0;
113  fXY[i][1] = 0.0;
114  }
115  SetShapeBit(kGeoArb8);
116 }
117 
118 ////////////////////////////////////////////////////////////////////////////////
119 /// Constructor. If the array of vertices is not null, this should be
120 /// in the format : (x0, y0, x1, y1, ... , x7, y7)
121 
123  :TGeoBBox(0,0,0)
124 {
125  fDz = dz;
126  fTwist = 0;
128  if (vertices) {
129  for (Int_t i=0; i<8; i++) {
130  fXY[i][0] = vertices[2*i];
131  fXY[i][1] = vertices[2*i+1];
132  }
133  ComputeTwist();
134  ComputeBBox();
135  } else {
136  for (Int_t i=0; i<8; i++) {
137  fXY[i][0] = 0.0;
138  fXY[i][1] = 0.0;
139  }
140  }
141 }
142 
143 ////////////////////////////////////////////////////////////////////////////////
144 /// Named constructor. If the array of vertices is not null, this should be
145 /// in the format : (x0, y0, x1, y1, ... , x7, y7)
146 
147 TGeoArb8::TGeoArb8(const char *name, Double_t dz, Double_t *vertices)
148  :TGeoBBox(name, 0,0,0)
149 {
150  fDz = dz;
151  fTwist = 0;
153  if (vertices) {
154  for (Int_t i=0; i<8; i++) {
155  fXY[i][0] = vertices[2*i];
156  fXY[i][1] = vertices[2*i+1];
157  }
158  ComputeTwist();
159  ComputeBBox();
160  } else {
161  for (Int_t i=0; i<8; i++) {
162  fXY[i][0] = 0.0;
163  fXY[i][1] = 0.0;
164  }
165  }
166 }
167 
168 ////////////////////////////////////////////////////////////////////////////////
169 ///copy constructor
170 
172  TGeoBBox(ga8),
173  fDz(ga8.fDz),
174  fTwist(ga8.fTwist)
175 {
176  for(Int_t i=0; i<8; i++) {
177  fXY[i][0]=ga8.fXY[i][0];
178  fXY[i][1]=ga8.fXY[i][1];
179  }
180 }
181 
182 ////////////////////////////////////////////////////////////////////////////////
183 ///assignment operator
184 
186 {
187  if(this!=&ga8) {
188  TGeoBBox::operator=(ga8);
189  fDz=ga8.fDz;
190  fTwist=ga8.fTwist;
191  for(Int_t i=0; i<8; i++) {
192  fXY[i][0]=ga8.fXY[i][0];
193  fXY[i][1]=ga8.fXY[i][1];
194  }
195  }
196  return *this;
197 }
198 
199 ////////////////////////////////////////////////////////////////////////////////
200 /// Destructor.
201 
203 {
204  if (fTwist) delete [] fTwist;
205 }
206 
207 ////////////////////////////////////////////////////////////////////////////////
208 /// Computes capacity of the shape in [length^3].
209 
211 {
212  Int_t i,j;
213  Double_t capacity = 0;
214  for (i=0; i<4; i++) {
215  j = (i+1)%4;
216  capacity += 0.25*fDz*((fXY[i][0]+fXY[i+4][0])*(fXY[j][1]+fXY[j+4][1]) -
217  (fXY[j][0]+fXY[j+4][0])*(fXY[i][1]+fXY[i+4][1]) +
218  (1./3)*((fXY[i+4][0]-fXY[i][0])*(fXY[j+4][1]-fXY[j][1]) -
219  (fXY[j][0]-fXY[j+4][0])*(fXY[i][1]-fXY[i+4][1])));
220  }
221  return TMath::Abs(capacity);
222 }
223 
224 ////////////////////////////////////////////////////////////////////////////////
225 /// Computes bounding box for an Arb8 shape.
226 
228 {
230  xmin = xmax = fXY[0][0];
231  ymin = ymax = fXY[0][1];
232 
233  for (Int_t i=1; i<8; i++) {
234  if (xmin>fXY[i][0]) xmin=fXY[i][0];
235  if (xmax<fXY[i][0]) xmax=fXY[i][0];
236  if (ymin>fXY[i][1]) ymin=fXY[i][1];
237  if (ymax<fXY[i][1]) ymax=fXY[i][1];
238  }
239  fDX = 0.5*(xmax-xmin);
240  fDY = 0.5*(ymax-ymin);
241  fDZ = fDz;
242  fOrigin[0] = 0.5*(xmax+xmin);
243  fOrigin[1] = 0.5*(ymax+ymin);
244  fOrigin[2] = 0;
246 }
247 
248 ////////////////////////////////////////////////////////////////////////////////
249 /// Computes tangents of twist angles (angles between projections on XY plane
250 /// of corresponding -dz +dz edges). Computes also if the vertices are defined
251 /// clockwise or anti-clockwise.
252 
254 {
255  Double_t twist[4];
256  Bool_t twisted = kFALSE;
257  Double_t dx1, dy1, dx2, dy2;
258  Bool_t singleBottom = kTRUE;
259  Bool_t singleTop = kTRUE;
260  Int_t i;
261  for (i=0; i<4; i++) {
262  dx1 = fXY[(i+1)%4][0]-fXY[i][0];
263  dy1 = fXY[(i+1)%4][1]-fXY[i][1];
265  twist[i] = 0;
266  continue;
267  }
268  singleBottom = kFALSE;
269  dx2 = fXY[4+(i+1)%4][0]-fXY[4+i][0];
270  dy2 = fXY[4+(i+1)%4][1]-fXY[4+i][1];
272  twist[i] = 0;
273  continue;
274  }
275  singleTop = kFALSE;
276  twist[i] = dy1*dx2 - dx1*dy2;
277  if (TMath::Abs(twist[i])<TGeoShape::Tolerance()) {
278  twist[i] = 0;
279  continue;
280  }
281  twist[i] = TMath::Sign(1.,twist[i]);
282  twisted = kTRUE;
283  }
284  if (twisted) {
285  if (fTwist) delete [] fTwist;
286  fTwist = new Double_t[4];
287  memcpy(fTwist, &twist[0], 4*sizeof(Double_t));
288  }
289  if (singleBottom) {
290  for (i=0; i<4; i++) {
291  fXY[i][0] += 1.E-8*fXY[i+4][0];
292  fXY[i][1] += 1.E-8*fXY[i+4][1];
293  }
294  }
295  if (singleTop) {
296  for (i=0; i<4; i++) {
297  fXY[i+4][0] += 1.E-8*fXY[i][0];
298  fXY[i+4][1] += 1.E-8*fXY[i][1];
299  }
300  }
301  Double_t sum1 = 0.;
302  Double_t sum2 = 0.;
303  Int_t j;
304  for (i=0; i<4; i++) {
305  j = (i+1)%4;
306  sum1 += fXY[i][0]*fXY[j][1]-fXY[j][0]*fXY[i][1];
307  sum2 += fXY[i+4][0]*fXY[j+4][1]-fXY[j+4][0]*fXY[i+4][1];
308  }
309  if (sum1*sum2 < -TGeoShape::Tolerance()) {
310  Fatal("ComputeTwist", "Shape %s type Arb8: Lower/upper faces defined with opposite clockwise", GetName());
311  return;
312  }
313  if (sum1>TGeoShape::Tolerance()) {
314  Error("ComputeTwist", "Shape %s type Arb8: Vertices must be defined clockwise in XY planes. Re-ordering...", GetName());
315  Double_t xtemp, ytemp;
316  xtemp = fXY[1][0];
317  ytemp = fXY[1][1];
318  fXY[1][0] = fXY[3][0];
319  fXY[1][1] = fXY[3][1];
320  fXY[3][0] = xtemp;
321  fXY[3][1] = ytemp;
322  xtemp = fXY[5][0];
323  ytemp = fXY[5][1];
324  fXY[5][0] = fXY[7][0];
325  fXY[5][1] = fXY[7][1];
326  fXY[7][0] = xtemp;
327  fXY[7][1] = ytemp;
328  }
329  // Check for illegal crossings.
330  Bool_t illegal_cross = kFALSE;
331  illegal_cross = TGeoShape::IsSegCrossing(fXY[0][0],fXY[0][1],fXY[1][0],fXY[1][1],
332  fXY[2][0],fXY[2][1],fXY[3][0],fXY[3][1]);
333  if (!illegal_cross)
334  illegal_cross = TGeoShape::IsSegCrossing(fXY[4][0],fXY[4][1],fXY[5][0],fXY[5][1],
335  fXY[6][0],fXY[6][1],fXY[7][0],fXY[7][1]);
336  if (illegal_cross) {
337  Error("ComputeTwist", "Shape %s type Arb8: Malformed polygon with crossing opposite segments", GetName());
338  InspectShape();
339  }
340 }
341 
342 ////////////////////////////////////////////////////////////////////////////////
343 /// Get twist for segment I in range [0,3]
344 
346 {
347  if (!fTwist) return 0.;
348  if (iseg<0 || iseg>3) return 0.;
349  return fTwist[iseg];
350 }
351 
352 ////////////////////////////////////////////////////////////////////////////////
353 /// Get index of the edge of the quadrilater represented by vert closest to point.
354 /// If [P1,P2] is the closest segment and P is the point, the function returns the fraction of the
355 /// projection of (P1P) over (P1P2). If projection of P is not in range [P1,P2] return -1.
356 
357 Double_t TGeoArb8::GetClosestEdge(const Double_t *point, Double_t *vert, Int_t &isegment) const
358 {
359  isegment = 0;
360  Int_t isegmin = 0;
361  Int_t i1, i2;
362  Double_t p1[2], p2[2];
363  Double_t lsq, ssq, dx, dy, dpx, dpy, u;
364  Double_t umin = -1.;
365  Double_t safe=1E30;
366  for (i1=0; i1<4; i1++) {
367  if (TGeoShape::IsSameWithinTolerance(safe,0)) {
368  isegment = isegmin;
369  return umin;
370  }
371  i2 = (i1+1)%4;
372  p1[0] = vert[2*i1];
373  p1[1] = vert[2*i1+1];
374  p2[0] = vert[2*i2];
375  p2[1] = vert[2*i2+1];
376  dx = p2[0] - p1[0];
377  dy = p2[1] - p1[1];
378  dpx = point[0] - p1[0];
379  dpy = point[1] - p1[1];
380  lsq = dx*dx + dy*dy;
381  // Current segment collapsed to a point
383  ssq = dpx*dpx + dpy*dpy;
384  if (ssq < safe) {
385  safe = ssq;
386  isegmin = i1;
387  umin = -1;
388  }
389  continue;
390  }
391  // Projection fraction
392  u = (dpx*dx + dpy*dy)/lsq;
393  // If projection of P is outside P1P2 limits, take the distance from P to the closest of P1 and P2
394  if (u>1) {
395  // Outside, closer to P2
396  dpx = point[0]-p2[0];
397  dpy = point[1]-p2[1];
398  u = -1.;
399  } else {
400  if (u>=0) {
401  // Projection inside
402  dpx -= u*dx;
403  dpy -= u*dy;
404  } else {
405  // Outside, closer to P1
406  u = -1.;
407  }
408  }
409  ssq = dpx*dpx + dpy*dpy;
410  if (ssq < safe) {
411  safe = ssq;
412  isegmin = i1;
413  umin = u;
414  }
415  }
416  isegment = isegmin;
417 // safe = TMath::Sqrt(safe);
418  return umin;
419 }
420 
421 ////////////////////////////////////////////////////////////////////////////////
422 /// Compute normal to closest surface from POINT.
423 
425 {
426  Double_t safc;
427  Double_t x0, y0, z0, x1, y1, z1, x2, y2, z2;
428  Double_t ax, ay, az, bx, by, bz;
429  Double_t fn;
430  safc = fDz-TMath::Abs(point[2]);
431  if (safc<10.*TGeoShape::Tolerance()) {
432  memset(norm,0,3*sizeof(Double_t));
433  norm[2] = (dir[2]>0)?1:(-1);
434  return;
435  }
436  Double_t vert[8];
437  SetPlaneVertices(point[2], vert);
438  // Get the closest edge (point should be on this edge within tolerance)
439  Int_t iseg;
440  Double_t frac = GetClosestEdge(point, vert, iseg);
441  if (frac<0) frac = 0.;
442  Int_t jseg = (iseg+1)%4;
443  x0 = vert[2*iseg];
444  y0 = vert[2*iseg+1];
445  z0 = point[2];
446  x2 = vert[2*jseg];
447  y2 = vert[2*jseg+1];
448  z2 = point[2];
449  x0 += frac*(x2-x0);
450  y0 += frac*(y2-y0);
451  x1 = fXY[iseg+4][0];
452  y1 = fXY[iseg+4][1];
453  z1 = fDz;
454  x1 += frac*(fXY[jseg+4][0]-x1);
455  y1 += frac*(fXY[jseg+4][1]-y1);
456  ax = x1-x0;
457  ay = y1-y0;
458  az = z1-z0;
459  bx = x2-x0;
460  by = y2-y0;
461  bz = z2-z0;
462  // Cross product of the vector given by the section segment (that contains the point) at z=point[2]
463  // and the vector connecting the point projection to its correspondent on the top edge (hard to swallow, isn't it?)
464  norm[0] = ay*bz-az*by;
465  norm[1] = az*bx-ax*bz;
466  norm[2] = ax*by-ay*bx;
467  fn = TMath::Sqrt(norm[0]*norm[0]+norm[1]*norm[1]+norm[2]*norm[2]);
468  // If point is on one edge, fn may be very small and the normal does not make sense - avoid divzero
469  if (fn<1E-10) {
470  norm[0] = 1.;
471  norm[1] = 0.;
472  norm[2] = 0.;
473  } else {
474  norm[0] /= fn;
475  norm[1] /= fn;
476  norm[2] /= fn;
477  }
478  // Make sure the dot product of the normal and the direction is positive.
479  if (dir[0]>-2. && dir[0]*norm[0]+dir[1]*norm[1]+dir[2]*norm[2] < 0) {
480  norm[0] = -norm[0];
481  norm[1] = -norm[1];
482  norm[2] = -norm[2];
483  }
484 }
485 
486 ////////////////////////////////////////////////////////////////////////////////
487 /// Test if point is inside this shape.
488 /// first check Z range
489 
490 Bool_t TGeoArb8::Contains(const Double_t *point) const
491 {
492  if (TMath::Abs(point[2]) > fDz) return kFALSE;
493  // compute intersection between Z plane containing point and the arb8
494  Double_t poly[8];
495 // memset(&poly[0], 0, 8*sizeof(Double_t));
496  //SetPlaneVertices(point[2], &poly[0]);
497  Double_t cf = 0.5*(fDz-point[2])/fDz;
498  Int_t i;
499  for (i=0; i<4; i++) {
500  poly[2*i] = fXY[i+4][0]+cf*(fXY[i][0]-fXY[i+4][0]);
501  poly[2*i+1] = fXY[i+4][1]+cf*(fXY[i][1]-fXY[i+4][1]);
502  }
503  return InsidePolygon(point[0],point[1],poly);
504 }
505 
506 ////////////////////////////////////////////////////////////////////////////////
507 /// Computes distance to plane ipl :
508 /// ipl=0 : points 0,4,1,5
509 /// ipl=1 : points 1,5,2,6
510 /// ipl=2 : points 2,6,3,7
511 /// ipl=3 : points 3,7,0,4
512 
513 Double_t TGeoArb8::DistToPlane(const Double_t *point, const Double_t *dir, Int_t ipl, Bool_t in) const
514 {
515  Double_t xa,xb,xc,xd;
516  Double_t ya,yb,yc,yd;
517  Double_t eps = 10.*TGeoShape::Tolerance();
518  Double_t norm[3];
519  Double_t dirp[3];
520  Double_t ndotd = 0;
521  Int_t j = (ipl+1)%4;
522  xa=fXY[ipl][0];
523  ya=fXY[ipl][1];
524  xb=fXY[ipl+4][0];
525  yb=fXY[ipl+4][1];
526  xc=fXY[j][0];
527  yc=fXY[j][1];
528  xd=fXY[4+j][0];
529  yd=fXY[4+j][1];
530  Double_t dz2 =0.5/fDz;
531  Double_t tx1 =dz2*(xb-xa);
532  Double_t ty1 =dz2*(yb-ya);
533  Double_t tx2 =dz2*(xd-xc);
534  Double_t ty2 =dz2*(yd-yc);
535  Double_t dzp =fDz+point[2];
536  Double_t xs1 =xa+tx1*dzp;
537  Double_t ys1 =ya+ty1*dzp;
538  Double_t xs2 =xc+tx2*dzp;
539  Double_t ys2 =yc+ty2*dzp;
540  Double_t dxs =xs2-xs1;
541  Double_t dys =ys2-ys1;
542  Double_t dtx =tx2-tx1;
543  Double_t dty =ty2-ty1;
544  Double_t a=(dtx*dir[1]-dty*dir[0]+(tx1*ty2-tx2*ty1)*dir[2])*dir[2];
545  Double_t signa = TMath::Sign(1.,a);
546  Double_t b=dxs*dir[1]-dys*dir[0]+(dtx*point[1]-dty*point[0]+ty2*xs1-ty1*xs2
547  +tx1*ys2-tx2*ys1)*dir[2];
548  Double_t c=dxs*point[1]-dys*point[0]+xs1*ys2-xs2*ys1;
550  Double_t x1,x2,y1,y2,xp,yp,zi;
551  if (TMath::Abs(a)<eps) {
552  // Surface is planar
553  if (TMath::Abs(b)<eps) return TGeoShape::Big(); // Track parallel to surface
554  s=-c/b;
555  if (TMath::Abs(s)<1.E-6 && TMath::Abs(TMath::Abs(point[2])-fDz)>eps) {
556  memcpy(dirp,dir,3*sizeof(Double_t));
557  dirp[0] = -3;
558  // Compute normal pointing outside
559  ((TGeoArb8*)this)->ComputeNormal(point,dirp,norm);
560  ndotd = dir[0]*norm[0]+dir[1]*norm[1]+dir[2]*norm[2];
561  if (!in) ndotd*=-1.;
562  if (ndotd>0) {
563  s = TMath::Max(0.,s);
564  zi = (point[0]-xs1)*(point[0]-xs2)+(point[1]-ys1)*(point[1]-ys2);
565  if (zi<=0) return s;
566  }
567  return TGeoShape::Big();
568  }
569  if (s<0) return TGeoShape::Big();
570  } else {
571  Double_t d=b*b-4*a*c;
572  if (d<0) return TGeoShape::Big();
573  Double_t smin=0.5*(-b-signa*TMath::Sqrt(d))/a;
574  Double_t smax=0.5*(-b+signa*TMath::Sqrt(d))/a;
575  s = smin;
576  if (TMath::Abs(s)<1.E-6 && TMath::Abs(TMath::Abs(point[2])-fDz)>eps) {
577  memcpy(dirp,dir,3*sizeof(Double_t));
578  dirp[0] = -3;
579  // Compute normal pointing outside
580  ((TGeoArb8*)this)->ComputeNormal(point,dirp,norm);
581  ndotd = dir[0]*norm[0]+dir[1]*norm[1]+dir[2]*norm[2];
582  if (!in) ndotd*=-1.;
583  if (ndotd>0) return TMath::Max(0.,s);
584  s = 0.; // ignore
585  }
586  if (s>eps) {
587  // Check smin
588  zi=point[2]+s*dir[2];
589  if (TMath::Abs(zi)<fDz) {
590  x1=xs1+tx1*dir[2]*s;
591  x2=xs2+tx2*dir[2]*s;
592  xp=point[0]+s*dir[0];
593  y1=ys1+ty1*dir[2]*s;
594  y2=ys2+ty2*dir[2]*s;
595  yp=point[1]+s*dir[1];
596  zi = (xp-x1)*(xp-x2)+(yp-y1)*(yp-y2);
597  if (zi<=0) return s;
598  }
599  }
600  // Smin failed, try smax
601  s=smax;
602  if (TMath::Abs(s)<1.E-6 && TMath::Abs(TMath::Abs(point[2])-fDz)>eps) {
603  memcpy(dirp,dir,3*sizeof(Double_t));
604  dirp[0] = -3;
605  // Compute normal pointing outside
606  ((TGeoArb8*)this)->ComputeNormal(point,dirp,norm);
607  ndotd = dir[0]*norm[0]+dir[1]*norm[1]+dir[2]*norm[2];
608  if (!in) ndotd*=-1.;
609  if (ndotd>0) s = TMath::Max(0.,s);
610  else s = TGeoShape::Big();
611  return s;
612  }
613  }
614  if (s>eps) {
615  // Check smin
616  zi=point[2]+s*dir[2];
617  if (TMath::Abs(zi)<fDz) {
618  x1=xs1+tx1*dir[2]*s;
619  x2=xs2+tx2*dir[2]*s;
620  xp=point[0]+s*dir[0];
621  y1=ys1+ty1*dir[2]*s;
622  y2=ys2+ty2*dir[2]*s;
623  yp=point[1]+s*dir[1];
624  zi = (xp-x1)*(xp-x2)+(yp-y1)*(yp-y2);
625  if (zi<=0) return s;
626  }
627  }
628  return TGeoShape::Big();
629 }
630 
631 ////////////////////////////////////////////////////////////////////////////////
632 /// Computes distance from outside point to surface of the shape.
633 
634 Double_t TGeoArb8::DistFromOutside(const Double_t *point, const Double_t *dir, Int_t /*iact*/, Double_t step, Double_t * /*safe*/) const
635 {
636  Double_t sdist = TGeoBBox::DistFromOutside(point,dir, fDX, fDY, fDZ, fOrigin, step);
637  if (sdist>=step) return TGeoShape::Big();
638  Double_t snext;
639  // check Z planes
640  if (TMath::Abs(point[2])>fDz-1.E-8) {
641  Double_t pt[3];
642  if (point[2]*dir[2]<0) {
643  pt[2]=fDz*TMath::Sign(1.,point[2]);
644  snext = TMath::Max((pt[2]-point[2])/dir[2],0.);
645  for (Int_t j=0; j<2; j++) pt[j]=point[j]+snext*dir[j];
646  if (Contains(&pt[0])) return snext;
647  }
648  }
649  // check lateral faces
650  Double_t dist;
651  snext = TGeoShape::Big();
652  for (Int_t i=0; i<4; i++) {
653  dist = DistToPlane(point, dir, i, kFALSE);
654  if (dist<snext) snext = dist;
655  }
656  return snext;
657 }
658 
659 ////////////////////////////////////////////////////////////////////////////////
660 /// Compute distance from inside point to surface of the shape.
661 
662 Double_t TGeoArb8::DistFromInside(const Double_t *point, const Double_t *dir, Int_t /*iact*/, Double_t /*step*/, Double_t * /*safe*/) const
663 {
664  Int_t i;
665  Double_t distz = TGeoShape::Big();
666  Double_t distl = TGeoShape::Big();
667  Double_t dist;
668  Double_t pt[3] = {0.,0.,0.};
669  if (dir[2]<0) {
670  distz=(-fDz-point[2])/dir[2];
671  pt[2] = -fDz;
672  } else {
673  if (dir[2]>0) distz=(fDz-point[2])/dir[2];
674  pt[2] = fDz;
675  }
676  for (i=0; i<4; i++) {
677  dist=DistToPlane(point, dir, i, kTRUE);
678  if (dist<distl) distl = dist;
679  }
680  if (distz<distl) {
681  pt[0] = point[0]+distz*dir[0];
682  pt[1] = point[1]+distz*dir[1];
683  if (!Contains(pt)) distz = TGeoShape::Big();
684  }
685  dist = TMath::Min(distz, distl);
686  if (dist<0 || dist>1.E10) return 0.;
687  return dist;
688 #ifdef OLDALGORITHM
689 //#else
690 // compute distance to plane ipl :
691 // ipl=0 : points 0,4,1,5
692 // ipl=1 : points 1,5,2,6
693 // ipl=2 : points 2,6,3,7
694 // ipl=3 : points 3,7,0,4
695  Double_t distmin;
696  Bool_t lateral_cross = kFALSE;
697  if (dir[2]<0) {
698  distmin=(-fDz-point[2])/dir[2];
699  } else {
700  if (dir[2]>0) distmin =(fDz-point[2])/dir[2];
701  else distmin = TGeoShape::Big();
702  }
703  Double_t dz2 =0.5/fDz;
704  Double_t xa,xb,xc,xd;
705  Double_t ya,yb,yc,yd;
706  Double_t eps = 100.*TGeoShape::Tolerance();
707  for (Int_t ipl=0;ipl<4;ipl++) {
708  Int_t j = (ipl+1)%4;
709  xa=fXY[ipl][0];
710  ya=fXY[ipl][1];
711  xb=fXY[ipl+4][0];
712  yb=fXY[ipl+4][1];
713  xc=fXY[j][0];
714  yc=fXY[j][1];
715  xd=fXY[4+j][0];
716  yd=fXY[4+j][1];
717 
718  Double_t tx1 =dz2*(xb-xa);
719  Double_t ty1 =dz2*(yb-ya);
720  Double_t tx2 =dz2*(xd-xc);
721  Double_t ty2 =dz2*(yd-yc);
722  Double_t dzp =fDz+point[2];
723  Double_t xs1 =xa+tx1*dzp;
724  Double_t ys1 =ya+ty1*dzp;
725  Double_t xs2 =xc+tx2*dzp;
726  Double_t ys2 =yc+ty2*dzp;
727  Double_t dxs =xs2-xs1;
728  Double_t dys =ys2-ys1;
729  Double_t dtx =tx2-tx1;
730  Double_t dty =ty2-ty1;
731  Double_t a=(dtx*dir[1]-dty*dir[0]+(tx1*ty2-tx2*ty1)*dir[2])*dir[2];
732  Double_t b=dxs*dir[1]-dys*dir[0]+(dtx*point[1]-dty*point[0]+ty2*xs1-ty1*xs2
733  +tx1*ys2-tx2*ys1)*dir[2];
734  Double_t c=dxs*point[1]-dys*point[0]+xs1*ys2-xs2*ys1;
736  if (TMath::Abs(a)<eps) {
737  if (TMath::Abs(b)<eps) continue;
738  s=-c/b;
739  if (s>eps && s < distmin) {
740  distmin =s;
741  lateral_cross=kTRUE;
742  }
743  continue;
744  }
745  Double_t d=b*b-4*a*c;
746  if (d>=0.) {
747  if (a>0) s=0.5*(-b-TMath::Sqrt(d))/a;
748  else s=0.5*(-b+TMath::Sqrt(d))/a;
749  if (s>eps) {
750  if (s < distmin) {
751  distmin = s;
752  lateral_cross = kTRUE;
753  }
754  } else {
755  if (a>0) s=0.5*(-b+TMath::Sqrt(d))/a;
756  else s=0.5*(-b-TMath::Sqrt(d))/a;
757  if (s>eps && s < distmin) {
758  distmin =s;
759  lateral_cross = kTRUE;
760  }
761  }
762  }
763  }
764 
765  if (!lateral_cross) {
766  // We have to make sure that track crosses the top or bottom.
767  if (distmin > 1.E10) return TGeoShape::Tolerance();
768  Double_t pt[2];
769  pt[0] = point[0]+distmin*dir[0];
770  pt[1] = point[1]+distmin*dir[1];
771  // Check if propagated point is in the polygon
772  Double_t poly[8];
773  Int_t i = 0;
774  if (dir[2]>0.) i=4;
775  for (Int_t j=0; j<4; j++) {
776  poly[2*j] = fXY[j+i][0];
777  poly[2*j+1] = fXY[j+i][1];
778  }
779  if (!InsidePolygon(pt[0],pt[1],poly)) return TGeoShape::Tolerance();
780  }
781  return distmin;
782 #endif
783 }
784 
785 ////////////////////////////////////////////////////////////////////////////////
786 /// Divide this shape along one axis.
787 
788 TGeoVolume *TGeoArb8::Divide(TGeoVolume *voldiv, const char * /*divname*/, Int_t /*iaxis*/, Int_t /*ndiv*/,
789  Double_t /*start*/, Double_t /*step*/)
790 {
791  Error("Divide", "Division of an arbitrary trapezoid not implemented");
792  return voldiv;
793 }
794 
795 ////////////////////////////////////////////////////////////////////////////////
796 /// Get shape range on a given axis.
797 
799 {
800  xlo = 0;
801  xhi = 0;
802  Double_t dx = 0;
803  if (iaxis==3) {
804  xlo = -fDz;
805  xhi = fDz;
806  dx = xhi-xlo;
807  return dx;
808  }
809  return dx;
810 }
811 
812 ////////////////////////////////////////////////////////////////////////////////
813 ///--- Fill vector param[4] with the bounding cylinder parameters. The order
814 /// is the following : Rmin, Rmax, Phi1, Phi2
815 ///--- first compute rmin/rmax
816 
818 {
819  Double_t rmaxsq = 0;
820  Double_t rsq;
821  Int_t i;
822  for (i=0; i<8; i++) {
823  rsq = fXY[i][0]*fXY[i][0] + fXY[i][1]*fXY[i][1];
824  rmaxsq = TMath::Max(rsq, rmaxsq);
825  }
826  param[0] = 0.; // Rmin
827  param[1] = rmaxsq; // Rmax
828  param[2] = 0.; // Phi1
829  param[3] = 360.; // Phi2
830 }
831 
832 ////////////////////////////////////////////////////////////////////////////////
833 /// Fills real parameters of a positioned box inside this arb8. Returns 0 if successfull.
834 
835 Int_t TGeoArb8::GetFittingBox(const TGeoBBox *parambox, TGeoMatrix *mat, Double_t &dx, Double_t &dy, Double_t &dz) const
836 {
837  dx=dy=dz=0;
838  if (mat->IsRotation()) {
839  Error("GetFittingBox", "cannot handle parametrized rotated volumes");
840  return 1; // ### rotation not accepted ###
841  }
842  //--> translate the origin of the parametrized box to the frame of this box.
843  Double_t origin[3];
844  mat->LocalToMaster(parambox->GetOrigin(), origin);
845  if (!Contains(origin)) {
846  Error("GetFittingBox", "wrong matrix - parametrized box is outside this");
847  return 1; // ### wrong matrix ###
848  }
849  //--> now we have to get the valid range for all parametrized axis
850  Double_t dd[3];
851  dd[0] = parambox->GetDX();
852  dd[1] = parambox->GetDY();
853  dd[2] = parambox->GetDZ();
854  //-> check if Z range is fixed
855  if (dd[2]<0) {
856  dd[2] = TMath::Min(origin[2]+fDz, fDz-origin[2]);
857  if (dd[2]<0) {
858  Error("GetFittingBox", "wrong matrix");
859  return 1;
860  }
861  }
862  if (dd[0]>=0 && dd[1]>=0) {
863  dx = dd[0];
864  dy = dd[1];
865  dz = dd[2];
866  return 0;
867  }
868  //-> check now vertices at Z = origin[2] +/- dd[2]
869  Double_t upper[8];
870  Double_t lower[8];
871  SetPlaneVertices(origin[2]-dd[2], lower);
872  SetPlaneVertices(origin[2]+dd[2], upper);
873  Double_t ddmin=TGeoShape::Big();
874  for (Int_t iaxis=0; iaxis<2; iaxis++) {
875  if (dd[iaxis]>=0) continue;
876  ddmin=TGeoShape::Big();
877  for (Int_t ivert=0; ivert<4; ivert++) {
878  ddmin = TMath::Min(ddmin, TMath::Abs(origin[iaxis]-lower[2*ivert+iaxis]));
879  ddmin = TMath::Min(ddmin, TMath::Abs(origin[iaxis]-upper[2*ivert+iaxis]));
880  }
881  dd[iaxis] = ddmin;
882  }
883  dx = dd[0];
884  dy = dd[1];
885  dz = dd[2];
886  return 0;
887 }
888 
889 ////////////////////////////////////////////////////////////////////////////////
890 /// Computes normal to plane defined by P1, P2 and P3
891 
893 {
894  Double_t cross = 0.;
895  Double_t v1[3], v2[3];
896  Int_t i;
897  for (i=0; i<3; i++) {
898  v1[i] = p2[i] - p1[i];
899  v2[i] = p3[i] - p1[i];
900  }
901  norm[0] = v1[1]*v2[2]-v1[2]*v2[1];
902  cross += norm[0]*norm[0];
903  norm[1] = v1[2]*v2[0]-v1[0]*v2[2];
904  cross += norm[1]*norm[1];
905  norm[2] = v1[0]*v2[1]-v1[1]*v2[0];
906  cross += norm[2]*norm[2];
907  if (TMath::Abs(cross) < TGeoShape::Tolerance()) return;
908  cross = 1./TMath::Sqrt(cross);
909  for (i=0; i<3; i++) norm[i] *= cross;
910 }
911 
912 ////////////////////////////////////////////////////////////////////////////////
913 /// Fills array with n random points located on the surface of indexed facet.
914 /// The output array must be provided with a length of minimum 3*npoints. Returns
915 /// true if operation succeeded.
916 /// Possible index values:
917 /// 0 - all facets togeather
918 /// 1 to 6 - facet index from bottom to top Z
919 
920 Bool_t TGeoArb8::GetPointsOnFacet(Int_t /*index*/, Int_t /*npoints*/, Double_t * /* array */) const
921 {
922  return kFALSE;
923 /*
924  if (index<0 || index>6) return kFALSE;
925  if (index==0) {
926  // Just generate same number of points on each facet
927  Int_t npts = npoints/6.;
928  Int_t count = 0;
929  for (Int_t ifacet=0; ifacet<6; ifacet++) {
930  if (GetPointsOnFacet(ifacet+1, npts, &array[3*count])) count += npts;
931  if (ifacet<5) npts = (npoints-count)/(5.-ifacet);
932  }
933  if (count>0) return kTRUE;
934  return kFALSE;
935  }
936  Double_t z, cf;
937  Double_t xmin=TGeoShape::Big();
938  Double_t xmax=-xmin;
939  Double_t ymin=TGeoShape::Big();
940  Double_t ymax=-ymin;
941  Double_t dy=0.;
942  Double_t poly[8];
943  Double_t point[2];
944  Int_t i;
945  if (index==1 || index==6) {
946  z = (index==1)?-fDz:fDz;
947  cf = 0.5*(fDz-z)/fDz;
948  for (i=0; i<4; i++) {
949  poly[2*i] = fXY[i+4][0]+cf*(fXY[i][0]-fXY[i+4][0]);
950  poly[2*i+1] = fXY[i+4][1]+cf*(fXY[i][1]-fXY[i+4][1]);
951  xmin = TMath::Min(xmin, poly[2*i]);
952  xmax = TMath::Max(xmax, poly[2*i]);
953  ymin = TMath::Min(ymin, poly[2*i]);
954  ymax = TMath::Max(ymax, poly[2*i]);
955  }
956  }
957  Int_t nshoot = 0;
958  Int_t nmiss = 0;
959  for (i=0; i<npoints; i++) {
960  Double_t *point = &array[3*i];
961  switch (surfindex) {
962  case 1:
963  case 6:
964  while (nmiss<1000) {
965  point[0] = xmin + (xmax-xmin)*gRandom->Rndm();
966  point[1] = ymin + (ymax-ymin)*gRandom->Rndm();
967  }
968 
969  return InsidePolygon(point[0],point[1],poly);
970 */
971 }
972 
973 ////////////////////////////////////////////////////////////////////////////////
974 /// Finds if a point in XY plane is inside the polygon defines by PTS.
975 
977 {
978  Int_t i,j;
979  Double_t x1,y1,x2,y2;
980  Double_t cross;
981  for (i=0; i<4; i++) {
982  j = (i+1)%4;
983  x1 = pts[i<<1];
984  y1 = pts[(i<<1)+1];
985  x2 = pts[j<<1];
986  y2 = pts[(j<<1)+1];
987  cross = (x-x1)*(y2-y1)-(y-y1)*(x2-x1);
988  if (cross<0) return kFALSE;
989  }
990  return kTRUE;
991 }
992 
993 ////////////////////////////////////////////////////////////////////////////////
994 /// Prints shape parameters
995 
997 {
998  printf("*** Shape %s: TGeoArb8 ***\n", GetName());
999  if (IsTwisted()) printf(" = TWISTED\n");
1000  for (Int_t ip=0; ip<8; ip++) {
1001  printf(" point #%i : x=%11.5f y=%11.5f z=%11.5f\n",
1002  ip, fXY[ip][0], fXY[ip][1], fDz*((ip<4)?-1:1));
1003  }
1004  printf(" Bounding box:\n");
1006 }
1007 
1008 ////////////////////////////////////////////////////////////////////////////////
1009 /// Computes the closest distance from given point to this shape.
1010 
1011 Double_t TGeoArb8::Safety(const Double_t *point, Bool_t in) const
1012 {
1013  Double_t safz = fDz-TMath::Abs(point[2]);
1014  if (!in) safz = -safz;
1015  Int_t iseg;
1016  Double_t safe = TGeoShape::Big();
1017  Double_t lsq, ssq, dx, dy, dpx, dpy, u;
1018  if (IsTwisted()) {
1019  if (!in) {
1020  if (!TGeoBBox::Contains(point)) return TGeoBBox::Safety(point,kFALSE);
1021  }
1022  // Point is also in the bounding box ;-(
1023  // Compute closest distance to any segment
1024  Double_t vert[8];
1025  Double_t *p1, *p2;
1026  Int_t isegmin=0;
1027  Double_t umin = 0.;
1028  SetPlaneVertices (point[2], vert);
1029  for (iseg=0; iseg<4; iseg++) {
1030  if (safe<TGeoShape::Tolerance()) return 0.;
1031  p1 = &vert[2*iseg];
1032  p2 = &vert[2*((iseg+1)%4)];
1033  dx = p2[0] - p1[0];
1034  dy = p2[1] - p1[1];
1035  dpx = point[0] - p1[0];
1036  dpy = point[1] - p1[1];
1037 
1038  lsq = dx*dx + dy*dy;
1039  u = (dpx*dx + dpy*dy)/lsq;
1040  if (u>1) {
1041  dpx = point[0]-p2[0];
1042  dpy = point[1]-p2[1];
1043  } else {
1044  if (u>=0) {
1045  dpx -= u*dx;
1046  dpy -= u*dy;
1047  }
1048  }
1049  ssq = dpx*dpx + dpy*dpy;
1050  if (ssq < safe) {
1051  isegmin = iseg;
1052  umin = u;
1053  safe = ssq;
1054  }
1055  }
1056  if (umin<0) umin = 0.;
1057  if (umin>1) {
1058  isegmin = (isegmin+1)%4;
1059  umin = 0.;
1060  }
1061  Int_t i1 = isegmin;
1062  Int_t i2 = (isegmin+1)%4;
1063  Double_t dx1 = fXY[i2][0]-fXY[i1][0];
1064  Double_t dx2 = fXY[i2+4][0]-fXY[i1+4][0];
1065  Double_t dy1 = fXY[i2][1]-fXY[i1][1];
1066  Double_t dy2 = fXY[i2+4][1]-fXY[i1+4][1];
1067  dx = dx1 + umin*(dx2-dx1);
1068  dy = dy1 + umin*(dy2-dy1);
1069  safe *= 1.- 4.*fDz*fDz/(dx*dx+dy*dy+4.*fDz*fDz);
1070  safe = TMath::Sqrt(safe);
1071  if (in) return TMath::Min(safz,safe);
1072  return TMath::Max(safz,safe);
1073  }
1074 
1075  Double_t saf[5];
1076  saf[0] = safz;
1077 
1078  for (iseg=0; iseg<4; iseg++) saf[iseg+1] = SafetyToFace(point,iseg,in);
1079  if (in) safe = saf[TMath::LocMin(5, saf)];
1080  else safe = saf[TMath::LocMax(5, saf)];
1081  if (safe<0) return 0.;
1082  return safe;
1083 }
1084 
1085 ////////////////////////////////////////////////////////////////////////////////
1086 /// Estimate safety to lateral plane defined by segment iseg in range [0,3]
1087 /// Might be negative: plane seen only from inside.
1088 
1089 Double_t TGeoArb8::SafetyToFace(const Double_t *point, Int_t iseg, Bool_t in) const
1090 {
1091  Double_t vertices[12];
1092  Int_t ipln = (iseg+1)%4;
1093  // point 1
1094  vertices[0] = fXY[iseg][0];
1095  vertices[1] = fXY[iseg][1];
1096  vertices[2] = -fDz;
1097  // point 2
1098  vertices[3] = fXY[ipln][0];
1099  vertices[4] = fXY[ipln][1];
1100  vertices[5] = -fDz;
1101  // point 3
1102  vertices[6] = fXY[ipln+4][0];
1103  vertices[7] = fXY[ipln+4][1];
1104  vertices[8] = fDz;
1105  // point 4
1106  vertices[9] = fXY[iseg+4][0];
1107  vertices[10] = fXY[iseg+4][1];
1108  vertices[11] = fDz;
1109  Double_t safe;
1110  Double_t norm[3];
1111  Double_t *p1, *p2, *p3;
1112  p1 = &vertices[0];
1113  p2 = &vertices[9];
1114  p3 = &vertices[6];
1115  if (IsSamePoint(p2,p3)) {
1116  p3 = &vertices[3];
1117  if (IsSamePoint(p1,p3)) return -TGeoShape::Big(); // skip single segment
1118  }
1119  GetPlaneNormal(p1,p2,p3,norm);
1120  safe = (point[0]-p1[0])*norm[0]+(point[1]-p1[1])*norm[1]+(point[2]-p1[2])*norm[2];
1121  if (in) return (-safe);
1122  return safe;
1123 }
1124 
1125 ////////////////////////////////////////////////////////////////////////////////
1126 /// Save a primitive as a C++ statement(s) on output stream "out".
1127 
1128 void TGeoArb8::SavePrimitive(std::ostream &out, Option_t * /*option*/ /*= ""*/)
1129 {
1130  if (TObject::TestBit(kGeoSavePrimitive)) return;
1131  out << " // Shape: " << GetName() << " type: " << ClassName() << std::endl;
1132  out << " dz = " << fDz << ";" << std::endl;
1133  out << " vert[0] = " << fXY[0][0] << ";" << std::endl;
1134  out << " vert[1] = " << fXY[0][1] << ";" << std::endl;
1135  out << " vert[2] = " << fXY[1][0] << ";" << std::endl;
1136  out << " vert[3] = " << fXY[1][1] << ";" << std::endl;
1137  out << " vert[4] = " << fXY[2][0] << ";" << std::endl;
1138  out << " vert[5] = " << fXY[2][1] << ";" << std::endl;
1139  out << " vert[6] = " << fXY[3][0] << ";" << std::endl;
1140  out << " vert[7] = " << fXY[3][1] << ";" << std::endl;
1141  out << " vert[8] = " << fXY[4][0] << ";" << std::endl;
1142  out << " vert[9] = " << fXY[4][1] << ";" << std::endl;
1143  out << " vert[10] = " << fXY[5][0] << ";" << std::endl;
1144  out << " vert[11] = " << fXY[5][1] << ";" << std::endl;
1145  out << " vert[12] = " << fXY[6][0] << ";" << std::endl;
1146  out << " vert[13] = " << fXY[6][1] << ";" << std::endl;
1147  out << " vert[14] = " << fXY[7][0] << ";" << std::endl;
1148  out << " vert[15] = " << fXY[7][1] << ";" << std::endl;
1149  out << " TGeoShape *" << GetPointerName() << " = new TGeoArb8(\"" << GetName() << "\", dz,vert);" << std::endl;
1151 }
1152 
1153 ////////////////////////////////////////////////////////////////////////////////
1154 /// Computes intersection points between plane at zpl and non-horizontal edges.
1155 
1157 {
1158  Double_t cf = 0.5*(fDz-zpl)/fDz;
1159  for (Int_t i=0; i<4; i++) {
1160  vertices[2*i] = fXY[i+4][0]+cf*(fXY[i][0]-fXY[i+4][0]);
1161  vertices[2*i+1] = fXY[i+4][1]+cf*(fXY[i][1]-fXY[i+4][1]);
1162  }
1163 }
1164 
1165 ////////////////////////////////////////////////////////////////////////////////
1166 /// Set all arb8 params in one step.
1167 /// param[0] = dz
1168 /// param[1] = x0
1169 /// param[2] = y0
1170 /// ...
1171 
1173 {
1174  fDz = param[0];
1175  for (Int_t i=0; i<8; i++) {
1176  fXY[i][0] = param[2*i+1];
1177  fXY[i][1] = param[2*i+2];
1178  }
1179  ComputeTwist();
1180  ComputeBBox();
1181 }
1182 
1183 ////////////////////////////////////////////////////////////////////////////////
1184 /// Creates arb8 mesh points
1185 
1187 {
1188  for (Int_t i=0; i<8; i++) {
1189  points[3*i] = fXY[i][0];
1190  points[3*i+1] = fXY[i][1];
1191  points[3*i+2] = (i<4)?-fDz:fDz;
1192  }
1193 }
1194 
1195 ////////////////////////////////////////////////////////////////////////////////
1196 /// Creates arb8 mesh points
1197 
1199 {
1200  for (Int_t i=0; i<8; i++) {
1201  points[3*i] = fXY[i][0];
1202  points[3*i+1] = fXY[i][1];
1203  points[3*i+2] = (i<4)?-fDz:fDz;
1204  }
1205 }
1206 
1207 ////////////////////////////////////////////////////////////////////////////////
1208 /// Set values for a given vertex.
1209 
1211 {
1212  if (vnum<0 || vnum >7) {
1213  Error("SetVertex", "Invalid vertex number");
1214  return;
1215  }
1216  fXY[vnum][0] = x;
1217  fXY[vnum][1] = y;
1218  if (vnum == 7) {
1219  ComputeTwist();
1220  ComputeBBox();
1221  }
1222 }
1223 
1224 ////////////////////////////////////////////////////////////////////////////////
1225 /// Fill size of this 3-D object
1226 
1228 {
1230 }
1231 
1232 ////////////////////////////////////////////////////////////////////////////////
1233 /// Stream an object of class TGeoManager.
1234 
1235 void TGeoArb8::Streamer(TBuffer &R__b)
1236 {
1237  if (R__b.IsReading()) {
1238  R__b.ReadClassBuffer(TGeoArb8::Class(), this);
1239  ComputeTwist();
1240  } else {
1241  R__b.WriteClassBuffer(TGeoArb8::Class(), this);
1242  }
1243 }
1244 
1245 ////////////////////////////////////////////////////////////////////////////////
1246 /// Check the inside status for each of the points in the array.
1247 /// Input: Array of point coordinates + vector size
1248 /// Output: Array of Booleans for the inside of each point
1249 
1250 void TGeoArb8::Contains_v(const Double_t *points, Bool_t *inside, Int_t vecsize) const
1251 {
1252  for (Int_t i=0; i<vecsize; i++) inside[i] = Contains(&points[3*i]);
1253 }
1254 
1255 ////////////////////////////////////////////////////////////////////////////////
1256 /// Compute the normal for an array o points so that norm.dot.dir is positive
1257 /// Input: Arrays of point coordinates and directions + vector size
1258 /// Output: Array of normal directions
1259 
1260 void TGeoArb8::ComputeNormal_v(const Double_t *points, const Double_t *dirs, Double_t *norms, Int_t vecsize)
1261 {
1262  for (Int_t i=0; i<vecsize; i++) ComputeNormal(&points[3*i], &dirs[3*i], &norms[3*i]);
1263 }
1264 
1265 ////////////////////////////////////////////////////////////////////////////////
1266 /// Compute distance from array of input points having directions specisied by dirs. Store output in dists
1267 
1268 void TGeoArb8::DistFromInside_v(const Double_t *points, const Double_t *dirs, Double_t *dists, Int_t vecsize, Double_t* step) const
1269 {
1270  for (Int_t i=0; i<vecsize; i++) dists[i] = DistFromInside(&points[3*i], &dirs[3*i], 3, step[i]);
1271 }
1272 
1273 ////////////////////////////////////////////////////////////////////////////////
1274 /// Compute distance from array of input points having directions specisied by dirs. Store output in dists
1275 
1276 void TGeoArb8::DistFromOutside_v(const Double_t *points, const Double_t *dirs, Double_t *dists, Int_t vecsize, Double_t* step) const
1277 {
1278  for (Int_t i=0; i<vecsize; i++) dists[i] = DistFromOutside(&points[3*i], &dirs[3*i], 3, step[i]);
1279 }
1280 
1281 ////////////////////////////////////////////////////////////////////////////////
1282 /// Compute safe distance from each of the points in the input array.
1283 /// Input: Array of point coordinates, array of statuses for these points, size of the arrays
1284 /// Output: Safety values
1285 
1286 void TGeoArb8::Safety_v(const Double_t *points, const Bool_t *inside, Double_t *safe, Int_t vecsize) const
1287 {
1288  for (Int_t i=0; i<vecsize; i++) safe[i] = Safety(&points[3*i], inside[i]);
1289 }
1290 
1292 
1293 ////////////////////////////////////////////////////////////////////////////////
1294 /// Default ctor
1295 
1296 TGeoTrap::TGeoTrap()
1297 {
1298  fDz = 0;
1299  fTheta = 0;
1300  fPhi = 0;
1301  fH1 = fH2 = fBl1 = fBl2 = fTl1 = fTl2 = fAlpha1 = fAlpha2 = 0;
1302 }
1303 
1304 ////////////////////////////////////////////////////////////////////////////////
1305 /// Constructor providing just a range in Z, theta and phi.
1306 
1308  :TGeoArb8("", 0, 0)
1309 {
1310  fDz = dz;
1311  fTheta = theta;
1312  fPhi = phi;
1313  fH1 = fH2 = fBl1 = fBl2 = fTl1 = fTl2 = fAlpha1 = fAlpha2 = 0;
1314 }
1315 
1316 ////////////////////////////////////////////////////////////////////////////////
1317 /// Normal constructor.
1318 
1320  Double_t bl1, Double_t tl1, Double_t alpha1, Double_t h2, Double_t bl2,
1321  Double_t tl2, Double_t alpha2)
1322  :TGeoArb8("", 0, 0)
1323 {
1324  fDz = dz;
1325  fTheta = theta;
1326  fPhi = phi;
1327  fH1 = h1;
1328  fH2 = h2;
1329  fBl1 = bl1;
1330  fBl2 = bl2;
1331  fTl1 = tl1;
1332  fTl2 = tl2;
1333  fAlpha1 = alpha1;
1334  fAlpha2 = alpha2;
1337  Double_t ta1 = TMath::Tan(alpha1*TMath::DegToRad());
1338  Double_t ta2 = TMath::Tan(alpha2*TMath::DegToRad());
1339  fXY[0][0] = -dz*tx-h1*ta1-bl1; fXY[0][1] = -dz*ty-h1;
1340  fXY[1][0] = -dz*tx+h1*ta1-tl1; fXY[1][1] = -dz*ty+h1;
1341  fXY[2][0] = -dz*tx+h1*ta1+tl1; fXY[2][1] = -dz*ty+h1;
1342  fXY[3][0] = -dz*tx-h1*ta1+bl1; fXY[3][1] = -dz*ty-h1;
1343  fXY[4][0] = dz*tx-h2*ta2-bl2; fXY[4][1] = dz*ty-h2;
1344  fXY[5][0] = dz*tx+h2*ta2-tl2; fXY[5][1] = dz*ty+h2;
1345  fXY[6][0] = dz*tx+h2*ta2+tl2; fXY[6][1] = dz*ty+h2;
1346  fXY[7][0] = dz*tx-h2*ta2+bl2; fXY[7][1] = dz*ty-h2;
1347  ComputeTwist();
1348  if ((dz<0) || (h1<0) || (bl1<0) || (tl1<0) ||
1349  (h2<0) || (bl2<0) || (tl2<0)) {
1351  }
1352  else TGeoArb8::ComputeBBox();
1353 }
1354 
1355 ////////////////////////////////////////////////////////////////////////////////
1356 /// Constructor with name.
1357 
1359  Double_t bl1, Double_t tl1, Double_t alpha1, Double_t h2, Double_t bl2,
1360  Double_t tl2, Double_t alpha2)
1361  :TGeoArb8(name, 0, 0)
1362 {
1363  SetName(name);
1364  fDz = dz;
1365  fTheta = theta;
1366  fPhi = phi;
1367  fH1 = h1;
1368  fH2 = h2;
1369  fBl1 = bl1;
1370  fBl2 = bl2;
1371  fTl1 = tl1;
1372  fTl2 = tl2;
1373  fAlpha1 = alpha1;
1374  fAlpha2 = alpha2;
1375  for (Int_t i=0; i<8; i++) {
1376  fXY[i][0] = 0.0;
1377  fXY[i][1] = 0.0;
1378  }
1381  Double_t ta1 = TMath::Tan(alpha1*TMath::DegToRad());
1382  Double_t ta2 = TMath::Tan(alpha2*TMath::DegToRad());
1383  fXY[0][0] = -dz*tx-h1*ta1-bl1; fXY[0][1] = -dz*ty-h1;
1384  fXY[1][0] = -dz*tx+h1*ta1-tl1; fXY[1][1] = -dz*ty+h1;
1385  fXY[2][0] = -dz*tx+h1*ta1+tl1; fXY[2][1] = -dz*ty+h1;
1386  fXY[3][0] = -dz*tx-h1*ta1+bl1; fXY[3][1] = -dz*ty-h1;
1387  fXY[4][0] = dz*tx-h2*ta2-bl2; fXY[4][1] = dz*ty-h2;
1388  fXY[5][0] = dz*tx+h2*ta2-tl2; fXY[5][1] = dz*ty+h2;
1389  fXY[6][0] = dz*tx+h2*ta2+tl2; fXY[6][1] = dz*ty+h2;
1390  fXY[7][0] = dz*tx-h2*ta2+bl2; fXY[7][1] = dz*ty-h2;
1391  ComputeTwist();
1392  if ((dz<0) || (h1<0) || (bl1<0) || (tl1<0) ||
1393  (h2<0) || (bl2<0) || (tl2<0)) {
1395  }
1396  else TGeoArb8::ComputeBBox();
1397 }
1398 
1399 ////////////////////////////////////////////////////////////////////////////////
1400 /// destructor
1401 
1403 {
1404 }
1405 
1406 ////////////////////////////////////////////////////////////////////////////////
1407 /// Compute distance from inside point to surface of the trapezoid
1408 
1409 Double_t TGeoTrap::DistFromInside(const Double_t *point, const Double_t *dir, Int_t iact, Double_t step, Double_t *safe) const
1410 {
1411  if (iact<3 && safe) {
1412  // compute safe distance
1413  *safe = Safety(point, kTRUE);
1414  if (iact==0) return TGeoShape::Big();
1415  if (iact==1 && step<*safe) return TGeoShape::Big();
1416  }
1417  // compute distance to get ouside this shape
1418 // return TGeoArb8::DistFromInside(point, dir, iact, step, safe);
1419 
1420 // compute distance to plane ipl :
1421 // ipl=0 : points 0,4,1,5
1422 // ipl=1 : points 1,5,2,6
1423 // ipl=2 : points 2,6,3,7
1424 // ipl=3 : points 3,7,0,4
1425  Double_t distmin;
1426  if (dir[2]<0) {
1427  distmin=(-fDz-point[2])/dir[2];
1428  } else {
1429  if (dir[2]>0) distmin =(fDz-point[2])/dir[2];
1430  else distmin = TGeoShape::Big();
1431  }
1432  Double_t xa,xb,xc;
1433  Double_t ya,yb,yc;
1434  for (Int_t ipl=0;ipl<4;ipl++) {
1435  Int_t j = (ipl+1)%4;
1436  xa=fXY[ipl][0];
1437  ya=fXY[ipl][1];
1438  xb=fXY[ipl+4][0];
1439  yb=fXY[ipl+4][1];
1440  xc=fXY[j][0];
1441  yc=fXY[j][1];
1442  Double_t ax,ay,az;
1443  ax = xb-xa;
1444  ay = yb-ya;
1445  az = 2.*fDz;
1446  Double_t bx,by;
1447  bx = xc-xa;
1448  by = yc-ya;
1449  Double_t ddotn = -dir[0]*az*by + dir[1]*az*bx+dir[2]*(ax*by-ay*bx);
1450  if (ddotn<=0) continue; // entering
1451  Double_t saf = -(point[0]-xa)*az*by + (point[1]-ya)*az*bx + (point[2]+fDz)*(ax*by-ay*bx);
1452  if (saf>=0.0) return 0.0;
1453  Double_t s = -saf/ddotn;
1454  if (s<distmin) distmin=s;
1455  }
1456  return distmin;
1457 }
1458 
1459 ////////////////////////////////////////////////////////////////////////////////
1460 /// Compute distance from outside point to surface of the trapezoid
1461 
1462 Double_t TGeoTrap::DistFromOutside(const Double_t *point, const Double_t *dir, Int_t iact, Double_t step, Double_t *safe) const
1463 {
1464  if (iact<3 && safe) {
1465  // compute safe distance
1466  *safe = Safety(point, kFALSE);
1467  if (iact==0) return TGeoShape::Big();
1468  if (iact==1 && step<*safe) return TGeoShape::Big();
1469  }
1470 // Check if the bounding box is crossed within the requested distance
1471  Double_t sdist = TGeoBBox::DistFromOutside(point,dir, fDX, fDY, fDZ, fOrigin, step);
1472  if (sdist>=step) return TGeoShape::Big();
1473  // compute distance to get ouside this shape
1474  Bool_t in = kTRUE;
1475  Double_t pts[8];
1476  Double_t snxt;
1477  Double_t xnew, ynew, znew;
1478  Int_t i,j;
1479  if (point[2]<-fDz+TGeoShape::Tolerance()) {
1480  if (dir[2]<=0) return TGeoShape::Big();
1481  in = kFALSE;
1482  snxt = -(fDz+point[2])/dir[2];
1483  xnew = point[0] + snxt*dir[0];
1484  ynew = point[1] + snxt*dir[1];
1485  for (i=0;i<4;i++) {
1486  j = i<<1;
1487  pts[j] = fXY[i][0];
1488  pts[j+1] = fXY[i][1];
1489  }
1490  if (InsidePolygon(xnew,ynew,pts)) return snxt;
1491  } else if (point[2]>fDz-TGeoShape::Tolerance()) {
1492  if (dir[2]>=0) return TGeoShape::Big();
1493  in = kFALSE;
1494  snxt = (fDz-point[2])/dir[2];
1495  xnew = point[0] + snxt*dir[0];
1496  ynew = point[1] + snxt*dir[1];
1497  for (i=0;i<4;i++) {
1498  j = i<<1;
1499  pts[j] = fXY[i+4][0];
1500  pts[j+1] = fXY[i+4][1];
1501  }
1502  if (InsidePolygon(xnew,ynew,pts)) return snxt;
1503  }
1504  snxt = TGeoShape::Big();
1505 
1506 
1507  // check lateral faces
1508  Double_t dz2 =0.5/fDz;
1509  Double_t xa,xb,xc,xd;
1510  Double_t ya,yb,yc,yd;
1511  Double_t ax,ay,az;
1512  Double_t bx,by;
1513  Double_t ddotn, saf;
1514  Double_t safmin = TGeoShape::Big();
1515  Bool_t exiting = kFALSE;
1516  for (i=0; i<4; i++) {
1517  j = (i+1)%4;
1518  xa=fXY[i][0];
1519  ya=fXY[i][1];
1520  xb=fXY[i+4][0];
1521  yb=fXY[i+4][1];
1522  xc=fXY[j][0];
1523  yc=fXY[j][1];
1524  xd=fXY[4+j][0];
1525  yd=fXY[4+j][1];
1526  ax = xb-xa;
1527  ay = yb-ya;
1528  az = 2.*fDz;
1529  bx = xc-xa;
1530  by = yc-ya;
1531  ddotn = -dir[0]*az*by + dir[1]*az*bx+dir[2]*(ax*by-ay*bx);
1532  saf = (point[0]-xa)*az*by - (point[1]-ya)*az*bx - (point[2]+fDz)*(ax*by-ay*bx);
1533 
1534  if (saf<=0) {
1535  // face visible from point outside
1536  in = kFALSE;
1537  if (ddotn>=0) return TGeoShape::Big();
1538  snxt = saf/ddotn;
1539  znew = point[2]+snxt*dir[2];
1540  if (TMath::Abs(znew)<=fDz) {
1541  xnew = point[0]+snxt*dir[0];
1542  ynew = point[1]+snxt*dir[1];
1543  Double_t tx1 =dz2*(xb-xa);
1544  Double_t ty1 =dz2*(yb-ya);
1545  Double_t tx2 =dz2*(xd-xc);
1546  Double_t ty2 =dz2*(yd-yc);
1547  Double_t dzp =fDz+znew;
1548  Double_t xs1 =xa+tx1*dzp;
1549  Double_t ys1 =ya+ty1*dzp;
1550  Double_t xs2 =xc+tx2*dzp;
1551  Double_t ys2 =yc+ty2*dzp;
1552  if (TMath::Abs(xs1-xs2)>TMath::Abs(ys1-ys2)) {
1553  if ((xnew-xs1)*(xs2-xnew)>=0) return snxt;
1554  } else {
1555  if ((ynew-ys1)*(ys2-ynew)>=0) return snxt;
1556  }
1557  }
1558  } else {
1559  if (saf<safmin) {
1560  safmin = saf;
1561  if (ddotn>=0) exiting = kTRUE;
1562  else exiting = kFALSE;
1563  }
1564  }
1565  }
1566  // Check also Z boundaries (point may be inside and close to Z) - Christian Hammann
1567  saf = fDz - TMath::Abs(point[2]);
1568  if (saf>0 && saf<safmin) exiting = (point[2]*dir[2] > 0)?kTRUE:kFALSE;
1569  if (!in) return TGeoShape::Big();
1570  if (exiting) return TGeoShape::Big();
1571  return 0.0;
1572 }
1573 
1574 ////////////////////////////////////////////////////////////////////////////////
1575 ///--- Divide this trapezoid shape belonging to volume "voldiv" into ndiv volumes
1576 /// called divname, from start position with the given step. Only Z divisions
1577 /// are supported. For Z divisions just return the pointer to the volume to be
1578 /// divided. In case a wrong division axis is supplied, returns pointer to
1579 /// volume that was divided.
1580 
1581 TGeoVolume *TGeoTrap::Divide(TGeoVolume *voldiv, const char *divname, Int_t iaxis, Int_t ndiv,
1582  Double_t start, Double_t step)
1583 {
1584  TGeoShape *shape; //--- shape to be created
1585  TGeoVolume *vol; //--- division volume to be created
1586  TGeoVolumeMulti *vmulti; //--- generic divided volume
1587  TGeoPatternFinder *finder; //--- finder to be attached
1588  TString opt = ""; //--- option to be attached
1589  if (iaxis!=3) {
1590  Error("Divide", "cannot divide trapezoids on other axis than Z");
1591  return 0;
1592  }
1593  Double_t end = start+ndiv*step;
1594  Double_t points_lo[8];
1595  Double_t points_hi[8];
1596  finder = new TGeoPatternTrapZ(voldiv, ndiv, start, end);
1597  voldiv->SetFinder(finder);
1598  finder->SetDivIndex(voldiv->GetNdaughters());
1599  opt = "Z";
1600  vmulti = gGeoManager->MakeVolumeMulti(divname, voldiv->GetMedium());
1601  Double_t txz = ((TGeoPatternTrapZ*)finder)->GetTxz();
1602  Double_t tyz = ((TGeoPatternTrapZ*)finder)->GetTyz();
1603  Double_t zmin, zmax, ox,oy,oz;
1604  for (Int_t idiv=0; idiv<ndiv; idiv++) {
1605  zmin = start+idiv*step;
1606  zmax = start+(idiv+1)*step;
1607  oz = start+idiv*step+step/2;
1608  ox = oz*txz;
1609  oy = oz*tyz;
1610  SetPlaneVertices(zmin, &points_lo[0]);
1611  SetPlaneVertices(zmax, &points_hi[0]);
1612  shape = new TGeoTrap(step/2, fTheta, fPhi);
1613  for (Int_t vert1=0; vert1<4; vert1++)
1614  ((TGeoArb8*)shape)->SetVertex(vert1, points_lo[2*vert1]-ox, points_lo[2*vert1+1]-oy);
1615  for (Int_t vert2=0; vert2<4; vert2++)
1616  ((TGeoArb8*)shape)->SetVertex(vert2+4, points_hi[2*vert2]-ox, points_hi[2*vert2+1]-oy);
1617  vol = new TGeoVolume(divname, shape, voldiv->GetMedium());
1618  vmulti->AddVolume(vol);
1619  voldiv->AddNodeOffset(vol, idiv, oz, opt.Data());
1620  ((TGeoNodeOffset*)voldiv->GetNodes()->At(voldiv->GetNdaughters()-1))->SetFinder(finder);
1621  }
1622  return vmulti;
1623 }
1624 
1625 ////////////////////////////////////////////////////////////////////////////////
1626 /// In case shape has some negative parameters, these have to be computed
1627 /// in order to fit the mother.
1628 
1630 {
1631  if (!TestShapeBit(kGeoRunTimeShape)) return 0;
1632  if (mother->IsRunTimeShape()) {
1633  Error("GetMakeRuntimeShape", "invalid mother");
1634  return 0;
1635  }
1636  Double_t dz, h1, bl1, tl1, h2, bl2, tl2;
1637  if (fDz<0) dz=((TGeoTrap*)mother)->GetDz();
1638  else dz=fDz;
1639 
1640  if (fH1<0) h1 = ((TGeoTrap*)mother)->GetH1();
1641  else h1 = fH1;
1642 
1643  if (fH2<0) h2 = ((TGeoTrap*)mother)->GetH2();
1644  else h2 = fH2;
1645 
1646  if (fBl1<0) bl1 = ((TGeoTrap*)mother)->GetBl1();
1647  else bl1 = fBl1;
1648 
1649  if (fBl2<0) bl2 = ((TGeoTrap*)mother)->GetBl2();
1650  else bl2 = fBl2;
1651 
1652  if (fTl1<0) tl1 = ((TGeoTrap*)mother)->GetTl1();
1653  else tl1 = fTl1;
1654 
1655  if (fTl2<0) tl2 = ((TGeoTrap*)mother)->GetTl2();
1656  else tl2 = fTl2;
1657 
1658  return (new TGeoTrap(dz, fTheta, fPhi, h1, bl1, tl1, fAlpha1, h2, bl2, tl2, fAlpha2));
1659 }
1660 
1661 ////////////////////////////////////////////////////////////////////////////////
1662 /// Computes the closest distance from given point to this shape.
1663 
1664 Double_t TGeoTrap::Safety(const Double_t *point, Bool_t in) const
1665 {
1666  Double_t safe = TGeoShape::Big();
1667  Double_t saf[5];
1668  Double_t norm[3]; // normal to current facette
1669  Int_t i,j; // current facette index
1670  Double_t x0, y0, z0=-fDz, x1, y1, z1=fDz, x2, y2;
1671  Double_t ax, ay, az=z1-z0, bx, by;
1672  Double_t fn;
1673  //---> compute safety for lateral planes
1674  for (i=0; i<4; i++) {
1675  if (in) saf[i] = TGeoShape::Big();
1676  else saf[i] = 0.;
1677  x0 = fXY[i][0];
1678  y0 = fXY[i][1];
1679  x1 = fXY[i+4][0];
1680  y1 = fXY[i+4][1];
1681  ax = x1-x0;
1682  ay = y1-y0;
1683  az = z1-z0;
1684  j = (i+1)%4;
1685  x2 = fXY[j][0];
1686  y2 = fXY[j][1];
1687  bx = x2-x0;
1688  by = y2-y0;
1690  x2 = fXY[4+j][0];
1691  y2 = fXY[4+j][1];
1692  bx = x2-x1;
1693  by = y2-y1;
1694  if (TMath::Abs(bx)<TGeoShape::Tolerance() && TMath::Abs(by)<TGeoShape::Tolerance()) continue;
1695  }
1696  norm[0] = -az*by;
1697  norm[1] = az*bx;
1698  norm[2] = ax*by-ay*bx;
1699  fn = TMath::Sqrt(norm[0]*norm[0]+norm[1]*norm[1]+norm[2]*norm[2]);
1700  if (fn<1E-10) continue;
1701  saf[i] = (x0-point[0])*norm[0]+(y0-point[1])*norm[1]+(-fDz-point[2])*norm[2];
1702  if (in) {
1703  saf[i]=TMath::Abs(saf[i])/fn; // they should be all positive anyway
1704  } else {
1705  saf[i] = -saf[i]/fn; // only negative values are interesting
1706  }
1707  }
1708  saf[4] = fDz-TMath::Abs(point[2]);
1709  if (in) {
1710  safe = saf[0];
1711  for (j=1;j<5;j++) if (saf[j] <safe) safe = saf[j];
1712  } else {
1713  saf[4]=-saf[4];
1714  safe = saf[0];
1715  for (j=1;j<5;j++) if (saf[j] >safe) safe = saf[j];
1716  }
1717  return safe;
1718 }
1719 
1720 ////////////////////////////////////////////////////////////////////////////////
1721 /// Save a primitive as a C++ statement(s) on output stream "out".
1722 
1723 void TGeoTrap::SavePrimitive(std::ostream &out, Option_t * /*option*/ /*= ""*/)
1724 {
1725  if (TObject::TestBit(kGeoSavePrimitive)) return;
1726  out << " // Shape: " << GetName() << " type: " << ClassName() << std::endl;
1727  out << " dz = " << fDz << ";" << std::endl;
1728  out << " theta = " << fTheta << ";" << std::endl;
1729  out << " phi = " << fPhi << ";" << std::endl;
1730  out << " h1 = " << fH1<< ";" << std::endl;
1731  out << " bl1 = " << fBl1<< ";" << std::endl;
1732  out << " tl1 = " << fTl1<< ";" << std::endl;
1733  out << " alpha1 = " << fAlpha1 << ";" << std::endl;
1734  out << " h2 = " << fH2 << ";" << std::endl;
1735  out << " bl2 = " << fBl2<< ";" << std::endl;
1736  out << " tl2 = " << fTl2<< ";" << std::endl;
1737  out << " alpha2 = " << fAlpha2 << ";" << std::endl;
1738  out << " TGeoShape *" << GetPointerName() << " = new TGeoTrap(\"" << GetName() << "\", dz,theta,phi,h1,bl1,tl1,alpha1,h2,bl2,tl2,alpha2);" << std::endl;
1740 }
1741 
1742 ////////////////////////////////////////////////////////////////////////////////
1743 /// Set all arb8 params in one step.
1744 /// param[0] = dz
1745 /// param[1] = theta
1746 /// param[2] = phi
1747 /// param[3] = h1
1748 /// param[4] = bl1
1749 /// param[5] = tl1
1750 /// param[6] = alpha1
1751 /// param[7] = h2
1752 /// param[8] = bl2
1753 /// param[9] = tl2
1754 /// param[10] = alpha2
1755 
1757 {
1758  fDz = param[0];
1759  fTheta = param[1];
1760  fPhi = param[2];
1761  fH1 = param[3];
1762  fH2 = param[7];
1763  fBl1 = param[4];
1764  fBl2 = param[8];
1765  fTl1 = param[5];
1766  fTl2 = param[9];
1767  fAlpha1 = param[6];
1768  fAlpha2 = param[10];
1773  fXY[0][0] = -fDz*tx-fH1*ta1-fBl1; fXY[0][1] = -fDz*ty-fH1;
1774  fXY[1][0] = -fDz*tx+fH1*ta1-fTl1; fXY[1][1] = -fDz*ty+fH1;
1775  fXY[2][0] = -fDz*tx+fH1*ta1+fTl1; fXY[2][1] = -fDz*ty+fH1;
1776  fXY[3][0] = -fDz*tx-fH1*ta1+fBl1; fXY[3][1] = -fDz*ty-fH1;
1777  fXY[4][0] = fDz*tx-fH2*ta2-fBl2; fXY[4][1] = fDz*ty-fH2;
1778  fXY[5][0] = fDz*tx+fH2*ta2-fTl2; fXY[5][1] = fDz*ty+fH2;
1779  fXY[6][0] = fDz*tx+fH2*ta2+fTl2; fXY[6][1] = fDz*ty+fH2;
1780  fXY[7][0] = fDz*tx-fH2*ta2+fBl2; fXY[7][1] = fDz*ty-fH2;
1781  ComputeTwist();
1782  if ((fDz<0) || (fH1<0) || (fBl1<0) || (fTl1<0) ||
1783  (fH2<0) || (fBl2<0) || (fTl2<0)) {
1785  }
1786  else TGeoArb8::ComputeBBox();
1787 }
1788 
1789 ////////////////////////////////////////////////////////////////////////////////
1790 /// Compute distance from array of input points having directions specisied by dirs. Store output in dists
1791 
1792 void TGeoTrap::DistFromInside_v(const Double_t *points, const Double_t *dirs, Double_t *dists, Int_t vecsize, Double_t* step) const
1793 {
1794  for (Int_t i=0; i<vecsize; i++) dists[i] = DistFromInside(&points[3*i], &dirs[3*i], 3, step[i]);
1795 }
1796 
1797 ////////////////////////////////////////////////////////////////////////////////
1798 /// Compute distance from array of input points having directions specisied by dirs. Store output in dists
1799 
1800 void TGeoTrap::DistFromOutside_v(const Double_t *points, const Double_t *dirs, Double_t *dists, Int_t vecsize, Double_t* step) const
1801 {
1802  for (Int_t i=0; i<vecsize; i++) dists[i] = DistFromOutside(&points[3*i], &dirs[3*i], 3, step[i]);
1803 }
1804 
1805 ////////////////////////////////////////////////////////////////////////////////
1806 /// Compute safe distance from each of the points in the input array.
1807 /// Input: Array of point coordinates, array of statuses for these points, size of the arrays
1808 /// Output: Safety values
1809 
1810 void TGeoTrap::Safety_v(const Double_t *points, const Bool_t *inside, Double_t *safe, Int_t vecsize) const
1811 {
1812  for (Int_t i=0; i<vecsize; i++) safe[i] = Safety(&points[3*i], inside[i]);
1813 }
1814 
1816 
1817 ////////////////////////////////////////////////////////////////////////////////
1818 /// Default ctor
1819 
1820 TGeoGtra::TGeoGtra()
1821 {
1822  fTwistAngle = 0;
1823 
1824 }
1825 
1826 ////////////////////////////////////////////////////////////////////////////////
1827 /// Constructor.
1828 
1830  Double_t bl1, Double_t tl1, Double_t alpha1, Double_t h2, Double_t bl2,
1831  Double_t tl2, Double_t alpha2)
1832  :TGeoTrap(dz, theta, phi, h1, bl1, tl1, alpha1, h2, bl2, tl2, alpha2)
1833 {
1834  fTwistAngle = twist;
1835  Double_t x,y;
1836  Double_t th = theta*TMath::DegToRad();
1837  Double_t ph = phi*TMath::DegToRad();
1838  // Coordinates of the center of the bottom face
1839  Double_t xc = -dz*TMath::Sin(th)*TMath::Cos(ph);
1840  Double_t yc = -dz*TMath::Sin(th)*TMath::Sin(ph);
1841 
1842  Int_t i;
1843 
1844  for (i=0; i<4; i++) {
1845  x = fXY[i][0] - xc;
1846  y = fXY[i][1] - yc;
1847  fXY[i][0] = x*TMath::Cos(-0.5*twist*TMath::DegToRad()) + y*TMath::Sin(-0.5*twist*TMath::DegToRad()) + xc;
1848  fXY[i][1] = -x*TMath::Sin(-0.5*twist*TMath::DegToRad()) + y*TMath::Cos(-0.5*twist*TMath::DegToRad()) + yc;
1849  }
1850  // Coordinates of the center of the top face
1851  xc = -xc;
1852  yc = -yc;
1853  for (i=4; i<8; i++) {
1854  x = fXY[i][0] - xc;
1855  y = fXY[i][1] - yc;
1856  fXY[i][0] = x*TMath::Cos(0.5*twist*TMath::DegToRad()) + y*TMath::Sin(0.5*twist*TMath::DegToRad()) + xc;
1857  fXY[i][1] = -x*TMath::Sin(0.5*twist*TMath::DegToRad()) + y*TMath::Cos(0.5*twist*TMath::DegToRad()) + yc;
1858  }
1859  ComputeTwist();
1860  if ((dz<0) || (h1<0) || (bl1<0) || (tl1<0) ||
1861  (h2<0) || (bl2<0) || (tl2<0)) SetShapeBit(kGeoRunTimeShape);
1862  else TGeoArb8::ComputeBBox();
1863 }
1864 
1865 ////////////////////////////////////////////////////////////////////////////////
1866 /// Constructor providing the name of the shape.
1867 
1869  Double_t bl1, Double_t tl1, Double_t alpha1, Double_t h2, Double_t bl2,
1870  Double_t tl2, Double_t alpha2)
1871  :TGeoTrap(name, dz, theta, phi, h1, bl1, tl1, alpha1, h2, bl2, tl2, alpha2)
1872 {
1873  fTwistAngle = twist;
1874  Double_t x,y;
1875  Double_t th = theta*TMath::DegToRad();
1876  Double_t ph = phi*TMath::DegToRad();
1877  // Coordinates of the center of the bottom face
1878  Double_t xc = -dz*TMath::Sin(th)*TMath::Cos(ph);
1879  Double_t yc = -dz*TMath::Sin(th)*TMath::Sin(ph);
1880 
1881  Int_t i;
1882 
1883  for (i=0; i<4; i++) {
1884  x = fXY[i][0] - xc;
1885  y = fXY[i][1] - yc;
1886  fXY[i][0] = x*TMath::Cos(-0.5*twist*TMath::DegToRad()) + y*TMath::Sin(-0.5*twist*TMath::DegToRad()) + xc;
1887  fXY[i][1] = -x*TMath::Sin(-0.5*twist*TMath::DegToRad()) + y*TMath::Cos(-0.5*twist*TMath::DegToRad()) + yc;
1888  }
1889  // Coordinates of the center of the top face
1890  xc = -xc;
1891  yc = -yc;
1892  for (i=4; i<8; i++) {
1893  x = fXY[i][0] - xc;
1894  y = fXY[i][1] - yc;
1895  fXY[i][0] = x*TMath::Cos(0.5*twist*TMath::DegToRad()) + y*TMath::Sin(0.5*twist*TMath::DegToRad()) + xc;
1896  fXY[i][1] = -x*TMath::Sin(0.5*twist*TMath::DegToRad()) + y*TMath::Cos(0.5*twist*TMath::DegToRad()) + yc;
1897  }
1898  ComputeTwist();
1899  if ((dz<0) || (h1<0) || (bl1<0) || (tl1<0) ||
1900  (h2<0) || (bl2<0) || (tl2<0)) SetShapeBit(kGeoRunTimeShape);
1901  else TGeoArb8::ComputeBBox();
1902 }
1903 
1904 ////////////////////////////////////////////////////////////////////////////////
1905 /// Destructor.
1906 
1908 {
1909 }
1910 
1911 ////////////////////////////////////////////////////////////////////////////////
1912 /// Compute distance from inside point to surface of the shape.
1913 
1914 Double_t TGeoGtra::DistFromInside(const Double_t *point, const Double_t *dir, Int_t iact, Double_t step, Double_t *safe) const
1915 {
1916  if (iact<3 && safe) {
1917  // compute safe distance
1918  *safe = Safety(point, kTRUE);
1919  if (iact==0) return TGeoShape::Big();
1920  if (iact==1 && step<*safe) return TGeoShape::Big();
1921  }
1922  // compute distance to get ouside this shape
1923  return TGeoArb8::DistFromInside(point, dir, iact, step, safe);
1924 }
1925 
1926 ////////////////////////////////////////////////////////////////////////////////
1927 /// Compute distance from inside point to surface of the shape.
1928 
1929 Double_t TGeoGtra::DistFromOutside(const Double_t *point, const Double_t *dir, Int_t iact, Double_t step, Double_t *safe) const
1930 {
1931  if (iact<3 && safe) {
1932  // compute safe distance
1933  *safe = Safety(point, kTRUE);
1934  if (iact==0) return TGeoShape::Big();
1935  if (iact==1 && step<*safe) return TGeoShape::Big();
1936  }
1937  // compute distance to get ouside this shape
1938  return TGeoArb8::DistFromOutside(point, dir, iact, step, safe);
1939 }
1940 
1941 ////////////////////////////////////////////////////////////////////////////////
1942 /// In case shape has some negative parameters, these has to be computed
1943 /// in order to fit the mother
1944 
1946 {
1947  if (!TestShapeBit(kGeoRunTimeShape)) return 0;
1948  if (mother->IsRunTimeShape()) {
1949  Error("GetMakeRuntimeShape", "invalid mother");
1950  return 0;
1951  }
1952  Double_t dz, h1, bl1, tl1, h2, bl2, tl2;
1953  if (fDz<0) dz=((TGeoTrap*)mother)->GetDz();
1954  else dz=fDz;
1955  if (fH1<0)
1956  h1 = ((TGeoTrap*)mother)->GetH1();
1957  else
1958  h1 = fH1;
1959  if (fH2<0)
1960  h2 = ((TGeoTrap*)mother)->GetH2();
1961  else
1962  h2 = fH2;
1963  if (fBl1<0)
1964  bl1 = ((TGeoTrap*)mother)->GetBl1();
1965  else
1966  bl1 = fBl1;
1967  if (fBl2<0)
1968  bl2 = ((TGeoTrap*)mother)->GetBl2();
1969  else
1970  bl2 = fBl2;
1971  if (fTl1<0)
1972  tl1 = ((TGeoTrap*)mother)->GetTl1();
1973  else
1974  tl1 = fTl1;
1975  if (fTl2<0)
1976  tl2 = ((TGeoTrap*)mother)->GetTl2();
1977  else
1978  tl2 = fTl2;
1979  return (new TGeoGtra(dz, fTheta, fPhi, fTwistAngle ,h1, bl1, tl1, fAlpha1, h2, bl2, tl2, fAlpha2));
1980 }
1981 
1982 ////////////////////////////////////////////////////////////////////////////////
1983 /// Computes the closest distance from given point to this shape.
1984 
1985 Double_t TGeoGtra::Safety(const Double_t *point, Bool_t in) const
1986 {
1987  return TGeoArb8::Safety(point,in);
1988 }
1989 
1990 ////////////////////////////////////////////////////////////////////////////////
1991 /// Save a primitive as a C++ statement(s) on output stream "out".
1992 
1993 void TGeoGtra::SavePrimitive(std::ostream &out, Option_t * /*option*/ /*= ""*/)
1994 {
1995  if (TObject::TestBit(kGeoSavePrimitive)) return;
1996  out << " // Shape: " << GetName() << " type: " << ClassName() << std::endl;
1997  out << " dz = " << fDz << ";" << std::endl;
1998  out << " theta = " << fTheta << ";" << std::endl;
1999  out << " phi = " << fPhi << ";" << std::endl;
2000  out << " twist = " << fTwistAngle << ";" << std::endl;
2001  out << " h1 = " << fH1<< ";" << std::endl;
2002  out << " bl1 = " << fBl1<< ";" << std::endl;
2003  out << " tl1 = " << fTl1<< ";" << std::endl;
2004  out << " alpha1 = " << fAlpha1 << ";" << std::endl;
2005  out << " h2 = " << fH2 << ";" << std::endl;
2006  out << " bl2 = " << fBl2<< ";" << std::endl;
2007  out << " tl2 = " << fTl2<< ";" << std::endl;
2008  out << " alpha2 = " << fAlpha2 << ";" << std::endl;
2009  out << " TGeoShape *" << GetPointerName() << " = new TGeoGtra(\"" << GetName() << "\", dz,theta,phi,twist,h1,bl1,tl1,alpha1,h2,bl2,tl2,alpha2);" << std::endl;
2011 }
2012 
2013 ////////////////////////////////////////////////////////////////////////////////
2014 /// Set all arb8 params in one step.
2015 /// param[0] = dz
2016 /// param[1] = theta
2017 /// param[2] = phi
2018 /// param[3] = h1
2019 /// param[4] = bl1
2020 /// param[5] = tl1
2021 /// param[6] = alpha1
2022 /// param[7] = h2
2023 /// param[8] = bl2
2024 /// param[9] = tl2
2025 /// param[10] = alpha2
2026 /// param[11] = twist
2027 
2029 {
2030  TGeoTrap::SetDimensions(param);
2031  fTwistAngle = param[11];
2032  Double_t x,y;
2033  Double_t twist = fTwistAngle;
2035  Double_t ph = fPhi*TMath::DegToRad();
2036  // Coordinates of the center of the bottom face
2037  Double_t xc = -fDz*TMath::Sin(th)*TMath::Cos(ph);
2038  Double_t yc = -fDz*TMath::Sin(th)*TMath::Sin(ph);
2039 
2040  Int_t i;
2041 
2042  for (i=0; i<4; i++) {
2043  x = fXY[i][0] - xc;
2044  y = fXY[i][1] - yc;
2045  fXY[i][0] = x*TMath::Cos(-0.5*twist*TMath::DegToRad()) + y*TMath::Sin(-0.5*twist*TMath::DegToRad()) + xc;
2046  fXY[i][1] = -x*TMath::Sin(-0.5*twist*TMath::DegToRad()) + y*TMath::Cos(-0.5*twist*TMath::DegToRad()) + yc;
2047  }
2048  // Coordinates of the center of the top face
2049  xc = -xc;
2050  yc = -yc;
2051  for (i=4; i<8; i++) {
2052  x = fXY[i][0] - xc;
2053  y = fXY[i][1] - yc;
2054  fXY[i][0] = x*TMath::Cos(0.5*twist*TMath::DegToRad()) + y*TMath::Sin(0.5*twist*TMath::DegToRad()) + xc;
2055  fXY[i][1] = -x*TMath::Sin(0.5*twist*TMath::DegToRad()) + y*TMath::Cos(0.5*twist*TMath::DegToRad()) + yc;
2056  }
2057  ComputeTwist();
2058  if ((fDz<0) || (fH1<0) || (fBl1<0) || (fTl1<0) ||
2059  (fH2<0) || (fBl2<0) || (fTl2<0)) SetShapeBit(kGeoRunTimeShape);
2060  else TGeoArb8::ComputeBBox();
2061 }
2062 
2063 ////////////////////////////////////////////////////////////////////////////////
2064 /// Compute distance from array of input points having directions specisied by dirs. Store output in dists
2065 
2066 void TGeoGtra::DistFromInside_v(const Double_t *points, const Double_t *dirs, Double_t *dists, Int_t vecsize, Double_t* step) const
2067 {
2068  for (Int_t i=0; i<vecsize; i++) dists[i] = DistFromInside(&points[3*i], &dirs[3*i], 3, step[i]);
2069 }
2070 
2071 ////////////////////////////////////////////////////////////////////////////////
2072 /// Compute distance from array of input points having directions specisied by dirs. Store output in dists
2073 
2074 void TGeoGtra::DistFromOutside_v(const Double_t *points, const Double_t *dirs, Double_t *dists, Int_t vecsize, Double_t* step) const
2075 {
2076  for (Int_t i=0; i<vecsize; i++) dists[i] = DistFromOutside(&points[3*i], &dirs[3*i], 3, step[i]);
2077 }
2078 
2079 ////////////////////////////////////////////////////////////////////////////////
2080 /// Compute safe distance from each of the points in the input array.
2081 /// Input: Array of point coordinates, array of statuses for these points, size of the arrays
2082 /// Output: Safety values
2083 
2084 void TGeoGtra::Safety_v(const Double_t *points, const Bool_t *inside, Double_t *safe, Int_t vecsize) const
2085 {
2086  for (Int_t i=0; i<vecsize; i++) safe[i] = Safety(&points[3*i], inside[i]);
2087 }
TGeoVolumeMulti * MakeVolumeMulti(const char *name, TGeoMedium *medium)
Make a TGeoVolumeMulti handling a list of volumes.
virtual void SetPoints(Double_t *points) const
Creates arb8 mesh points.
Definition: TGeoArb8.cxx:1186
Double_t SafetyToFace(const Double_t *point, Int_t iseg, Bool_t in) const
Estimate safety to lateral plane defined by segment iseg in range [0,3] Might be negative: plane seen...
Definition: TGeoArb8.cxx:1089
Bool_t IsRunTimeShape() const
Definition: TGeoShape.h:148
double dist(Rotation3D const &r1, Rotation3D const &r2)
Definition: 3DDistances.cxx:48
void SetPlaneVertices(Double_t zpl, Double_t *vertices) const
Computes intersection points between plane at zpl and non-horizontal edges.
Definition: TGeoArb8.cxx:1156
float xmin
Definition: THbookFile.cxx:93
virtual Int_t WriteClassBuffer(const TClass *cl, void *pointer)=0
#define snext(osub1, osub2)
Definition: triangle.c:1167
Long64_t LocMax(Long64_t n, const T *a)
Definition: TMath.h:724
const Double_t * v1
Definition: TArcBall.cxx:33
static double p3(double t, double a, double b, double c, double d)
virtual ~TGeoGtra()
Destructor.
Definition: TGeoArb8.cxx:1907
T1 Sign(T1 a, T2 b)
Definition: TMathBase.h:155
void SetFinder(TGeoPatternFinder *finder)
Definition: TGeoVolume.h:247
Bool_t IsReading() const
Definition: TBuffer.h:83
virtual TGeoVolume * Divide(TGeoVolume *voldiv, const char *divname, Int_t iaxis, Int_t ndiv, Double_t start, Double_t step)
Divide this shape along one axis.
Definition: TGeoArb8.cxx:788
TVector3 cross(const TVector3 &v1, const TVector3 &v2)
Definition: CsgOps.cxx:816
float Float_t
Definition: RtypesCore.h:53
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
Float_t theta
Definition: shapesAnim.C:5
return c
const char Option_t
Definition: RtypesCore.h:62
virtual void SavePrimitive(std::ostream &out, Option_t *option="")
Save a primitive as a C++ statement(s) on output stream "out".
Definition: TGeoArb8.cxx:1723
float ymin
Definition: THbookFile.cxx:93
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: TGeoArb8.cxx:1286
virtual Double_t Safety(const Double_t *point, Bool_t in=kTRUE) const
Computes the closest distance from given point to this shape.
Definition: TGeoArb8.cxx:1985
virtual void SetName(const char *name)
Change (i.e.
Definition: TNamed.cxx:128
Double_t DegToRad()
Definition: TMath.h:50
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: TGeoArb8.cxx:1250
Buffer base class used for serializing objects.
Definition: TBuffer.h:42
Double_t fOrigin[3]
Definition: TGeoBBox.h:36
Double_t fBl1
Definition: TGeoArb8.h:138
Basic string class.
Definition: TString.h:137
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
virtual Double_t GetDY() const
Definition: TGeoBBox.h:83
static const float upper
Definition: main.cpp:49
virtual Bool_t GetPointsOnFacet(Int_t, Int_t, Double_t *) const
Fills array with n random points located on the surface of indexed facet.
Definition: TGeoArb8.cxx:920
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
Bool_t IsRotation() const
Definition: TGeoMatrix.h:79
virtual Double_t GetDZ() const
Definition: TGeoBBox.h:84
Short_t Abs(Short_t d)
Definition: TMathBase.h:110
Int_t GetNdaughters() const
Definition: TGeoVolume.h:362
Double_t GetTwist(Int_t iseg) const
Get twist for segment I in range [0,3].
Definition: TGeoArb8.cxx:345
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
tuple xs2
Definition: hsum.py:47
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 trapezoid.
Definition: TGeoArb8.cxx:1409
TObjArray * GetNodes()
Definition: TGeoVolume.h:183
static Double_t Tolerance()
Definition: TGeoShape.h:101
virtual void SavePrimitive(std::ostream &out, Option_t *option="")
Save a primitive as a C++ statement(s) on output stream "out".
Definition: TGeoArb8.cxx:1993
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
static const double x2[5]
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: TGeoArb8.cxx:1810
Double_t x[n]
Definition: legend1.C:17
Double_t fDZ
Definition: TGeoBBox.h:35
Double_t DistToPlane(const Double_t *point, const Double_t *dir, Int_t ipl, Bool_t in) const
Computes distance to plane ipl : ipl=0 : points 0,4,1,5 ipl=1 : points 1,5,2,6 ipl=2 : points 2...
Definition: TGeoArb8.cxx:513
void AddVolume(TGeoVolume *vol)
Add a volume with valid shape to the list of volumes.
void Class()
Definition: Class.C:29
int d
Definition: tornado.py:11
static double p2(double t, double a, double b, double c)
Double_t fXY[8][2]
[4] tangents of twist angles
Definition: TGeoArb8.h:56
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: TGeoArb8.cxx:1800
virtual void SetVertex(Int_t vnum, Double_t x, Double_t y)
Set values for a given vertex.
Definition: TGeoArb8.cxx:1210
Double_t fTl1
Definition: TGeoArb8.h:139
Double_t fAlpha1
Definition: TGeoArb8.h:140
TH2D * h2
Definition: fit2dHist.C:45
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition: TObject.cxx:918
virtual void ComputeBBox()
Computes bounding box for an Arb8 shape.
Definition: TGeoArb8.cxx:227
TH1F * h1
Definition: legend1.C:5
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 inside point to surface of the shape.
Definition: TGeoArb8.cxx:1929
char * out
Definition: TBase64.cxx:29
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: TGeoArb8.cxx:1260
virtual Int_t GetFittingBox(const TGeoBBox *parambox, TGeoMatrix *mat, Double_t &dx, Double_t &dy, Double_t &dz) const
Fills real parameters of a positioned box inside this arb8. Returns 0 if successfull.
Definition: TGeoArb8.cxx:835
virtual const Double_t * GetOrigin() const
Definition: TGeoBBox.h:85
Double_t fDz
Definition: TGeoArb8.h:54
virtual TGeoShape * GetMakeRuntimeShape(TGeoShape *mother, TGeoMatrix *mat) const
In case shape has some negative parameters, these have to be computed in order to fit the mother...
Definition: TGeoArb8.cxx:1629
virtual void ComputeNormal(const Double_t *point, const Double_t *dir, Double_t *norm)
Compute normal to closest surface from POINT.
Definition: TGeoArb8.cxx:424
point * points
Definition: X3DBuffer.c:20
static Bool_t IsSegCrossing(Double_t x1, Double_t y1, Double_t x2, Double_t y2, Double_t x3, Double_t y3, Double_t x4, Double_t y4)
Check if segments (A,B) and (C,D) are crossing, where: A(x1,y1), B(x2,y2), C(x3,y3), D(x4,y4)
Definition: TGeoShape.cxx:335
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: TGeoArb8.cxx:2084
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 trapezoid.
Definition: TGeoArb8.cxx:1462
virtual Double_t GetDX() const
Definition: TGeoBBox.h:82
float ymax
Definition: THbookFile.cxx:93
virtual void InspectShape() const
Prints shape parameters.
Definition: TGeoArb8.cxx:996
TNamed & operator=(const TNamed &rhs)
TNamed assignment operator.
Definition: TNamed.cxx:40
TPaveText * pt
virtual ~TGeoTrap()
destructor
Definition: TGeoArb8.cxx:1402
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 shape.
Definition: TGeoArb8.cxx:662
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: TGeoArb8.cxx:2074
static Bool_t InsidePolygon(Double_t x, Double_t y, Double_t *pts)
Finds if a point in XY plane is inside the polygon defines by PTS.
Definition: TGeoArb8.cxx:976
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 shape.
Definition: TGeoArb8.cxx:1914
Double_t fPhi
Definition: TGeoArb8.h:136
Double_t fAlpha2
Definition: TGeoArb8.h:144
virtual const char * ClassName() const
Returns name of class to which the object belongs.
Definition: TObject.cxx:187
virtual Double_t Safety(const Double_t *point, Bool_t in=kTRUE) const
Computes the closest distance from given point to this shape.
Definition: TGeoArb8.cxx:1011
virtual void LocalToMaster(const Double_t *local, Double_t *master) const
convert a point by multiplying its column vector (x, y, z, 1) to matrix inverse
Definition: TGeoMatrix.cxx:346
void ComputeTwist()
Computes tangents of twist angles (angles between projections on XY plane of corresponding -dz +dz ed...
Definition: TGeoArb8.cxx:253
Double_t fTheta
Definition: TGeoArb8.h:135
Bool_t TestBit(UInt_t f) const
Definition: TObject.h:173
Double_t fH2
Definition: TGeoArb8.h:141
Bool_t IsTwisted() const
Definition: TGeoArb8.h:100
virtual void SavePrimitive(std::ostream &out, Option_t *option="")
Save a primitive as a C++ statement(s) on output stream "out".
Definition: TGeoArb8.cxx:1128
Double_t E()
Definition: TMath.h:54
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: TGeoArb8.cxx:2066
static Bool_t IsSamePoint(const Double_t *p1, const Double_t *p2)
Definition: TGeoArb8.h:97
static double p1(double t, double a, double b)
float xmax
Definition: THbookFile.cxx:93
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
Computes distance from outside point to surface of the shape.
Definition: TGeoArb8.cxx:634
virtual Double_t Safety(const Double_t *point, Bool_t in=kTRUE) const
Computes the closest distance from given point to this shape.
Definition: TGeoBBox.cxx:811
void SetDivIndex(Int_t index)
ClassImp(TGeoArb8) TGeoArb8
Default ctor.
Definition: TGeoArb8.cxx:21
virtual const char * GetName() const
Get the shape name.
Definition: TGeoShape.cxx:247
virtual Bool_t Contains(const Double_t *point) const
Test if point is inside this shape.
Definition: TGeoArb8.cxx:490
Double_t GetClosestEdge(const Double_t *point, Double_t *vert, Int_t &isegment) const
Get index of the edge of the quadrilater represented by vert closest to point.
Definition: TGeoArb8.cxx:357
Double_t Cos(Double_t)
Definition: TMath.h:424
Float_t phi
Definition: shapesAnim.C:6
virtual Int_t ReadClassBuffer(const TClass *cl, void *pointer, const TClass *onfile_class=0)=0
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: TGeoArb8.cxx:1792
virtual void Sizeof3D() const
Fill size of this 3-D object.
Definition: TGeoArb8.cxx:1227
virtual void InspectShape() const
Prints shape parameters.
Definition: TGeoBBox.cxx:749
static const double x1[5]
R__EXTERN TGeoManager * gGeoManager
Definition: TGeoManager.h:556
Double_t fTwistAngle
Definition: TGeoArb8.h:204
double Double_t
Definition: RtypesCore.h:55
virtual Double_t Capacity() const
Computes capacity of the shape in [length^3].
Definition: TGeoArb8.cxx:210
ClassImp(TMCParticle) void TMCParticle printf(": p=(%7.3f,%7.3f,%9.3f) ;", fPx, fPy, fPz)
void dir(char *path=0)
Definition: rootalias.C:30
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: TGeoArb8.cxx:1268
Double_t y[n]
Definition: legend1.C:17
const char * GetPointerName() const
Provide a pointer name containing uid.
Definition: TGeoShape.cxx:698
static Double_t Big()
Definition: TGeoShape.h:98
static void GetPlaneNormal(Double_t *p1, Double_t *p2, Double_t *p3, Double_t *norm)
Computes normal to plane defined by P1, P2 and P3.
Definition: TGeoArb8.cxx:892
virtual Double_t Safety(const Double_t *point, Bool_t in=kTRUE) const
Computes the closest distance from given point to this shape.
Definition: TGeoArb8.cxx:1664
Double_t fDY
Definition: TGeoBBox.h:34
#define name(a, b)
Definition: linkTestLib0.cpp:5
void SetShapeBit(UInt_t f, Bool_t set)
Equivalent of TObject::SetBit.
Definition: TGeoShape.cxx:523
virtual ~TGeoArb8()
Destructor.
Definition: TGeoArb8.cxx:202
Bool_t TestShapeBit(UInt_t f) const
Definition: TGeoShape.h:172
Double_t fH1
Definition: TGeoArb8.h:137
TGeoMedium * GetMedium() const
Definition: TGeoVolume.h:189
Short_t Max(Short_t a, Short_t b)
Definition: TMathBase.h:202
virtual void GetBoundingCylinder(Double_t *param) const
— Fill vector param[4] with the bounding cylinder parameters.
Definition: TGeoArb8.cxx:817
Double_t Sin(Double_t)
Definition: TMath.h:421
tuple xs1
Definition: hsum.py:46
Double_t fDX
Definition: TGeoBBox.h:33
Double_t fTl2
Definition: TGeoArb8.h:143
TGeoArb8 & operator=(const TGeoArb8 &)
assignment operator
Definition: TGeoArb8.cxx:185
Double_t fBl2
Definition: TGeoArb8.h:142
Double_t Sqrt(Double_t x)
Definition: TMath.h:464
TObject * At(Int_t idx) const
Definition: TObjArray.h:167
virtual void SetDimensions(Double_t *param)
Set all arb8 params in one step.
Definition: TGeoArb8.cxx:1172
virtual void SetDimensions(Double_t *param)
Set all arb8 params in one step.
Definition: TGeoArb8.cxx:2028
virtual void Sizeof3D() const
Definition: TGeoBBox.cxx:952
virtual TGeoVolume * Divide(TGeoVolume *voldiv, const char *divname, Int_t iaxis, Int_t ndiv, Double_t start, Double_t step)
— Divide this trapezoid shape belonging to volume "voldiv" into ndiv volumes called divname...
Definition: TGeoArb8.cxx:1581
Long64_t LocMin(Long64_t n, const T *a)
Definition: TMath.h:695
const Bool_t kTRUE
Definition: Rtypes.h:91
double norm(double *x, double *p)
Definition: unuranDistr.cxx:40
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: TGeoArb8.cxx:1276
virtual Bool_t Contains(const Double_t *point) const
Test if point is inside this shape.
Definition: TGeoBBox.cxx:296
Double_t Tan(Double_t)
Definition: TMath.h:427
virtual void SetDimensions(Double_t *param)
Set all arb8 params in one step.
Definition: TGeoArb8.cxx:1756
static const float lower
Definition: main.cpp:48
Double_t * fTwist
Definition: TGeoArb8.h:55
virtual Double_t GetAxisRange(Int_t iaxis, Double_t &xlo, Double_t &xhi) const
Get shape range on a given axis.
Definition: TGeoArb8.cxx:798
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: TGeoArb8.cxx:1945