Geant4  10.00.p02
G4Trd.cc
Go to the documentation of this file.
1 //
2 // ********************************************************************
3 // * License and Disclaimer *
4 // * *
5 // * The Geant4 software is copyright of the Copyright Holders of *
6 // * the Geant4 Collaboration. It is provided under the terms and *
7 // * conditions of the Geant4 Software License, included in the file *
8 // * LICENSE and available at http://cern.ch/geant4/license . These *
9 // * include a list of copyright holders. *
10 // * *
11 // * Neither the authors of this software system, nor their employing *
12 // * institutes,nor the agencies providing financial support for this *
13 // * work make any representation or warranty, express or implied, *
14 // * regarding this software system or assume any liability for its *
15 // * use. Please see the license in the file LICENSE and URL above *
16 // * for the full disclaimer and the limitation of liability. *
17 // * *
18 // * This code implementation is the result of the scientific and *
19 // * technical work of the GEANT4 collaboration. *
20 // * By using, copying, modifying or distributing the software (or *
21 // * any work based on the software) you agree to acknowledge its *
22 // * use in resulting scientific publications, and indicate your *
23 // * acceptance of all terms of the Geant4 Software license. *
24 // ********************************************************************
25 //
26 //
27 // $Id: G4Trd.cc 81636 2014-06-04 09:06:08Z gcosmo $
28 //
29 //
30 // Implementation for G4Trd class
31 //
32 // History:
33 //
34 // 28.04.05 V.Grichine: new SurfaceNormal according to J. Apostolakis proposal
35 // 26.04.05, V.Grichine, new SurfaceNoramal is default
36 // 07.12.04, V.Grichine, SurfaceNoramal with edges/vertices.
37 // 07.05.00, V.Grichine, in d = DistanceToIn(p,v), if d<0.5*kCarTolerance, d=0
38 // ~1996, V.Grichine, 1st implementation based on old code of P.Kent
39 //
41 
42 #include "G4Trd.hh"
43 
44 #if !defined(G4GEOM_USE_UTRD)
45 
46 #include "G4VPVParameterisation.hh"
47 #include "G4VoxelLimits.hh"
48 #include "G4AffineTransform.hh"
49 #include "Randomize.hh"
50 
51 #include "G4VGraphicsScene.hh"
52 
53 using namespace CLHEP;
54 
56 //
57 // Constructor - check & set half widths
58 
59 G4Trd::G4Trd( const G4String& pName,
60  G4double pdx1, G4double pdx2,
61  G4double pdy1, G4double pdy2,
62  G4double pdz )
63  : G4CSGSolid(pName)
64 {
65  CheckAndSetAllParameters (pdx1, pdx2, pdy1, pdy2, pdz);
66 }
67 
69 //
70 // Set and check (coplanarity) of trd parameters
71 
73  G4double pdy1, G4double pdy2,
74  G4double pdz )
75 {
76  if ( pdx1>0&&pdx2>0&&pdy1>0&&pdy2>0&&pdz>0 )
77  {
78  fDx1=pdx1; fDx2=pdx2;
79  fDy1=pdy1; fDy2=pdy2;
80  fDz=pdz;
81  }
82  else
83  {
84  if ( pdx1>=0 && pdx2>=0 && pdy1>=0 && pdy2>=0 && pdz>=0 )
85  {
86  // G4double Minimum_length= (1+per_thousand) * kCarTolerance/2.;
87  // FIX-ME : temporary solution for ZERO or very-small parameters
88  //
89  G4double Minimum_length= kCarTolerance/2.;
90  fDx1=std::max(pdx1,Minimum_length);
91  fDx2=std::max(pdx2,Minimum_length);
92  fDy1=std::max(pdy1,Minimum_length);
93  fDy2=std::max(pdy2,Minimum_length);
94  fDz=std::max(pdz,Minimum_length);
95  }
96  else
97  {
98  std::ostringstream message;
99  message << "Invalid negative dimensions for Solid: " << GetName()
100  << G4endl
101  << " X - " << pdx1 << ", " << pdx2 << G4endl
102  << " Y - " << pdy1 << ", " << pdy2 << G4endl
103  << " Z - " << pdz;
104  G4Exception("G4Trd::CheckAndSetAllParameters()",
105  "GeomSolids0002", FatalException, message);
106  }
107  }
108  fCubicVolume= 0.;
109  fSurfaceArea= 0.;
110  fpPolyhedron = 0;
111 }
112 
114 //
115 // Fake default constructor - sets only member data and allocates memory
116 // for usage restricted to object persistency.
117 //
118 G4Trd::G4Trd( __void__& a )
119  : G4CSGSolid(a), fDx1(0.), fDx2(0.), fDy1(0.), fDy2(0.), fDz(0.)
120 {
121 }
122 
124 //
125 // Destructor
126 
128 {
129 }
130 
132 //
133 // Copy constructor
134 
135 G4Trd::G4Trd(const G4Trd& rhs)
136  : G4CSGSolid(rhs), fDx1(rhs.fDx1), fDx2(rhs.fDx2),
137  fDy1(rhs.fDy1), fDy2(rhs.fDy2), fDz(rhs.fDz)
138 {
140 }
141 
143 //
144 // Assignment operator
145 
147 {
148  // Check assignment to self
149  //
150  if (this == &rhs) { return *this; }
151 
152  // Copy base class data
153  //
155 
156  // Copy data
157  //
158  fDx1 = rhs.fDx1; fDx2 = rhs.fDx2;
159  fDy1 = rhs.fDy1; fDy2 = rhs.fDy2;
160  fDz = rhs.fDz;
162 
163  return *this;
164 }
165 
167 //
168 //
169 
171  G4double pdy2, G4double pdz )
172 {
173  CheckAndSetAllParameters (pdx1, pdx2, pdy1, pdy2, pdz);
174 }
175 
176 
178 //
179 // Dispatch to parameterisation for replication mechanism dimension
180 // computation & modification.
181 
183  const G4int n,
184  const G4VPhysicalVolume* pRep )
185 {
186  p->ComputeDimensions(*this,n,pRep);
187 }
188 
189 
191 //
192 // Calculate extent under transform and specified limit
193 
195  const G4VoxelLimits& pVoxelLimit,
196  const G4AffineTransform& pTransform,
197  G4double& pMin, G4double& pMax ) const
198 {
199  if (!pTransform.IsRotated())
200  {
201  // Special case handling for unrotated solids
202  // Compute x/y/z mins and maxs respecting limits, with early returns
203  // if outside limits. Then switch() on pAxis
204 
205  G4double xoffset,xMin,xMax;
206  G4double yoffset,yMin,yMax;
207  G4double zoffset,zMin,zMax;
208 
209  zoffset=pTransform.NetTranslation().z();
210  zMin=zoffset-fDz;
211  zMax=zoffset+fDz;
212  if (pVoxelLimit.IsZLimited())
213  {
214  if ( (zMin>pVoxelLimit.GetMaxZExtent()+kCarTolerance)
215  || (zMax<pVoxelLimit.GetMinZExtent()-kCarTolerance) )
216  {
217  return false;
218  }
219  else
220  {
221  if (zMin<pVoxelLimit.GetMinZExtent())
222  {
223  zMin=pVoxelLimit.GetMinZExtent();
224  }
225  if (zMax>pVoxelLimit.GetMaxZExtent())
226  {
227  zMax=pVoxelLimit.GetMaxZExtent();
228  }
229  }
230  }
231  xoffset=pTransform.NetTranslation().x();
232  if (fDx2 >= fDx1)
233  {
234  xMax = xoffset+(fDx1+fDx2)/2+(zMax-zoffset)*(fDx2-fDx1)/(2*fDz) ;
235  xMin = 2*xoffset - xMax ;
236  }
237  else
238  {
239  xMax = xoffset+(fDx1+fDx2)/2+(zMin-zoffset)*(fDx2-fDx1)/(2*fDz) ;
240  xMin = 2*xoffset - xMax ;
241  }
242  if (pVoxelLimit.IsXLimited())
243  {
244  if ( (xMin>pVoxelLimit.GetMaxXExtent()+kCarTolerance)
245  || (xMax<pVoxelLimit.GetMinXExtent()-kCarTolerance) )
246  {
247  return false;
248  }
249  else
250  {
251  if (xMin<pVoxelLimit.GetMinXExtent())
252  {
253  xMin=pVoxelLimit.GetMinXExtent();
254  }
255  if (xMax>pVoxelLimit.GetMaxXExtent())
256  {
257  xMax=pVoxelLimit.GetMaxXExtent();
258  }
259  }
260  }
261  yoffset= pTransform.NetTranslation().y() ;
262  if(fDy2 >= fDy1)
263  {
264  yMax = yoffset+(fDy2+fDy1)/2+(zMax-zoffset)*(fDy2-fDy1)/(2*fDz) ;
265  yMin = 2*yoffset - yMax ;
266  }
267  else
268  {
269  yMax = yoffset+(fDy2+fDy1)/2+(zMin-zoffset)*(fDy2-fDy1)/(2*fDz) ;
270  yMin = 2*yoffset - yMax ;
271  }
272  if (pVoxelLimit.IsYLimited())
273  {
274  if ( (yMin>pVoxelLimit.GetMaxYExtent()+kCarTolerance)
275  || (yMax<pVoxelLimit.GetMinYExtent()-kCarTolerance) )
276  {
277  return false;
278  }
279  else
280  {
281  if (yMin<pVoxelLimit.GetMinYExtent())
282  {
283  yMin=pVoxelLimit.GetMinYExtent();
284  }
285  if (yMax>pVoxelLimit.GetMaxYExtent())
286  {
287  yMax=pVoxelLimit.GetMaxYExtent();
288  }
289  }
290  }
291 
292  switch (pAxis)
293  {
294  case kXAxis:
295  pMin=xMin;
296  pMax=xMax;
297  break;
298  case kYAxis:
299  pMin=yMin;
300  pMax=yMax;
301  break;
302  case kZAxis:
303  pMin=zMin;
304  pMax=zMax;
305  break;
306  default:
307  break;
308  }
309 
310  // Add 2*Tolerance to avoid precision troubles ?
311  //
312  pMin-=kCarTolerance;
313  pMax+=kCarTolerance;
314 
315  return true;
316  }
317  else
318  {
319  // General rotated case - create and clip mesh to boundaries
320 
321  G4bool existsAfterClip=false;
322  G4ThreeVectorList *vertices;
323 
324  pMin=+kInfinity;
325  pMax=-kInfinity;
326 
327  // Calculate rotated vertex coordinates
328  //
329  vertices=CreateRotatedVertices(pTransform);
330  ClipCrossSection(vertices,0,pVoxelLimit,pAxis,pMin,pMax);
331  ClipCrossSection(vertices,4,pVoxelLimit,pAxis,pMin,pMax);
332  ClipBetweenSections(vertices,0,pVoxelLimit,pAxis,pMin,pMax);
333 
334  if (pMin!=kInfinity||pMax!=-kInfinity)
335  {
336  existsAfterClip=true;
337 
338  // Add 2*tolerance to avoid precision troubles
339  //
340  pMin-=kCarTolerance;
341  pMax+=kCarTolerance;
342 
343  }
344  else
345  {
346  // Check for case where completely enveloping clipping volume
347  // If point inside then we are confident that the solid completely
348  // envelopes the clipping volume. Hence set min/max extents according
349  // to clipping volume extents along the specified axis.
350 
351  G4ThreeVector clipCentre(
352  (pVoxelLimit.GetMinXExtent()+pVoxelLimit.GetMaxXExtent())*0.5,
353  (pVoxelLimit.GetMinYExtent()+pVoxelLimit.GetMaxYExtent())*0.5,
354  (pVoxelLimit.GetMinZExtent()+pVoxelLimit.GetMaxZExtent())*0.5);
355 
356  if (Inside(pTransform.Inverse().TransformPoint(clipCentre))!=kOutside)
357  {
358  existsAfterClip=true;
359  pMin=pVoxelLimit.GetMinExtent(pAxis);
360  pMax=pVoxelLimit.GetMaxExtent(pAxis);
361  }
362  }
363  delete vertices;
364  return existsAfterClip;
365  }
366 }
367 
369 //
370 // Return whether point inside/outside/on surface, using tolerance
371 
373 {
374  EInside in=kOutside;
375  G4double x,y,zbase1,zbase2;
376 
377  if (std::fabs(p.z())<=fDz-kCarTolerance/2)
378  {
379  zbase1=p.z()+fDz; // Dist from -ve z plane
380  zbase2=fDz-p.z(); // Dist from +ve z plane
381 
382  // Check whether inside x tolerance
383  //
384  x=0.5*(fDx2*zbase1+fDx1*zbase2)/fDz - kCarTolerance/2;
385  if (std::fabs(p.x())<=x)
386  {
387  y=0.5*((fDy2*zbase1+fDy1*zbase2))/fDz - kCarTolerance/2;
388  if (std::fabs(p.y())<=y)
389  {
390  in=kInside;
391  }
392  else if (std::fabs(p.y())<=y+kCarTolerance)
393  {
394  in=kSurface;
395  }
396  }
397  else if (std::fabs(p.x())<=x+kCarTolerance)
398  {
399  // y = y half width of shape at z of point + tolerant boundary
400  //
401  y=0.5*((fDy2*zbase1+fDy1*zbase2))/fDz + kCarTolerance/2;
402  if (std::fabs(p.y())<=y)
403  {
404  in=kSurface;
405  }
406  }
407  }
408  else if (std::fabs(p.z())<=fDz+kCarTolerance/2)
409  {
410  // Only need to check outer tolerant boundaries
411  //
412  zbase1=p.z()+fDz; // Dist from -ve z plane
413  zbase2=fDz-p.z(); // Dist from +ve z plane
414 
415  // x = x half width of shape at z of point plus tolerance
416  //
417  x=0.5*(fDx2*zbase1+fDx1*zbase2)/fDz + kCarTolerance/2;
418  if (std::fabs(p.x())<=x)
419  {
420  // y = y half width of shape at z of point
421  //
422  y=0.5*((fDy2*zbase1+fDy1*zbase2))/fDz + kCarTolerance/2;
423  if (std::fabs(p.y())<=y) in=kSurface;
424  }
425  }
426  return in;
427 }
428 
430 //
431 // Calculate side nearest to p, and return normal
432 // If two sides are equidistant, normal of first side (x/y/z)
433 // encountered returned
434 
436 {
437  G4ThreeVector norm, sumnorm(0.,0.,0.);
438  G4int noSurfaces = 0;
439  G4double z = 2.0*fDz, tanx, secx, newpx, widx;
440  G4double tany, secy, newpy, widy;
441  G4double distx, disty, distz, fcos;
442  G4double delta = 0.5*kCarTolerance;
443 
444  tanx = (fDx2 - fDx1)/z;
445  secx = std::sqrt(1.0+tanx*tanx);
446  newpx = std::fabs(p.x())-p.z()*tanx;
447  widx = fDx2 - fDz*tanx;
448 
449  tany = (fDy2 - fDy1)/z;
450  secy = std::sqrt(1.0+tany*tany);
451  newpy = std::fabs(p.y())-p.z()*tany;
452  widy = fDy2 - fDz*tany;
453 
454  distx = std::fabs(newpx-widx)/secx; // perp. distance to x side
455  disty = std::fabs(newpy-widy)/secy; // to y side
456  distz = std::fabs(std::fabs(p.z())-fDz); // to z side
457 
458  fcos = 1.0/secx;
459  G4ThreeVector nX = G4ThreeVector( fcos,0,-tanx*fcos);
460  G4ThreeVector nmX = G4ThreeVector(-fcos,0,-tanx*fcos);
461 
462  fcos = 1.0/secy;
463  G4ThreeVector nY = G4ThreeVector(0, fcos,-tany*fcos);
464  G4ThreeVector nmY = G4ThreeVector(0,-fcos,-tany*fcos);
465  G4ThreeVector nZ = G4ThreeVector( 0, 0, 1.0);
466 
467  if (distx <= delta)
468  {
469  noSurfaces ++;
470  if ( p.x() >= 0.) sumnorm += nX;
471  else sumnorm += nmX;
472  }
473  if (disty <= delta)
474  {
475  noSurfaces ++;
476  if ( p.y() >= 0.) sumnorm += nY;
477  else sumnorm += nmY;
478  }
479  if (distz <= delta)
480  {
481  noSurfaces ++;
482  if ( p.z() >= 0.) sumnorm += nZ;
483  else sumnorm -= nZ;
484  }
485  if ( noSurfaces == 0 )
486  {
487 #ifdef G4CSGDEBUG
488  G4Exception("G4Trd::SurfaceNormal(p)", "GeomSolids1002", JustWarning,
489  "Point p is not on surface !?" );
490 #endif
491  norm = ApproxSurfaceNormal(p);
492  }
493  else if ( noSurfaces == 1 ) norm = sumnorm;
494  else norm = sumnorm.unit();
495  return norm;
496 }
497 
498 
500 //
501 // Algorithm for SurfaceNormal() following the original specification
502 // for points not on the surface
503 
505 {
506  G4ThreeVector norm;
507  G4double z,tanx,secx,newpx,widx;
508  G4double tany,secy,newpy,widy;
509  G4double distx,disty,distz,fcos;
510 
511  z=2.0*fDz;
512 
513  tanx=(fDx2-fDx1)/z;
514  secx=std::sqrt(1.0+tanx*tanx);
515  newpx=std::fabs(p.x())-p.z()*tanx;
516  widx=fDx2-fDz*tanx;
517 
518  tany=(fDy2-fDy1)/z;
519  secy=std::sqrt(1.0+tany*tany);
520  newpy=std::fabs(p.y())-p.z()*tany;
521  widy=fDy2-fDz*tany;
522 
523  distx=std::fabs(newpx-widx)/secx; // perpendicular distance to x side
524  disty=std::fabs(newpy-widy)/secy; // to y side
525  distz=std::fabs(std::fabs(p.z())-fDz); // to z side
526 
527  // find closest side
528  //
529  if (distx<=disty)
530  {
531  if (distx<=distz)
532  {
533  // Closest to X
534  //
535  fcos=1.0/secx;
536  // normal=(+/-std::cos(ang),0,-std::sin(ang))
537  if (p.x()>=0)
538  norm=G4ThreeVector(fcos,0,-tanx*fcos);
539  else
540  norm=G4ThreeVector(-fcos,0,-tanx*fcos);
541  }
542  else
543  {
544  // Closest to Z
545  //
546  if (p.z()>=0)
547  norm=G4ThreeVector(0,0,1);
548  else
549  norm=G4ThreeVector(0,0,-1);
550  }
551  }
552  else
553  {
554  if (disty<=distz)
555  {
556  // Closest to Y
557  //
558  fcos=1.0/secy;
559  if (p.y()>=0)
560  norm=G4ThreeVector(0,fcos,-tany*fcos);
561  else
562  norm=G4ThreeVector(0,-fcos,-tany*fcos);
563  }
564  else
565  {
566  // Closest to Z
567  //
568  if (p.z()>=0)
569  norm=G4ThreeVector(0,0,1);
570  else
571  norm=G4ThreeVector(0,0,-1);
572  }
573  }
574  return norm;
575 }
576 
578 //
579 // Calculate distance to shape from outside
580 // - return kInfinity if no intersection
581 //
582 // ALGORITHM:
583 // For each component, calculate pair of minimum and maximum intersection
584 // values for which the particle is in the extent of the shape
585 // - The smallest (MAX minimum) allowed distance of the pairs is intersect
586 // - Z plane intersectin uses tolerance
587 // - XZ YZ planes use logic & *SLIGHTLY INCORRECT* tolerance
588 // (this saves at least 1 sqrt, 1 multiply and 1 divide... in applicable
589 // cases)
590 // - Note: XZ and YZ planes each divide space into four regions,
591 // characterised by ss1 ss2
592 // NOTE:
593 //
594 // `Inside' safe - meaningful answers given if point is inside the exact
595 // shape.
596 
598  const G4ThreeVector& v ) const
599 {
600  G4double snxt = kInfinity ; // snxt = default return value
601  G4double smin,smax;
602  G4double s1,s2,tanxz,tanyz,ds1,ds2;
603  G4double ss1,ss2,sn1=0.,sn2=0.,Dist;
604 
605  if ( v.z() ) // Calculate valid z intersect range
606  {
607  if ( v.z() > 0 ) // Calculate smax: must be +ve or no intersection.
608  {
609  Dist = fDz - p.z() ; // to plane at +dz
610 
611  if (Dist >= 0.5*kCarTolerance)
612  {
613  smax = Dist/v.z() ;
614  smin = -(fDz + p.z())/v.z() ;
615  }
616  else return snxt ;
617  }
618  else // v.z <0
619  {
620  Dist=fDz+p.z(); // plane at -dz
621 
622  if ( Dist >= 0.5*kCarTolerance )
623  {
624  smax = -Dist/v.z() ;
625  smin = (fDz - p.z())/v.z() ;
626  }
627  else return snxt ;
628  }
629  if (smin < 0 ) smin = 0 ;
630  }
631  else // v.z=0
632  {
633  if (std::fabs(p.z()) >= fDz ) return snxt ; // Outside & no intersect
634  else
635  {
636  smin = 0 ; // Always inside z range
637  smax = kInfinity;
638  }
639  }
640 
641  // Calculate x intersection range
642  //
643  // Calc half width at p.z, and components towards planes
644 
645  tanxz = (fDx2 - fDx1)*0.5/fDz ;
646  s1 = 0.5*(fDx1+fDx2) + tanxz*p.z() ; // x half width at p.z
647  ds1 = v.x() - tanxz*v.z() ; // Components of v towards faces at +-x
648  ds2 = v.x() + tanxz*v.z() ;
649  ss1 = s1 - p.x() ; // -delta x to +ve plane
650  // -ve when outside
651  ss2 = -s1 - p.x() ; // -delta x to -ve plane
652  // +ve when outside
653 
654  if (ss1 < 0 && ss2 <= 0 )
655  {
656  if (ds1 < 0) // In +ve coord Area
657  {
658  sn1 = ss1/ds1 ;
659 
660  if ( ds2 < 0 ) sn2 = ss2/ds2 ;
661  else sn2 = kInfinity ;
662  }
663  else return snxt ;
664  }
665  else if ( ss1 >= 0 && ss2 > 0 )
666  {
667  if ( ds2 > 0 ) // In -ve coord Area
668  {
669  sn1 = ss2/ds2 ;
670 
671  if (ds1 > 0) sn2 = ss1/ds1 ;
672  else sn2 = kInfinity;
673 
674  }
675  else return snxt ;
676  }
677  else if (ss1 >= 0 && ss2 <= 0 )
678  {
679  // Inside Area - calculate leaving distance
680  // *Don't* use exact distance to side for tolerance
681  // = ss1*std::cos(ang xz)
682  // = ss1/std::sqrt(1.0+tanxz*tanxz)
683  sn1 = 0 ;
684 
685  if ( ds1 > 0 )
686  {
687  if (ss1 > 0.5*kCarTolerance) sn2 = ss1/ds1 ; // Leave +ve side extent
688  else return snxt ; // Leave immediately by +ve
689  }
690  else sn2 = kInfinity ;
691 
692  if ( ds2 < 0 )
693  {
694  if ( ss2 < -0.5*kCarTolerance )
695  {
696  Dist = ss2/ds2 ; // Leave -ve side extent
697  if ( Dist < sn2 ) sn2 = Dist ;
698  }
699  else return snxt ;
700  }
701  }
702  else if (ss1 < 0 && ss2 > 0 )
703  {
704  // Within +/- plane cross-over areas (not on boundaries ss1||ss2==0)
705 
706  if ( ds1 >= 0 || ds2 <= 0 )
707  {
708  return snxt ;
709  }
710  else // Will intersect & stay inside
711  {
712  sn1 = ss1/ds1 ;
713  Dist = ss2/ds2 ;
714  if (Dist > sn1 ) sn1 = Dist ;
715  sn2 = kInfinity ;
716  }
717  }
718 
719  // Reduce allowed range of distances as appropriate
720 
721  if ( sn1 > smin ) smin = sn1 ;
722  if ( sn2 < smax ) smax = sn2 ;
723 
724  // Check for incompatible ranges (eg z intersects between 50 ->100 and x
725  // only 10-40 -> no intersection)
726 
727  if ( smax < smin ) return snxt ;
728 
729  // Calculate valid y intersection range
730  // (repeat of x intersection code)
731 
732  tanyz = (fDy2-fDy1)*0.5/fDz ;
733  s2 = 0.5*(fDy1+fDy2) + tanyz*p.z() ; // y half width at p.z
734  ds1 = v.y() - tanyz*v.z() ; // Components of v towards faces at +-y
735  ds2 = v.y() + tanyz*v.z() ;
736  ss1 = s2 - p.y() ; // -delta y to +ve plane
737  ss2 = -s2 - p.y() ; // -delta y to -ve plane
738 
739  if ( ss1 < 0 && ss2 <= 0 )
740  {
741  if (ds1 < 0 ) // In +ve coord Area
742  {
743  sn1 = ss1/ds1 ;
744  if ( ds2 < 0 ) sn2 = ss2/ds2 ;
745  else sn2 = kInfinity ;
746  }
747  else return snxt ;
748  }
749  else if ( ss1 >= 0 && ss2 > 0 )
750  {
751  if ( ds2 > 0 ) // In -ve coord Area
752  {
753  sn1 = ss2/ds2 ;
754  if ( ds1 > 0 ) sn2 = ss1/ds1 ;
755  else sn2 = kInfinity ;
756  }
757  else return snxt ;
758  }
759  else if (ss1 >= 0 && ss2 <= 0 )
760  {
761  // Inside Area - calculate leaving distance
762  // *Don't* use exact distance to side for tolerance
763  // = ss1*std::cos(ang yz)
764  // = ss1/std::sqrt(1.0+tanyz*tanyz)
765  sn1 = 0 ;
766 
767  if ( ds1 > 0 )
768  {
769  if (ss1 > 0.5*kCarTolerance) sn2 = ss1/ds1 ; // Leave +ve side extent
770  else return snxt ; // Leave immediately by +ve
771  }
772  else sn2 = kInfinity ;
773 
774  if ( ds2 < 0 )
775  {
776  if ( ss2 < -0.5*kCarTolerance )
777  {
778  Dist = ss2/ds2 ; // Leave -ve side extent
779  if (Dist < sn2) sn2=Dist;
780  }
781  else return snxt ;
782  }
783  }
784  else if (ss1 < 0 && ss2 > 0 )
785  {
786  // Within +/- plane cross-over areas (not on boundaries ss1||ss2==0)
787 
788  if (ds1 >= 0 || ds2 <= 0 )
789  {
790  return snxt ;
791  }
792  else // Will intersect & stay inside
793  {
794  sn1 = ss1/ds1 ;
795  Dist = ss2/ds2 ;
796  if (Dist > sn1 ) sn1 = Dist ;
797  sn2 = kInfinity ;
798  }
799  }
800 
801  // Reduce allowed range of distances as appropriate
802 
803  if ( sn1 > smin) smin = sn1 ;
804  if ( sn2 < smax) smax = sn2 ;
805 
806  // Check for incompatible ranges (eg x intersects between 50 ->100 and y
807  // only 10-40 -> no intersection). Set snxt if ok
808 
809  if ( smax > smin ) snxt = smin ;
810  if (snxt < 0.5*kCarTolerance ) snxt = 0.0 ;
811 
812  return snxt ;
813 }
814 
816 //
817 // Approximate distance to shape
818 // Calculate perpendicular distances to z/x/y surfaces, return largest
819 // which is the most fast estimation of shortest distance to Trd
820 // - Safe underestimate
821 // - If point within exact shape, return 0
822 
824 {
825  G4double safe=0.0;
826  G4double tanxz,distx,safx;
827  G4double tanyz,disty,safy;
828  G4double zbase;
829 
830  safe=std::fabs(p.z())-fDz;
831  if (safe<0) safe=0; // Also used to ensure x/y distances
832  // POSITIVE
833 
834  zbase=fDz+p.z();
835 
836  // Find distance along x direction to closest x plane
837  //
838  tanxz=(fDx2-fDx1)*0.5/fDz;
839  // widx=fDx1+tanxz*(fDz+p.z()); // x width at p.z
840  // distx=std::fabs(p.x())-widx; // distance to plane
841  distx=std::fabs(p.x())-(fDx1+tanxz*zbase);
842  if (distx>safe)
843  {
844  safx=distx/std::sqrt(1.0+tanxz*tanxz); // vector Dist=Dist*std::cos(ang)
845  if (safx>safe) safe=safx;
846  }
847 
848  // Find distance along y direction to slanted wall
849  tanyz=(fDy2-fDy1)*0.5/fDz;
850  // widy=fDy1+tanyz*(fDz+p.z()); // y width at p.z
851  // disty=std::fabs(p.y())-widy; // distance to plane
852  disty=std::fabs(p.y())-(fDy1+tanyz*zbase);
853  if (disty>safe)
854  {
855  safy=disty/std::sqrt(1.0+tanyz*tanyz); // distance along vector
856  if (safy>safe) safe=safy;
857  }
858  return safe;
859 }
860 
862 //
863 // Calcluate distance to surface of shape from inside
864 // Calculate distance to x/y/z planes - smallest is exiting distance
865 // - z planes have std. check for tolerance
866 // - xz yz planes have check based on distance || to x or y axis
867 // (not corrected for slope of planes)
868 // ?BUG? If v.z==0 are there cases when snside not set????
869 
871  const G4ThreeVector& v,
872  const G4bool calcNorm,
873  G4bool *validNorm,
874  G4ThreeVector *n ) const
875 {
876  ESide side = kUndefined, snside = kUndefined;
877  G4double snxt,pdist;
878  G4double central,ss1,ss2,ds1,ds2,sn=0.,sn2=0.;
879  G4double tanxz=0.,cosxz=0.,tanyz=0.,cosyz=0.;
880 
881  if (calcNorm) *validNorm=true; // All normals are valid
882 
883  // Calculate z plane intersection
884  if (v.z()>0)
885  {
886  pdist=fDz-p.z();
887  if (pdist>kCarTolerance/2)
888  {
889  snxt=pdist/v.z();
890  side=kPZ;
891  }
892  else
893  {
894  if (calcNorm)
895  {
896  *n=G4ThreeVector(0,0,1);
897  }
898  return snxt=0;
899  }
900  }
901  else if (v.z()<0)
902  {
903  pdist=fDz+p.z();
904  if (pdist>kCarTolerance/2)
905  {
906  snxt=-pdist/v.z();
907  side=kMZ;
908  }
909  else
910  {
911  if (calcNorm)
912  {
913  *n=G4ThreeVector(0,0,-1);
914  }
915  return snxt=0;
916  }
917  }
918  else
919  {
920  snxt=kInfinity;
921  }
922 
923  //
924  // Calculate x intersection
925  //
926  tanxz=(fDx2-fDx1)*0.5/fDz;
927  central=0.5*(fDx1+fDx2);
928 
929  // +ve plane (1)
930  //
931  ss1=central+tanxz*p.z()-p.x(); // distance || x axis to plane
932  // (+ve if point inside)
933  ds1=v.x()-tanxz*v.z(); // component towards plane at +x
934  // (-ve if +ve -> -ve direction)
935  // -ve plane (2)
936  //
937  ss2=-tanxz*p.z()-p.x()-central; //distance || x axis to plane
938  // (-ve if point inside)
939  ds2=tanxz*v.z()+v.x(); // component towards plane at -x
940 
941  if (ss1>0&&ss2<0)
942  {
943  // Normal case - entirely inside region
944  if (ds1<=0&&ds2<0)
945  {
946  if (ss2<-kCarTolerance/2)
947  {
948  sn=ss2/ds2; // Leave by -ve side
949  snside=kMX;
950  }
951  else
952  {
953  sn=0; // Leave immediately by -ve side
954  snside=kMX;
955  }
956  }
957  else if (ds1>0&&ds2>=0)
958  {
959  if (ss1>kCarTolerance/2)
960  {
961  sn=ss1/ds1; // Leave by +ve side
962  snside=kPX;
963  }
964  else
965  {
966  sn=0; // Leave immediately by +ve side
967  snside=kPX;
968  }
969  }
970  else if (ds1>0&&ds2<0)
971  {
972  if (ss1>kCarTolerance/2)
973  {
974  // sn=ss1/ds1; // Leave by +ve side
975  if (ss2<-kCarTolerance/2)
976  {
977  sn=ss1/ds1; // Leave by +ve side
978  sn2=ss2/ds2;
979  if (sn2<sn)
980  {
981  sn=sn2;
982  snside=kMX;
983  }
984  else
985  {
986  snside=kPX;
987  }
988  }
989  else
990  {
991  sn=0; // Leave immediately by -ve
992  snside=kMX;
993  }
994  }
995  else
996  {
997  sn=0; // Leave immediately by +ve side
998  snside=kPX;
999  }
1000  }
1001  else
1002  {
1003  // Must be || to both
1004  //
1005  sn=kInfinity; // Don't leave by either side
1006  }
1007  }
1008  else if (ss1<=0&&ss2<0)
1009  {
1010  // Outside, in +ve Area
1011 
1012  if (ds1>0)
1013  {
1014  sn=0; // Away from shape
1015  // Left by +ve side
1016  snside=kPX;
1017  }
1018  else
1019  {
1020  if (ds2<0)
1021  {
1022  // Ignore +ve plane and use -ve plane intersect
1023  //
1024  sn=ss2/ds2; // Leave by -ve side
1025  snside=kMX;
1026  }
1027  else
1028  {
1029  // Must be || to both -> exit determined by other axes
1030  //
1031  sn=kInfinity; // Don't leave by either side
1032  }
1033  }
1034  }
1035  else if (ss1>0&&ss2>=0)
1036  {
1037  // Outside, in -ve Area
1038 
1039  if (ds2<0)
1040  {
1041  sn=0; // away from shape
1042  // Left by -ve side
1043  snside=kMX;
1044  }
1045  else
1046  {
1047  if (ds1>0)
1048  {
1049  // Ignore +ve plane and use -ve plane intersect
1050  //
1051  sn=ss1/ds1; // Leave by +ve side
1052  snside=kPX;
1053  }
1054  else
1055  {
1056  // Must be || to both -> exit determined by other axes
1057  //
1058  sn=kInfinity; // Don't leave by either side
1059  }
1060  }
1061  }
1062 
1063  // Update minimum exit distance
1064 
1065  if (sn<snxt)
1066  {
1067  snxt=sn;
1068  side=snside;
1069  }
1070  if (snxt>0)
1071  {
1072  // Calculate y intersection
1073 
1074  tanyz=(fDy2-fDy1)*0.5/fDz;
1075  central=0.5*(fDy1+fDy2);
1076 
1077  // +ve plane (1)
1078  //
1079  ss1=central+tanyz*p.z()-p.y(); // distance || y axis to plane
1080  // (+ve if point inside)
1081  ds1=v.y()-tanyz*v.z(); // component towards +ve plane
1082  // (-ve if +ve -> -ve direction)
1083  // -ve plane (2)
1084  //
1085  ss2=-tanyz*p.z()-p.y()-central; // distance || y axis to plane
1086  // (-ve if point inside)
1087  ds2=tanyz*v.z()+v.y(); // component towards -ve plane
1088 
1089  if (ss1>0&&ss2<0)
1090  {
1091  // Normal case - entirely inside region
1092 
1093  if (ds1<=0&&ds2<0)
1094  {
1095  if (ss2<-kCarTolerance/2)
1096  {
1097  sn=ss2/ds2; // Leave by -ve side
1098  snside=kMY;
1099  }
1100  else
1101  {
1102  sn=0; // Leave immediately by -ve side
1103  snside=kMY;
1104  }
1105  }
1106  else if (ds1>0&&ds2>=0)
1107  {
1108  if (ss1>kCarTolerance/2)
1109  {
1110  sn=ss1/ds1; // Leave by +ve side
1111  snside=kPY;
1112  }
1113  else
1114  {
1115  sn=0; // Leave immediately by +ve side
1116  snside=kPY;
1117  }
1118  }
1119  else if (ds1>0&&ds2<0)
1120  {
1121  if (ss1>kCarTolerance/2)
1122  {
1123  // sn=ss1/ds1; // Leave by +ve side
1124  if (ss2<-kCarTolerance/2)
1125  {
1126  sn=ss1/ds1; // Leave by +ve side
1127  sn2=ss2/ds2;
1128  if (sn2<sn)
1129  {
1130  sn=sn2;
1131  snside=kMY;
1132  }
1133  else
1134  {
1135  snside=kPY;
1136  }
1137  }
1138  else
1139  {
1140  sn=0; // Leave immediately by -ve
1141  snside=kMY;
1142  }
1143  }
1144  else
1145  {
1146  sn=0; // Leave immediately by +ve side
1147  snside=kPY;
1148  }
1149  }
1150  else
1151  {
1152  // Must be || to both
1153  //
1154  sn=kInfinity; // Don't leave by either side
1155  }
1156  }
1157  else if (ss1<=0&&ss2<0)
1158  {
1159  // Outside, in +ve Area
1160 
1161  if (ds1>0)
1162  {
1163  sn=0; // Away from shape
1164  // Left by +ve side
1165  snside=kPY;
1166  }
1167  else
1168  {
1169  if (ds2<0)
1170  {
1171  // Ignore +ve plane and use -ve plane intersect
1172  //
1173  sn=ss2/ds2; // Leave by -ve side
1174  snside=kMY;
1175  }
1176  else
1177  {
1178  // Must be || to both -> exit determined by other axes
1179  //
1180  sn=kInfinity; // Don't leave by either side
1181  }
1182  }
1183  }
1184  else if (ss1>0&&ss2>=0)
1185  {
1186  // Outside, in -ve Area
1187  if (ds2<0)
1188  {
1189  sn=0; // away from shape
1190  // Left by -ve side
1191  snside=kMY;
1192  }
1193  else
1194  {
1195  if (ds1>0)
1196  {
1197  // Ignore +ve plane and use -ve plane intersect
1198  //
1199  sn=ss1/ds1; // Leave by +ve side
1200  snside=kPY;
1201  }
1202  else
1203  {
1204  // Must be || to both -> exit determined by other axes
1205  //
1206  sn=kInfinity; // Don't leave by either side
1207  }
1208  }
1209  }
1210 
1211  // Update minimum exit distance
1212 
1213  if (sn<snxt)
1214  {
1215  snxt=sn;
1216  side=snside;
1217  }
1218  }
1219 
1220  if (calcNorm)
1221  {
1222  switch (side)
1223  {
1224  case kPX:
1225  cosxz=1.0/std::sqrt(1.0+tanxz*tanxz);
1226  *n=G4ThreeVector(cosxz,0,-tanxz*cosxz);
1227  break;
1228  case kMX:
1229  cosxz=-1.0/std::sqrt(1.0+tanxz*tanxz);
1230  *n=G4ThreeVector(cosxz,0,tanxz*cosxz);
1231  break;
1232  case kPY:
1233  cosyz=1.0/std::sqrt(1.0+tanyz*tanyz);
1234  *n=G4ThreeVector(0,cosyz,-tanyz*cosyz);
1235  break;
1236  case kMY:
1237  cosyz=-1.0/std::sqrt(1.0+tanyz*tanyz);
1238  *n=G4ThreeVector(0,cosyz,tanyz*cosyz);
1239  break;
1240  case kPZ:
1241  *n=G4ThreeVector(0,0,1);
1242  break;
1243  case kMZ:
1244  *n=G4ThreeVector(0,0,-1);
1245  break;
1246  default:
1247  DumpInfo();
1248  G4Exception("G4Trd::DistanceToOut(p,v,..)",
1249  "GeomSolids1002", JustWarning,
1250  "Undefined side for valid surface normal to solid.");
1251  break;
1252  }
1253  }
1254  return snxt;
1255 }
1256 
1258 //
1259 // Calculate exact shortest distance to any boundary from inside
1260 // - Returns 0 is point outside
1261 
1263 {
1264  G4double safe=0.0;
1265  G4double tanxz,xdist,saf1;
1266  G4double tanyz,ydist,saf2;
1267  G4double zbase;
1268 
1269 #ifdef G4CSGDEBUG
1270  if( Inside(p) == kOutside )
1271  {
1272  G4int oldprc = G4cout.precision(16) ;
1273  G4cout << G4endl ;
1274  DumpInfo();
1275  G4cout << "Position:" << G4endl << G4endl ;
1276  G4cout << "p.x() = " << p.x()/mm << " mm" << G4endl ;
1277  G4cout << "p.y() = " << p.y()/mm << " mm" << G4endl ;
1278  G4cout << "p.z() = " << p.z()/mm << " mm" << G4endl << G4endl ;
1279  G4cout.precision(oldprc) ;
1280  G4Exception("G4Trd::DistanceToOut(p)", "GeomSolids1002", JustWarning,
1281  "Point p is outside !?" );
1282  }
1283 #endif
1284 
1285  safe=fDz-std::fabs(p.z()); // z perpendicular Dist
1286 
1287  zbase=fDz+p.z();
1288 
1289  // xdist = distance perpendicular to z axis to closest x plane from p
1290  // = (x half width of shape at p.z) - std::fabs(p.x)
1291  //
1292  tanxz=(fDx2-fDx1)*0.5/fDz;
1293  xdist=fDx1+tanxz*zbase-std::fabs(p.x());
1294  saf1=xdist/std::sqrt(1.0+tanxz*tanxz); // x*std::cos(ang_xz) =
1295  // shortest (perpendicular)
1296  // distance to plane
1297  tanyz=(fDy2-fDy1)*0.5/fDz;
1298  ydist=fDy1+tanyz*zbase-std::fabs(p.y());
1299  saf2=ydist/std::sqrt(1.0+tanyz*tanyz);
1300 
1301  // Return minimum x/y/z distance
1302  //
1303  if (safe>saf1) safe=saf1;
1304  if (safe>saf2) safe=saf2;
1305 
1306  if (safe<0) safe=0;
1307  return safe;
1308 }
1309 
1311 //
1312 // Create a List containing the transformed vertices
1313 // Ordering [0-3] -fDz cross section
1314 // [4-7] +fDz cross section such that [0] is below [4],
1315 // [1] below [5] etc.
1316 // Note:
1317 // Caller has deletion resposibility
1318 
1321 {
1322  G4ThreeVectorList *vertices;
1323  vertices=new G4ThreeVectorList();
1324  if (vertices)
1325  {
1326  vertices->reserve(8);
1327  G4ThreeVector vertex0(-fDx1,-fDy1,-fDz);
1328  G4ThreeVector vertex1(fDx1,-fDy1,-fDz);
1329  G4ThreeVector vertex2(fDx1,fDy1,-fDz);
1330  G4ThreeVector vertex3(-fDx1,fDy1,-fDz);
1331  G4ThreeVector vertex4(-fDx2,-fDy2,fDz);
1332  G4ThreeVector vertex5(fDx2,-fDy2,fDz);
1333  G4ThreeVector vertex6(fDx2,fDy2,fDz);
1334  G4ThreeVector vertex7(-fDx2,fDy2,fDz);
1335 
1336  vertices->push_back(pTransform.TransformPoint(vertex0));
1337  vertices->push_back(pTransform.TransformPoint(vertex1));
1338  vertices->push_back(pTransform.TransformPoint(vertex2));
1339  vertices->push_back(pTransform.TransformPoint(vertex3));
1340  vertices->push_back(pTransform.TransformPoint(vertex4));
1341  vertices->push_back(pTransform.TransformPoint(vertex5));
1342  vertices->push_back(pTransform.TransformPoint(vertex6));
1343  vertices->push_back(pTransform.TransformPoint(vertex7));
1344  }
1345  else
1346  {
1347  DumpInfo();
1348  G4Exception("G4Trd::CreateRotatedVertices()",
1349  "GeomSolids0003", FatalException,
1350  "Error in allocation of vertices. Out of memory !");
1351  }
1352  return vertices;
1353 }
1354 
1356 //
1357 // GetEntityType
1358 
1360 {
1361  return G4String("G4Trd");
1362 }
1363 
1365 //
1366 // Make a clone of the object
1367 //
1369 {
1370  return new G4Trd(*this);
1371 }
1372 
1374 //
1375 // Stream object contents to an output stream
1376 
1377 std::ostream& G4Trd::StreamInfo( std::ostream& os ) const
1378 {
1379  G4int oldprc = os.precision(16);
1380  os << "-----------------------------------------------------------\n"
1381  << " *** Dump for solid - " << GetName() << " ***\n"
1382  << " ===================================================\n"
1383  << " Solid type: G4Trd\n"
1384  << " Parameters: \n"
1385  << " half length X, surface -dZ: " << fDx1/mm << " mm \n"
1386  << " half length X, surface +dZ: " << fDx2/mm << " mm \n"
1387  << " half length Y, surface -dZ: " << fDy1/mm << " mm \n"
1388  << " half length Y, surface +dZ: " << fDy2/mm << " mm \n"
1389  << " half length Z : " << fDz/mm << " mm \n"
1390  << "-----------------------------------------------------------\n";
1391  os.precision(oldprc);
1392 
1393  return os;
1394 }
1395 
1396 
1398 //
1399 // GetPointOnSurface
1400 //
1401 // Return a point (G4ThreeVector) randomly and uniformly
1402 // selected on the solid surface
1403 
1405 {
1406  G4double px, py, pz, tgX, tgY, secX, secY, select, sumS, tmp;
1407  G4double Sxy1, Sxy2, Sxy, Sxz, Syz;
1408 
1409  tgX = 0.5*(fDx2-fDx1)/fDz;
1410  secX = std::sqrt(1+tgX*tgX);
1411  tgY = 0.5*(fDy2-fDy1)/fDz;
1412  secY = std::sqrt(1+tgY*tgY);
1413 
1414  // calculate 0.25 of side surfaces, sumS is 0.25 of total surface
1415 
1416  Sxy1 = fDx1*fDy1;
1417  Sxy2 = fDx2*fDy2;
1418  Sxy = Sxy1 + Sxy2;
1419  Sxz = (fDx1 + fDx2)*fDz*secY;
1420  Syz = (fDy1 + fDy2)*fDz*secX;
1421  sumS = Sxy + Sxz + Syz;
1422 
1423  select = sumS*G4UniformRand();
1424 
1425  if( select < Sxy ) // Sxy1 or Sxy2
1426  {
1427  if( select < Sxy1 )
1428  {
1429  pz = -fDz;
1430  px = -fDx1 + 2*fDx1*G4UniformRand();
1431  py = -fDy1 + 2*fDy1*G4UniformRand();
1432  }
1433  else
1434  {
1435  pz = fDz;
1436  px = -fDx2 + 2*fDx2*G4UniformRand();
1437  py = -fDy2 + 2*fDy2*G4UniformRand();
1438  }
1439  }
1440  else if ( ( select - Sxy ) < Sxz ) // Sxz
1441  {
1442  pz = -fDz + 2*fDz*G4UniformRand();
1443  tmp = fDx1 + (pz + fDz)*tgX;
1444  px = -tmp + 2*tmp*G4UniformRand();
1445  tmp = fDy1 + (pz + fDz)*tgY;
1446 
1447  if(G4UniformRand() > 0.5) { py = tmp; }
1448  else { py = -tmp; }
1449  }
1450  else // Syz
1451  {
1452  pz = -fDz + 2*fDz*G4UniformRand();
1453  tmp = fDy1 + (pz + fDz)*tgY;
1454  py = -tmp + 2*tmp*G4UniformRand();
1455  tmp = fDx1 + (pz + fDz)*tgX;
1456 
1457  if(G4UniformRand() > 0.5) { px = tmp; }
1458  else { px = -tmp; }
1459  }
1460  return G4ThreeVector(px,py,pz);
1461 }
1462 
1464 //
1465 // Methods for visualisation
1466 
1468 {
1469  scene.AddSolid (*this);
1470 }
1471 
1473 {
1474  return new G4PolyhedronTrd2 (fDx1, fDx2, fDy1, fDy2, fDz);
1475 }
1476 
1477 #endif
void DescribeYourselfTo(G4VGraphicsScene &scene) const
Definition: G4Trd.cc:1467
void SetAllParameters(G4double pdx1, G4double pdx2, G4double pdy1, G4double pdy2, G4double pdz)
Definition: G4Trd.cc:170
G4ThreeVectorList * CreateRotatedVertices(const G4AffineTransform &pTransform) const
Definition: G4Trd.cc:1320
G4double fDy2
Definition: G4Trd.hh:181
G4String GetName() const
~G4Trd()
Definition: G4Trd.cc:127
void ClipCrossSection(G4ThreeVectorList *pVertices, const G4int pSectionIndex, const G4VoxelLimits &pVoxelLimit, const EAxis pAxis, G4double &pMin, G4double &pMax) const
Definition: G4VSolid.cc:347
ESide
Definition: G4Trd.hh:157
static const G4double kInfinity
Definition: geomdefs.hh:42
G4double GetMinYExtent() const
CLHEP::Hep3Vector G4ThreeVector
G4AffineTransform Inverse() const
G4double z
Definition: TRTMaterials.hh:39
G4bool IsYLimited() const
std::ostream & StreamInfo(std::ostream &os) const
Definition: G4Trd.cc:1377
G4bool IsRotated() const
G4double fCubicVolume
Definition: G4CSGSolid.hh:78
G4ThreeVector NetTranslation() const
G4GeometryType GetEntityType() const
Definition: G4Trd.cc:1359
G4bool IsXLimited() const
G4double a
Definition: TRTMaterials.hh:39
Definition: G4Trd.hh:72
G4double fcos(G4double arg)
virtual void AddSolid(const G4Box &)=0
int G4int
Definition: G4Types.hh:78
const G4int smax
void DumpInfo() const
G4VSolid * Clone() const
Definition: G4Trd.cc:1368
G4ThreeVector GetPointOnSurface() const
Definition: G4Trd.cc:1404
G4ThreeVector ApproxSurfaceNormal(const G4ThreeVector &p) const
Definition: G4Trd.cc:504
G4double fDy1
Definition: G4Trd.hh:181
G4double GetMaxXExtent() const
G4double GetMinZExtent() const
#define G4UniformRand()
Definition: Randomize.hh:87
G4double fSurfaceArea
Definition: G4CSGSolid.hh:79
G4GLOB_DLL std::ostream G4cout
G4Polyhedron * CreatePolyhedron() const
Definition: G4Trd.cc:1472
G4double DistanceToIn(const G4ThreeVector &p, const G4ThreeVector &v) const
Definition: G4Trd.cc:597
G4Polyhedron * fpPolyhedron
Definition: G4CSGSolid.hh:80
bool G4bool
Definition: G4Types.hh:79
virtual G4Polyhedron * GetPolyhedron() const
Definition: G4CSGSolid.cc:124
std::vector< G4ThreeVector > G4ThreeVectorList
Definition: G4VSolid.hh:79
EInside Inside(const G4ThreeVector &p) const
Definition: G4Trd.cc:372
const G4int n
G4double fDx2
Definition: G4Trd.hh:181
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *comments)
Definition: G4Exception.cc:41
virtual void ComputeDimensions(G4Box &, const G4int, const G4VPhysicalVolume *) const
G4double GetMinXExtent() const
G4ThreeVector TransformPoint(const G4ThreeVector &vec) const
G4double GetMaxZExtent() const
T max(const T t1, const T t2)
brief Return the largest of the two arguments
EInside
Definition: geomdefs.hh:58
EAxis
Definition: geomdefs.hh:54
G4double DistanceToOut(const G4ThreeVector &p, const G4ThreeVector &v, const G4bool calcNorm=false, G4bool *validNorm=0, G4ThreeVector *n=0) const
Definition: G4Trd.cc:870
void CheckAndSetAllParameters(G4double pdx1, G4double pdx2, G4double pdy1, G4double pdy2, G4double pdz)
Definition: G4Trd.cc:72
G4Trd & operator=(const G4Trd &rhs)
Definition: G4Trd.cc:146
void ComputeDimensions(G4VPVParameterisation *p, const G4int n, const G4VPhysicalVolume *pRep)
Definition: G4Trd.cc:182
G4ThreeVector SurfaceNormal(const G4ThreeVector &p) const
Definition: G4Trd.cc:435
#define G4endl
Definition: G4ios.hh:61
G4double GetMaxYExtent() const
G4double kCarTolerance
Definition: G4VSolid.hh:305
G4Trd(const G4String &pName, G4double pdx1, G4double pdx2, G4double pdy1, G4double pdy2, G4double pdz)
Definition: G4Trd.cc:59
G4bool CalculateExtent(const EAxis pAxis, const G4VoxelLimits &pVoxelLimit, const G4AffineTransform &pTransform, G4double &pMin, G4double &pMax) const
Definition: G4Trd.cc:194
double G4double
Definition: G4Types.hh:76
G4double GetMaxExtent(const EAxis pAxis) const
G4CSGSolid & operator=(const G4CSGSolid &rhs)
Definition: G4CSGSolid.cc:82
G4double fDz
Definition: G4Trd.hh:181
G4double fDx1
Definition: G4Trd.hh:181
G4bool IsZLimited() const
static const double mm
Definition: G4SIunits.hh:102
void ClipBetweenSections(G4ThreeVectorList *pVertices, const G4int pSectionIndex, const G4VoxelLimits &pVoxelLimit, const EAxis pAxis, G4double &pMin, G4double &pMax) const
Definition: G4VSolid.cc:378
G4double GetMinExtent(const EAxis pAxis) const