ROOT  6.06/09
Reference Guide
TGeoTrd1.cxx
Go to the documentation of this file.
1 // @(#)root/geom:$Id$
2 // Author: Andrei Gheata 24/10/01
3 // TGeoTrd1::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 // TGeoTrd1 - a trapezoid with only x length varying with z. It has 4
15 // parameters, the half length in x at the low z surface, that at the
16 // high z surface, the half length in y, and in z
17 //
18 //_____________________________________________________________________________
19 //Begin_Html
20 /*
21 <img src="gif/t_trd1.gif">
22 */
23 //End_Html
24 
25 //Begin_Html
26 /*
27 <img src="gif/t_trd1divY.gif">
28 */
29 //End_Html
30 
31 //Begin_Html
32 /*
33 <img src="gif/t_trd1divZ.gif">
34 */
35 //End_Html
36 
37 //Begin_Html
38 /*
39 <img src="gif/t_trd1divstepZ.gif">
40 */
41 //End_Html
42 
43 #include "Riostream.h"
44 
45 #include "TGeoManager.h"
46 #include "TGeoMatrix.h"
47 #include "TGeoVolume.h"
48 #include "TGeoTrd1.h"
49 #include "TMath.h"
50 
52 
53 ////////////////////////////////////////////////////////////////////////////////
54 /// dummy ctor
55 
57 {
58  fDz = fDx1 = fDx2 = fDy = 0;
59  SetShapeBit(kGeoTrd1);
60 }
61 
62 ////////////////////////////////////////////////////////////////////////////////
63 /// constructor.
64 
66  :TGeoBBox(0,0,0)
67 {
69  fDx1 = dx1;
70  fDx2 = dx2;
71  fDy = dy;
72  fDz = dz;
73  if ((dx1<0) || (dx2<0) || (dy<0) || (dz<0)) {
75  printf("trd1 : dx1=%f, dx2=%f, dy=%f, dz=%f\n",
76  dx1,dx2,dy,dz);
77  }
78  else ComputeBBox();
79 }
80 
81 ////////////////////////////////////////////////////////////////////////////////
82 /// constructor.
83 
84 TGeoTrd1::TGeoTrd1(const char *name, Double_t dx1, Double_t dx2, Double_t dy, Double_t dz)
85  :TGeoBBox(name, 0,0,0)
86 {
88  fDx1 = dx1;
89  fDx2 = dx2;
90  fDy = dy;
91  fDz = dz;
92  if ((dx1<0) || (dx2<0) || (dy<0) || (dz<0)) {
94  printf("trd1 : dx1=%f, dx2=%f, dy=%f, dz=%f\n",
95  dx1,dx2,dy,dz);
96  }
97  else ComputeBBox();
98 }
99 
100 ////////////////////////////////////////////////////////////////////////////////
101 /// ctor with an array of parameters
102 /// param[0] = dx1
103 /// param[1] = dx2
104 /// param[2] = dy
105 /// param[3] = dz
106 
108  :TGeoBBox(0,0,0)
109 {
111  SetDimensions(param);
112  if ((fDx1<0) || (fDx2<0) || (fDy<=0) || (fDz<=0)) SetShapeBit(kGeoRunTimeShape);
113  else ComputeBBox();
114 }
115 
116 ////////////////////////////////////////////////////////////////////////////////
117 /// destructor
118 
120 {
121 }
122 
123 ////////////////////////////////////////////////////////////////////////////////
124 /// Computes capacity of the shape in [length^3]
125 
127 {
128  Double_t capacity = 4.*(fDx1+fDx2)*fDy*fDz;
129  return capacity;
130 }
131 
132 ////////////////////////////////////////////////////////////////////////////////
133 /// compute bounding box for a trd1
134 
136 {
137  fDX = TMath::Max(fDx1, fDx2);
138  fDY = fDy;
139  fDZ = fDz;
140  memset(fOrigin, 0, 3*sizeof(Double_t));
141 }
142 
143 ////////////////////////////////////////////////////////////////////////////////
144 /// Compute normal to closest surface from POINT.
145 
146 void TGeoTrd1::ComputeNormal(const Double_t *point, const Double_t *dir, Double_t *norm)
147 {
148  Double_t safe, safemin;
149  //--- Compute safety first
150  Double_t fx = 0.5*(fDx1-fDx2)/fDz;
151  Double_t calf = 1./TMath::Sqrt(1.0+fx*fx);
152  // check Z facettes
153  safe = safemin = TMath::Abs(fDz-TMath::Abs(point[2]));
154  norm[0] = norm[1] = 0;
155  norm[2] = (dir[2]>=0)?1:-1;
156  if (safe<1E-6) return;
157  // check X facettes
158  Double_t distx = 0.5*(fDx1+fDx2)-fx*point[2];
159  if (distx>=0) {
160  safe=TMath::Abs(distx-TMath::Abs(point[0]))*calf;
161  if (safe<safemin) {
162  safemin = safe;
163  norm[0] = (point[0]>0)?calf:(-calf);
164  norm[1] = 0;
165  norm[2] = calf*fx;
166  Double_t dot = norm[0]*dir[0]+norm[1]*dir[1]+norm[2]*dir[2];
167  if (dot<0) {
168  norm[0] = -norm[0];
169  norm[2] = -norm[2];
170  }
171  if (safe<1E-6) return;
172  }
173  }
174  // check Y facettes
175  safe = TMath::Abs(fDy-TMath::Abs(point[1]));
176  if (safe<safemin) {
177  norm[0] = norm[2] = 0;
178  norm[1] = (dir[1]>=0)?1:-1;
179  }
180 }
181 
182 ////////////////////////////////////////////////////////////////////////////////
183 /// test if point is inside this shape
184 /// check Z range
185 
186 Bool_t TGeoTrd1::Contains(const Double_t *point) const
187 {
188  if (TMath::Abs(point[2]) > fDz) return kFALSE;
189  // then y
190  if (TMath::Abs(point[1]) > fDy) return kFALSE;
191  // then x
192  Double_t dx = 0.5*(fDx2*(point[2]+fDz)+fDx1*(fDz-point[2]))/fDz;
193  if (TMath::Abs(point[0]) > dx) return kFALSE;
194  return kTRUE;
195 }
196 
197 ////////////////////////////////////////////////////////////////////////////////
198 /// Compute distance from inside point to surface of the trd1
199 /// Boundary safe algorithm.
200 
201 Double_t TGeoTrd1::DistFromInside(const Double_t *point, const Double_t *dir, Int_t iact, Double_t step, Double_t *safe) const
202 {
203  Double_t snxt = TGeoShape::Big();
204  if (iact<3 && safe) {
205  // compute safe distance
206  *safe = Safety(point, kTRUE);
207  if (iact==0) return TGeoShape::Big();
208  if (iact==1 && step<*safe) return TGeoShape::Big();
209  }
210 
211  //--- Compute safety first
212  Double_t fx = 0.5*(fDx1-fDx2)/fDz;
213  Double_t cn;
214  Double_t distx = 0.5*(fDx1+fDx2)-fx*point[2];
215  //--- Compute distance to this shape
216  // first check if Z facettes are crossed
217  Double_t dist[3];
218  for (Int_t i=0; i<3; i++) dist[i]=TGeoShape::Big();
219  if (dir[2]<0) {
220  dist[0]=-(point[2]+fDz)/dir[2];
221  } else if (dir[2]>0) {
222  dist[0]=(fDz-point[2])/dir[2];
223  }
224  if (dist[0]<=0) return 0.0;
225  // now check X facettes
226  cn = -dir[0]+fx*dir[2];
227  if (cn>0) {
228  dist[1] = point[0]+distx;
229  if (dist[1]<=0) return 0.0;
230  dist[1] /= cn;
231  }
232  cn = dir[0]+fx*dir[2];
233  if (cn>0) {
234  Double_t s = distx-point[0];
235  if (s<=0) return 0.0;
236  s /= cn;
237  if (s<dist[1]) dist[1] = s;
238  }
239  // now check Y facettes
240  if (dir[1]<0) {
241  dist[2]=-(point[1]+fDy)/dir[1];
242  } else if (dir[1]>0) {
243  dist[2]=(fDy-point[1])/dir[1];
244  }
245  if (dist[2]<=0) return 0.0;
246  snxt = dist[TMath::LocMin(3,dist)];
247  return snxt;
248 }
249 
250 ////////////////////////////////////////////////////////////////////////////////
251 /// get the most visible corner from outside point and the normals
252 
253 void TGeoTrd1::GetVisibleCorner(const Double_t *point, Double_t *vertex, Double_t *normals) const
254 {
255  Double_t fx = 0.5*(fDx1-fDx2)/fDz;
256  Double_t calf = 1./TMath::Sqrt(1.0+fx*fx);
257  Double_t salf = calf*fx;
258  // check visibility of X faces
259  Double_t distx = 0.5*(fDx1+fDx2)-fx*point[2];
260  memset(normals, 0, 9*sizeof(Double_t));
261  TGeoTrd1 *trd1 = (TGeoTrd1*)this;
262  if (point[0]>distx) {
263  // hi x face visible
264  trd1->SetShapeBit(kGeoVisX);
265  normals[0]=calf;
266  normals[2]=salf;
267  } else {
268  trd1->SetShapeBit(kGeoVisX, kFALSE);
269  normals[0]=-calf;
270  normals[2]=salf;
271  }
272  if (point[1]>fDy) {
273  // hi y face visible
274  trd1->SetShapeBit(kGeoVisY);
275  normals[4]=1;
276  } else {
277  trd1->SetShapeBit(kGeoVisY, kFALSE);
278  normals[4]=-1;
279  }
280  if (point[2]>fDz) {
281  // hi z face visible
282  trd1->SetShapeBit(kGeoVisZ);
283  normals[8]=1;
284  } else {
285  trd1->SetShapeBit(kGeoVisZ, kFALSE);
286  normals[8]=-1;
287  }
288  SetVertex(vertex);
289 }
290 
291 ////////////////////////////////////////////////////////////////////////////////
292 /// get the opposite corner of the intersected face
293 
294 void TGeoTrd1::GetOppositeCorner(const Double_t * /*point*/, Int_t inorm, Double_t *vertex, Double_t *normals) const
295 {
296  TGeoTrd1 *trd1 = (TGeoTrd1*)this;
297  if (inorm != 0) {
298  // change x face
300  normals[0]=-normals[0];
301  }
302  if (inorm != 1) {
303  // change y face
305  normals[4]=-normals[4];
306  }
307  if (inorm != 2) {
308  // hi z face visible
310  normals[8]=-normals[8];
311  }
312  SetVertex(vertex);
313 }
314 
315 ////////////////////////////////////////////////////////////////////////////////
316 /// Compute distance from outside point to surface of the trd1
317 /// Boundary safe algorithm
318 
319 Double_t TGeoTrd1::DistFromOutside(const Double_t *point, const Double_t *dir, Int_t iact, Double_t step, Double_t *safe) const
320 {
321  Double_t snxt = TGeoShape::Big();
322  if (iact<3 && safe) {
323  // compute safe distance
324  *safe = Safety(point, kFALSE);
325  if (iact==0) return TGeoShape::Big();
326  if (iact==1 && step<*safe) return TGeoShape::Big();
327  }
328  // find a visible face
329  Double_t xnew,ynew,znew;
330  Double_t fx = 0.5*(fDx1-fDx2)/fDz;
331  Double_t cn;
332  Double_t distx = 0.5*(fDx1+fDx2)-fx*point[2];
333  Bool_t in = kTRUE;
334  Double_t safx = distx-TMath::Abs(point[0]);
335  Double_t safy = fDy-TMath::Abs(point[1]);
336  Double_t safz = fDz-TMath::Abs(point[2]);
337 
338  //--- Compute distance to this shape
339  // first check if Z facettes are crossed
340  if (point[2]<=-fDz) {
341  if (dir[2]<=0) return TGeoShape::Big();
342  in = kFALSE;
343  snxt = -(fDz+point[2])/dir[2];
344  // find extrapolated X and Y
345  xnew = point[0]+snxt*dir[0];
346  if (TMath::Abs(xnew) <= fDx1) {
347  ynew = point[1]+snxt*dir[1];
348  if (TMath::Abs(ynew) <= fDy) return snxt;
349  }
350  } else if (point[2]>=fDz) {
351  if (dir[2]>=0) return TGeoShape::Big();
352  in = kFALSE;
353  snxt = (fDz-point[2])/dir[2];
354  // find extrapolated X and Y
355  xnew = point[0]+snxt*dir[0];
356  if (TMath::Abs(xnew) <= fDx2) {
357  ynew = point[1]+snxt*dir[1];
358  if (TMath::Abs(ynew) <= fDy) return snxt;
359  }
360  }
361  // check if X facettes are crossed
362  if (point[0]<=-distx) {
363  cn = -dir[0]+fx*dir[2];
364  if (cn>=0) return TGeoShape::Big();
365  in = kFALSE;
366  snxt = (point[0]+distx)/cn;
367  // find extrapolated Y and Z
368  ynew = point[1]+snxt*dir[1];
369  if (TMath::Abs(ynew) <= fDy) {
370  znew = point[2]+snxt*dir[2];
371  if (TMath::Abs(znew) <= fDz) return snxt;
372  }
373  }
374  if (point[0]>=distx) {
375  cn = dir[0]+fx*dir[2];
376  if (cn>=0) return TGeoShape::Big();
377  in = kFALSE;
378  snxt = (distx-point[0])/cn;
379  // find extrapolated Y and Z
380  ynew = point[1]+snxt*dir[1];
381  if (TMath::Abs(ynew) < fDy) {
382  znew = point[2]+snxt*dir[2];
383  if (TMath::Abs(znew) < fDz) return snxt;
384  }
385  }
386  // finally check Y facettes
387  if (point[1]<=-fDy) {
388  cn = -dir[1];
389  if (cn>=0) return TGeoShape::Big();
390  in = kFALSE;
391  snxt = (point[1]+fDy)/cn;
392  // find extrapolated X and Z
393  znew = point[2]+snxt*dir[2];
394  if (TMath::Abs(znew) < fDz) {
395  xnew = point[0]+snxt*dir[0];
396  Double_t dx = 0.5*(fDx1+fDx2)-fx*znew;
397  if (TMath::Abs(xnew) < dx) return snxt;
398  }
399  } else if (point[1]>=fDy) {
400  cn = dir[1];
401  if (cn>=0) return TGeoShape::Big();
402  in = kFALSE;
403  snxt = (fDy-point[1])/cn;
404  // find extrapolated X and Z
405  znew = point[2]+snxt*dir[2];
406  if (TMath::Abs(znew) < fDz) {
407  xnew = point[0]+snxt*dir[0];
408  Double_t dx = 0.5*(fDx1+fDx2)-fx*znew;
409  if (TMath::Abs(xnew) < dx) return snxt;
410  }
411  }
412  if (!in) return TGeoShape::Big();
413  // Point actually inside
414  if (safz<safx && safz<safy) {
415  if (point[2]*dir[2]>=0) return TGeoShape::Big();
416  return 0.0;
417  }
418  if (safy<safx) {
419  if (point[1]*dir[1]>=0) return TGeoShape::Big();
420  return 0.0;
421  }
422  cn = TMath::Sign(1.0,point[0])*dir[0]+fx*dir[2];
423  if (cn>=0) return TGeoShape::Big();
424  return 0.0;
425 }
426 
427 ////////////////////////////////////////////////////////////////////////////////
428 ///--- Divide this trd1 shape belonging to volume "voldiv" into ndiv volumes
429 /// called divname, from start position with the given step. Returns pointer
430 /// to created division cell volume in case of Y divisions. For Z divisions just
431 /// return the pointer to the volume to be divided. In case a wrong
432 /// division axis is supplied, returns pointer to volume that was divided.
433 
434 TGeoVolume *TGeoTrd1::Divide(TGeoVolume *voldiv, const char *divname, Int_t iaxis, Int_t ndiv,
435  Double_t start, Double_t step)
436 {
437  TGeoShape *shape; //--- shape to be created
438  TGeoVolume *vol; //--- division volume to be created
439  TGeoVolumeMulti *vmulti; //--- generic divided volume
440  TGeoPatternFinder *finder; //--- finder to be attached
441  TString opt = ""; //--- option to be attached
442  Double_t zmin, zmax, dx1n, dx2n;
443  Int_t id;
444  Double_t end = start+ndiv*step;
445  switch (iaxis) {
446  case 1:
447  Warning("Divide", "dividing a Trd1 on X not implemented");
448  return 0;
449  case 2:
450  finder = new TGeoPatternY(voldiv, ndiv, start, end);
451  voldiv->SetFinder(finder);
452  finder->SetDivIndex(voldiv->GetNdaughters());
453  shape = new TGeoTrd1(fDx1, fDx2, step/2, fDz);
454  vol = new TGeoVolume(divname, shape, voldiv->GetMedium());
455  vmulti = gGeoManager->MakeVolumeMulti(divname, voldiv->GetMedium());
456  vmulti->AddVolume(vol);
457  opt = "Y";
458  for (id=0; id<ndiv; id++) {
459  voldiv->AddNodeOffset(vol, id, start+step/2+id*step, opt.Data());
460  ((TGeoNodeOffset*)voldiv->GetNodes()->At(voldiv->GetNdaughters()-1))->SetFinder(finder);
461  }
462  return vmulti;
463  case 3:
464  finder = new TGeoPatternZ(voldiv, ndiv, start, end);
465  voldiv->SetFinder(finder);
466  finder->SetDivIndex(voldiv->GetNdaughters());
467  vmulti = gGeoManager->MakeVolumeMulti(divname, voldiv->GetMedium());
468  for (id=0; id<ndiv; id++) {
469  zmin = start+id*step;
470  zmax = start+(id+1)*step;
471  dx1n = 0.5*(fDx1*(fDz-zmin)+fDx2*(fDz+zmin))/fDz;
472  dx2n = 0.5*(fDx1*(fDz-zmax)+fDx2*(fDz+zmax))/fDz;
473  shape = new TGeoTrd1(dx1n, dx2n, fDy, step/2.);
474  vol = new TGeoVolume(divname, shape, voldiv->GetMedium());
475  vmulti->AddVolume(vol);
476  opt = "Z";
477  voldiv->AddNodeOffset(vol, id, start+step/2+id*step, opt.Data());
478  ((TGeoNodeOffset*)voldiv->GetNodes()->At(voldiv->GetNdaughters()-1))->SetFinder(finder);
479  }
480  return vmulti;
481  default:
482  Error("Divide", "Wrong axis type for division");
483  return 0;
484  }
485 }
486 
487 ////////////////////////////////////////////////////////////////////////////////
488 /// Get range of shape for a given axis.
489 
491 {
492  xlo = 0;
493  xhi = 0;
494  Double_t dx = 0;
495  switch (iaxis) {
496  case 2:
497  xlo = -fDy;
498  xhi = fDy;
499  dx = xhi-xlo;
500  return dx;
501  case 3:
502  xlo = -fDz;
503  xhi = fDz;
504  dx = xhi-xlo;
505  return dx;
506  }
507  return dx;
508 }
509 
510 ////////////////////////////////////////////////////////////////////////////////
511 ///--- Fill vector param[4] with the bounding cylinder parameters. The order
512 /// is the following : Rmin, Rmax, Phi1, Phi2
513 
515 {
517 }
518 
519 ////////////////////////////////////////////////////////////////////////////////
520 /// Fills real parameters of a positioned box inside this. Returns 0 if successfull.
521 
522 Int_t TGeoTrd1::GetFittingBox(const TGeoBBox *parambox, TGeoMatrix *mat, Double_t &dx, Double_t &dy, Double_t &dz) const
523 {
524  dx=dy=dz=0;
525  if (mat->IsRotation()) {
526  Error("GetFittingBox", "cannot handle parametrized rotated volumes");
527  return 1; // ### rotation not accepted ###
528  }
529  //--> translate the origin of the parametrized box to the frame of this box.
530  Double_t origin[3];
531  mat->LocalToMaster(parambox->GetOrigin(), origin);
532  if (!Contains(origin)) {
533  Error("GetFittingBox", "wrong matrix - parametrized box is outside this");
534  return 1; // ### wrong matrix ###
535  }
536  //--> now we have to get the valid range for all parametrized axis
537  Double_t dd[3];
538  dd[0] = parambox->GetDX();
539  dd[1] = parambox->GetDY();
540  dd[2] = parambox->GetDZ();
541  //-> check if Z range is fixed
542  if (dd[2]<0) {
543  dd[2] = TMath::Min(origin[2]+fDz, fDz-origin[2]);
544  if (dd[2]<0) {
545  Error("GetFittingBox", "wrong matrix");
546  return 1;
547  }
548  }
549  //-> check if Y range is fixed
550  if (dd[1]<0) {
551  dd[1] = TMath::Min(origin[1]+fDy, fDy-origin[1]);
552  if (dd[1]<0) {
553  Error("GetFittingBox", "wrong matrix");
554  return 1;
555  }
556  }
557  if (dd[0]>=0) {
558  dx = dd[0];
559  dy = dd[1];
560  dz = dd[2];
561  return 0;
562  }
563  //-> check now range at Z = origin[2] +/- dd[2]
564  Double_t fx = 0.5*(fDx1-fDx2)/fDz;
565  Double_t dx0 = 0.5*(fDx1+fDx2);
566  Double_t z=origin[2]-dd[2];
567  dd[0] = dx0-fx*z-origin[0];
568  z=origin[2]+dd[2];
569  dd[0] = TMath::Min(dd[0], dx0-fx*z-origin[0]);
570  if (dd[0]<0) {
571  Error("GetFittingBox", "wrong matrix");
572  return 1;
573  }
574  dx = dd[0];
575  dy = dd[1];
576  dz = dd[2];
577  return 0;
578 }
579 
580 ////////////////////////////////////////////////////////////////////////////////
581 /// in case shape has some negative parameters, these has to be computed
582 /// in order to fit the mother
583 
585 {
586  if (!TestShapeBit(kGeoRunTimeShape)) return 0;
587  if (!mother->TestShapeBit(kGeoTrd1)) {
588  Error("GetMakeRuntimeShape", "invalid mother");
589  return 0;
590  }
591  Double_t dx1, dx2, dy, dz;
592  if (fDx1<0) dx1=((TGeoTrd1*)mother)->GetDx1();
593  else dx1=fDx1;
594  if (fDx2<0) dx2=((TGeoTrd1*)mother)->GetDx2();
595  else dx2=fDx2;
596  if (fDy<0) dy=((TGeoTrd1*)mother)->GetDy();
597  else dy=fDy;
598  if (fDz<0) dz=((TGeoTrd1*)mother)->GetDz();
599  else dz=fDz;
600 
601  return (new TGeoTrd1(dx1, dx2, dy, dz));
602 }
603 
604 ////////////////////////////////////////////////////////////////////////////////
605 /// print shape parameters
606 
608 {
609  printf("*** Shape %s: TGeoTrd1 ***\n", GetName());
610  printf(" dx1 = %11.5f\n", fDx1);
611  printf(" dx2 = %11.5f\n", fDx2);
612  printf(" dy = %11.5f\n", fDy);
613  printf(" dz = %11.5f\n", fDz);
614  printf(" Bounding box:\n");
616 }
617 
618 ////////////////////////////////////////////////////////////////////////////////
619 /// computes the closest distance from given point to this shape, according
620 /// to option. The matching point on the shape is stored in spoint.
621 
622 Double_t TGeoTrd1::Safety(const Double_t *point, Bool_t in) const
623 {
624  Double_t saf[3];
625  //--- Compute safety first
626  // check Z facettes
627  saf[0] = fDz-TMath::Abs(point[2]);
628  Double_t fx = 0.5*(fDx1-fDx2)/fDz;
629  Double_t calf = 1./TMath::Sqrt(1.0+fx*fx);
630  // check X facettes
631  Double_t distx = 0.5*(fDx1+fDx2)-fx*point[2];
632  if (distx<0) saf[1]=TGeoShape::Big();
633  else saf[1]=(distx-TMath::Abs(point[0]))*calf;
634  // check Y facettes
635  saf[2] = fDy-TMath::Abs(point[1]);
636  if (in) return saf[TMath::LocMin(3,saf)];
637  for (Int_t i=0; i<3; i++) saf[i]=-saf[i];
638  return saf[TMath::LocMax(3,saf)];
639 }
640 
641 ////////////////////////////////////////////////////////////////////////////////
642 /// Save a primitive as a C++ statement(s) on output stream "out".
643 
644 void TGeoTrd1::SavePrimitive(std::ostream &out, Option_t * /*option*/ /*= ""*/)
645 {
646  if (TObject::TestBit(kGeoSavePrimitive)) return;
647  out << " // Shape: " << GetName() << " type: " << ClassName() << std::endl;
648  out << " dx1 = " << fDx1 << ";" << std::endl;
649  out << " dx2 = " << fDx2 << ";" << std::endl;
650  out << " dy = " << fDy << ";" << std::endl;
651  out << " dz = " << fDZ << ";" << std::endl;
652  out << " TGeoShape *" << GetPointerName() << " = new TGeoTrd1(\"" << GetName() << "\", dx1,dx2,dy,dz);" << std::endl;
654 }
655 
656 ////////////////////////////////////////////////////////////////////////////////
657 /// set trd1 params in one step :
658 
660 {
661  fDx1 = param[0];
662  fDx2 = param[1];
663  fDy = param[2];
664  fDz = param[3];
665  ComputeBBox();
666 }
667 
668 ////////////////////////////////////////////////////////////////////////////////
669 /// set vertex of a corner according to visibility flags
670 
672 {
673  if (TestShapeBit(kGeoVisX)) {
674  if (TestShapeBit(kGeoVisZ)) {
675  vertex[0] = fDx2;
676  vertex[2] = fDz;
677  vertex[1] = (TestShapeBit(kGeoVisY))?fDy:-fDy;
678  } else {
679  vertex[0] = fDx1;
680  vertex[2] = -fDz;
681  vertex[1] = (TestShapeBit(kGeoVisY))?fDy:-fDy;
682  }
683  } else {
684  if (TestShapeBit(kGeoVisZ)) {
685  vertex[0] = -fDx2;
686  vertex[2] = fDz;
687  vertex[1] = (TestShapeBit(kGeoVisY))?fDy:-fDy;
688  } else {
689  vertex[0] = -fDx1;
690  vertex[2] = -fDz;
691  vertex[1] = (TestShapeBit(kGeoVisY))?fDy:-fDy;
692  }
693  }
694 }
695 
696 ////////////////////////////////////////////////////////////////////////////////
697 /// create arb8 mesh points
698 
700 {
701  if (!points) return;
702  points[ 0] = -fDx1; points[ 1] = -fDy; points[ 2] = -fDz;
703  points[ 3] = -fDx1; points[ 4] = fDy; points[ 5] = -fDz;
704  points[ 6] = fDx1; points[ 7] = fDy; points[ 8] = -fDz;
705  points[ 9] = fDx1; points[10] = -fDy; points[11] = -fDz;
706  points[12] = -fDx2; points[13] = -fDy; points[14] = fDz;
707  points[15] = -fDx2; points[16] = fDy; points[17] = fDz;
708  points[18] = fDx2; points[19] = fDy; points[20] = fDz;
709  points[21] = fDx2; points[22] = -fDy; points[23] = fDz;
710 }
711 
712 ////////////////////////////////////////////////////////////////////////////////
713 /// create arb8 mesh points
714 
716 {
717  if (!points) return;
718  points[ 0] = -fDx1; points[ 1] = -fDy; points[ 2] = -fDz;
719  points[ 3] = -fDx1; points[ 4] = fDy; points[ 5] = -fDz;
720  points[ 6] = fDx1; points[ 7] = fDy; points[ 8] = -fDz;
721  points[ 9] = fDx1; points[10] = -fDy; points[11] = -fDz;
722  points[12] = -fDx2; points[13] = -fDy; points[14] = fDz;
723  points[15] = -fDx2; points[16] = fDy; points[17] = fDz;
724  points[18] = fDx2; points[19] = fDy; points[20] = fDz;
725  points[21] = fDx2; points[22] = -fDy; points[23] = fDz;
726 }
727 
728 ////////////////////////////////////////////////////////////////////////////////
729 /// fill size of this 3-D object
730 
731 void TGeoTrd1::Sizeof3D() const
732 {
734 }
735 
736 ////////////////////////////////////////////////////////////////////////////////
737 /// Check the inside status for each of the points in the array.
738 /// Input: Array of point coordinates + vector size
739 /// Output: Array of Booleans for the inside of each point
740 
741 void TGeoTrd1::Contains_v(const Double_t *points, Bool_t *inside, Int_t vecsize) const
742 {
743  for (Int_t i=0; i<vecsize; i++) inside[i] = Contains(&points[3*i]);
744 }
745 
746 ////////////////////////////////////////////////////////////////////////////////
747 /// Compute the normal for an array o points so that norm.dot.dir is positive
748 /// Input: Arrays of point coordinates and directions + vector size
749 /// Output: Array of normal directions
750 
751 void TGeoTrd1::ComputeNormal_v(const Double_t *points, const Double_t *dirs, Double_t *norms, Int_t vecsize)
752 {
753  for (Int_t i=0; i<vecsize; i++) ComputeNormal(&points[3*i], &dirs[3*i], &norms[3*i]);
754 }
755 
756 ////////////////////////////////////////////////////////////////////////////////
757 /// Compute distance from array of input points having directions specisied by dirs. Store output in dists
758 
759 void TGeoTrd1::DistFromInside_v(const Double_t *points, const Double_t *dirs, Double_t *dists, Int_t vecsize, Double_t* step) const
760 {
761  for (Int_t i=0; i<vecsize; i++) dists[i] = DistFromInside(&points[3*i], &dirs[3*i], 3, step[i]);
762 }
763 
764 ////////////////////////////////////////////////////////////////////////////////
765 /// Compute distance from array of input points having directions specisied by dirs. Store output in dists
766 
767 void TGeoTrd1::DistFromOutside_v(const Double_t *points, const Double_t *dirs, Double_t *dists, Int_t vecsize, Double_t* step) const
768 {
769  for (Int_t i=0; i<vecsize; i++) dists[i] = DistFromOutside(&points[3*i], &dirs[3*i], 3, step[i]);
770 }
771 
772 ////////////////////////////////////////////////////////////////////////////////
773 /// Compute safe distance from each of the points in the input array.
774 /// Input: Array of point coordinates, array of statuses for these points, size of the arrays
775 /// Output: Safety values
776 
777 void TGeoTrd1::Safety_v(const Double_t *points, const Bool_t *inside, Double_t *safe, Int_t vecsize) const
778 {
779  for (Int_t i=0; i<vecsize; i++) safe[i] = Safety(&points[3*i], inside[i]);
780 }
TGeoVolumeMulti * MakeVolumeMulti(const char *name, TGeoMedium *medium)
Make a TGeoVolumeMulti handling a list of volumes.
virtual ~TGeoTrd1()
destructor
Definition: TGeoTrd1.cxx:119
double dist(Rotation3D const &r1, Rotation3D const &r2)
Definition: 3DDistances.cxx:48
virtual void InspectShape() const
print shape parameters
Definition: TGeoTrd1.cxx:607
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: TGeoTrd1.cxx:767
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
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
const char Option_t
Definition: RtypesCore.h:62
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: TGeoTrd1.cxx:622
Double_t fDx2
Definition: TGeoTrd1.h:33
virtual void ComputeBBox()
compute bounding box for a trd1
Definition: TGeoTrd1.cxx:135
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: TGeoTrd1.cxx:584
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. Returns 0 if successfull.
Definition: TGeoTrd1.cxx:522
virtual Double_t Capacity() const
Computes capacity of the shape in [length^3].
Definition: TGeoTrd1.cxx:126
void SetVertex(Double_t *vertex) const
set vertex of a corner according to visibility flags
Definition: TGeoTrd1.cxx:671
Double_t fOrigin[3]
Definition: TGeoBBox.h:36
Basic string class.
Definition: TString.h:137
virtual void ComputeNormal(const Double_t *point, const Double_t *dir, Double_t *norm)
Compute normal to closest surface from POINT.
Definition: TGeoTrd1.cxx:146
virtual void Sizeof3D() const
fill size of this 3-D object
Definition: TGeoTrd1.cxx:731
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
const Bool_t kFALSE
Definition: Rtypes.h:92
virtual Double_t GetDY() const
Definition: TGeoBBox.h:83
Double_t fDx1
Definition: TGeoTrd1.h:32
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
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
virtual Bool_t Contains(const Double_t *point) const
test if point is inside this shape check Z range
Definition: TGeoTrd1.cxx:186
const char * Data() const
Definition: TString.h:349
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: TGeoTrd1.cxx:777
virtual void SetPoints(Double_t *points) const
create arb8 mesh points
Definition: TGeoTrd1.cxx:699
Double_t dot(const TVector2 &v1, const TVector2 &v2)
Definition: CsgOps.cxx:333
virtual void SavePrimitive(std::ostream &out, Option_t *option="")
Save a primitive as a C++ statement(s) on output stream "out".
Definition: TGeoTrd1.cxx:644
Double_t fDZ
Definition: TGeoBBox.h:35
XFontStruct * id
Definition: TGX11.cxx:108
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition: TObject.cxx:918
char * out
Definition: TBase64.cxx:29
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: TGeoTrd1.cxx:751
virtual const Double_t * GetOrigin() const
Definition: TGeoBBox.h:85
REAL * vertex
Definition: triangle.c:512
point * points
Definition: X3DBuffer.c:20
virtual Double_t GetDX() const
Definition: TGeoBBox.h:82
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 trd1 Boundary safe algorithm.
Definition: TGeoTrd1.cxx:319
Double_t fDy
Definition: TGeoTrd1.h:34
virtual const char * ClassName() const
Returns name of class to which the object belongs.
Definition: TObject.cxx:187
virtual void SetDimensions(Double_t *param)
set trd1 params in one step :
Definition: TGeoTrd1.cxx:659
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: TGeoTrd1.cxx:741
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
virtual void GetBoundingCylinder(Double_t *param) const
Fill vector param[4] with the bounding cylinder parameters.
Definition: TGeoBBox.cxx:539
Bool_t TestBit(UInt_t f) const
Definition: TObject.h:173
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: TGeoTrd1.cxx:759
virtual TGeoVolume * Divide(TGeoVolume *voldiv, const char *divname, Int_t iaxis, Int_t ndiv, Double_t start, Double_t step)
— Divide this trd1 shape belonging to volume "voldiv" into ndiv volumes called divname, from start position with the given step.
Definition: TGeoTrd1.cxx:434
void SetDivIndex(Int_t index)
virtual const char * GetName() const
Get the shape name.
Definition: TGeoShape.cxx:247
virtual void InspectShape() const
Prints shape parameters.
Definition: TGeoBBox.cxx:749
R__EXTERN TGeoManager * gGeoManager
Definition: TGeoManager.h:556
virtual Double_t GetAxisRange(Int_t iaxis, Double_t &xlo, Double_t &xhi) const
Get range of shape for a given axis.
Definition: TGeoTrd1.cxx:490
double Double_t
Definition: RtypesCore.h:55
ClassImp(TMCParticle) void TMCParticle printf(": p=(%7.3f,%7.3f,%9.3f) ;", fPx, fPy, fPz)
void GetOppositeCorner(const Double_t *point, Int_t inorm, Double_t *vertex, Double_t *normals) const
get the opposite corner of the intersected face
Definition: TGeoTrd1.cxx:294
Double_t fDz
Definition: TGeoTrd1.h:35
const char * GetPointerName() const
Provide a pointer name containing uid.
Definition: TGeoShape.cxx:697
static Double_t Big()
Definition: TGeoShape.h:98
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:522
virtual void GetBoundingCylinder(Double_t *param) const
— Fill vector param[4] with the bounding cylinder parameters.
Definition: TGeoTrd1.cxx:514
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 trd1 Boundary safe algorithm.
Definition: TGeoTrd1.cxx:201
Bool_t TestShapeBit(UInt_t f) const
Definition: TGeoShape.h:172
ClassImp(TGeoTrd1) TGeoTrd1
dummy ctor
Definition: TGeoTrd1.cxx:51
TGeoMedium * GetMedium() const
Definition: TGeoVolume.h:189
Short_t Max(Short_t a, Short_t b)
Definition: TMathBase.h:202
Double_t fDX
Definition: TGeoBBox.h:33
void GetVisibleCorner(const Double_t *point, Double_t *vertex, Double_t *normals) const
get the most visible corner from outside point and the normals
Definition: TGeoTrd1.cxx:253
Double_t Sqrt(Double_t x)
Definition: TMath.h:464
TObject * At(Int_t idx) const
Definition: TObjArray.h:167
virtual void Sizeof3D() const
Definition: TGeoBBox.cxx:952
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 Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition: TObject.cxx:904