Geant4  10.00.p02
G4VTwistedFaceted.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 // $Id: G4VTwistedFaceted.cc 81641 2014-06-04 09:11:38Z gcosmo $
27 //
28 //
29 // --------------------------------------------------------------------
30 // GEANT 4 class source file
31 //
32 //
33 // G4VTwistedFaceted.cc
34 //
35 // Author:
36 //
37 // 04-Nov-2004 - O.Link (Oliver.Link@cern.ch)
38 //
39 // --------------------------------------------------------------------
40 
41 #include "G4VTwistedFaceted.hh"
42 
43 #include "G4PhysicalConstants.hh"
44 #include "G4SystemOfUnits.hh"
45 #include "G4VoxelLimits.hh"
46 #include "G4AffineTransform.hh"
47 #include "G4SolidExtentList.hh"
48 #include "G4ClippablePolygon.hh"
49 #include "G4VPVParameterisation.hh"
50 #include "G4GeometryTolerance.hh"
51 #include "meshdefs.hh"
52 
53 #include "G4VGraphicsScene.hh"
54 #include "G4Polyhedron.hh"
55 #include "G4VisExtent.hh"
56 
57 #include "Randomize.hh"
58 
59 //=====================================================================
60 //* constructors ------------------------------------------------------
61 
63 G4VTwistedFaceted( const G4String &pname, // Name of instance
64  G4double PhiTwist, // twist angle
65  G4double pDz, // half z length
66  G4double pTheta, // direction between end planes
67  G4double pPhi, // defined by polar and azim. angles
68  G4double pDy1, // half y length at -pDz
69  G4double pDx1, // half x length at -pDz,-pDy
70  G4double pDx2, // half x length at -pDz,+pDy
71  G4double pDy2, // half y length at +pDz
72  G4double pDx3, // half x length at +pDz,-pDy
73  G4double pDx4, // half x length at +pDz,+pDy
74  G4double pAlph // tilt angle
75  )
76  : G4VSolid(pname), fpPolyhedron(0),
77  fLowerEndcap(0), fUpperEndcap(0), fSide0(0),
78  fSide90(0), fSide180(0), fSide270(0),
79  fSurfaceArea(0.)
80 {
81 
82  G4double pDytmp ;
83  G4double fDxUp ;
84  G4double fDxDown ;
85 
86  fDx1 = pDx1 ;
87  fDx2 = pDx2 ;
88  fDx3 = pDx3 ;
89  fDx4 = pDx4 ;
90  fDy1 = pDy1 ;
91  fDy2 = pDy2 ;
92  fDz = pDz ;
93 
94  G4double kAngTolerance
96 
97  // maximum values
98  //
99  fDxDown = ( fDx1 > fDx2 ? fDx1 : fDx2 ) ;
100  fDxUp = ( fDx3 > fDx4 ? fDx3 : fDx4 ) ;
101  fDx = ( fDxUp > fDxDown ? fDxUp : fDxDown ) ;
102  fDy = ( fDy1 > fDy2 ? fDy1 : fDy2 ) ;
103 
104  // planarity check
105  //
106  if ( fDx1 != fDx2 && fDx3 != fDx4 )
107  {
108  pDytmp = fDy1 * ( fDx3 - fDx4 ) / ( fDx1 - fDx2 ) ;
109  if ( std::fabs(pDytmp - fDy2) > kCarTolerance )
110  {
111  std::ostringstream message;
112  message << "Not planar surface in untwisted Trapezoid: "
113  << GetName() << G4endl
114  << "fDy2 is " << fDy2 << " but should be "
115  << pDytmp << ".";
116  G4Exception("G4VTwistedFaceted::G4VTwistedFaceted()", "GeomSolids0002",
117  FatalErrorInArgument, message);
118  }
119  }
120 
121 #ifdef G4TWISTDEBUG
122  if ( fDx1 == fDx2 && fDx3 == fDx4 )
123  {
124  G4cout << "Trapezoid is a box" << G4endl ;
125  }
126 
127 #endif
128 
129  if ( ( fDx1 == fDx2 && fDx3 != fDx4 ) || ( fDx1 != fDx2 && fDx3 == fDx4 ) )
130  {
131  std::ostringstream message;
132  message << "Not planar surface in untwisted Trapezoid: "
133  << GetName() << G4endl
134  << "One endcap is rectangular, the other is a trapezoid." << G4endl
135  << "For planarity reasons they have to be rectangles or trapezoids "
136  << "on both sides.";
137  G4Exception("G4VTwistedFaceted::G4VTwistedFaceted()", "GeomSolids0002",
138  FatalErrorInArgument, message);
139  }
140 
141  // twist angle
142  //
143  fPhiTwist = PhiTwist ;
144 
145  // tilt angle
146  //
147  fAlph = pAlph ;
148  fTAlph = std::tan(fAlph) ;
149 
150  fTheta = pTheta ;
151  fPhi = pPhi ;
152 
153  // dx in surface equation
154  //
155  fdeltaX = 2 * fDz * std::tan(fTheta) * std::cos(fPhi) ;
156 
157  // dy in surface equation
158  //
159  fdeltaY = 2 * fDz * std::tan(fTheta) * std::sin(fPhi) ;
160 
161  if ( ! ( ( fDx1 > 2*kCarTolerance)
162  && ( fDx2 > 2*kCarTolerance)
163  && ( fDx3 > 2*kCarTolerance)
164  && ( fDx4 > 2*kCarTolerance)
165  && ( fDy1 > 2*kCarTolerance)
166  && ( fDy2 > 2*kCarTolerance)
167  && ( fDz > 2*kCarTolerance)
168  && ( std::fabs(fPhiTwist) > 2*kAngTolerance )
169  && ( std::fabs(fPhiTwist) < pi/2 )
170  && ( std::fabs(fAlph) < pi/2 )
171  && ( fTheta < pi/2 && fTheta >= 0 ) )
172  )
173  {
174  std::ostringstream message;
175  message << "Invalid dimensions. Too small, or twist angle too big: "
176  << GetName() << G4endl
177  << "fDx 1-4 = " << fDx1/cm << ", " << fDx2/cm << ", "
178  << fDx3/cm << ", " << fDx4/cm << " cm" << G4endl
179  << "fDy 1-2 = " << fDy1/cm << ", " << fDy2/cm << ", "
180  << " cm" << G4endl
181  << "fDz = " << fDz/cm << " cm" << G4endl
182  << " twistangle " << fPhiTwist/deg << " deg" << G4endl
183  << " phi,theta = " << fPhi/deg << ", " << fTheta/deg << " deg";
184  G4Exception("G4TwistedTrap::G4VTwistedFaceted()",
185  "GeomSolids0002", FatalErrorInArgument, message);
186  }
187  CreateSurfaces();
188  fCubicVolume = 2 * fDz * ( ( fDx1 + fDx2 ) * fDy1 + ( fDx3 + fDx4 ) * fDy2 );
189 }
190 
191 
192 //=====================================================================
193 //* Fake default constructor ------------------------------------------
194 
196  : G4VSolid(a), fpPolyhedron(0), fTheta(0.), fPhi(0.), fDy1(0.),
197  fDx1(0.), fDx2(0.), fDy2(0.), fDx3(0.), fDx4(0.),
198  fDz(0.), fDx(0.), fDy(0.), fAlph(0.),
199  fTAlph(0.), fdeltaX(0.), fdeltaY(0.), fPhiTwist(0.),
200  fLowerEndcap(0), fUpperEndcap(0), fSide0(0), fSide90(0), fSide180(0),
201  fSide270(0), fCubicVolume(0.), fSurfaceArea(0.)
202 {
203 }
204 
205 //=====================================================================
206 //* destructor --------------------------------------------------------
207 
209 {
210  if (fLowerEndcap) delete fLowerEndcap ;
211  if (fUpperEndcap) delete fUpperEndcap ;
212 
213  if (fSide0) delete fSide0 ;
214  if (fSide90) delete fSide90 ;
215  if (fSide180) delete fSide180 ;
216  if (fSide270) delete fSide270 ;
217  if (fpPolyhedron) delete fpPolyhedron;
218 }
219 
220 //=====================================================================
221 //* Copy constructor --------------------------------------------------
222 
224  : G4VSolid(rhs), fpPolyhedron(0), fTheta(rhs.fTheta), fPhi(rhs.fPhi),
225  fDy1(rhs.fDy1), fDx1(rhs.fDx1), fDx2(rhs.fDx2), fDy2(rhs.fDy2),
226  fDx3(rhs.fDx3), fDx4(rhs.fDx4), fDz(rhs.fDz), fDx(rhs.fDx), fDy(rhs.fDy),
227  fAlph(rhs.fAlph), fTAlph(rhs.fTAlph), fdeltaX(rhs.fdeltaX),
228  fdeltaY(rhs.fdeltaY), fPhiTwist(rhs.fPhiTwist), fLowerEndcap(0),
229  fUpperEndcap(0), fSide0(0), fSide90(0), fSide180(0), fSide270(0),
230  fCubicVolume(rhs.fCubicVolume), fSurfaceArea(rhs.fSurfaceArea),
231  fLastInside(rhs.fLastInside), fLastNormal(rhs.fLastNormal),
232  fLastDistanceToIn(rhs.fLastDistanceToIn),
233  fLastDistanceToOut(rhs.fLastDistanceToOut),
234  fLastDistanceToInWithV(rhs.fLastDistanceToInWithV),
235  fLastDistanceToOutWithV(rhs.fLastDistanceToOutWithV)
236 {
237  CreateSurfaces();
238 }
239 
240 
241 //=====================================================================
242 //* Assignment operator -----------------------------------------------
243 
245 {
246  // Check assignment to self
247  //
248  if (this == &rhs) { return *this; }
249 
250  // Copy base class data
251  //
252  G4VSolid::operator=(rhs);
253 
254  // Copy data
255  //
256  fTheta = rhs.fTheta; fPhi = rhs.fPhi;
257  fDy1= rhs.fDy1; fDx1= rhs.fDx1; fDx2= rhs.fDx2; fDy2= rhs.fDy2;
258  fDx3= rhs.fDx3; fDx4= rhs.fDx4; fDz= rhs.fDz; fDx= rhs.fDx; fDy= rhs.fDy;
259  fAlph= rhs.fAlph; fTAlph= rhs.fTAlph; fdeltaX= rhs.fdeltaX;
261  fUpperEndcap= 0; fSide0= 0; fSide90= 0; fSide180= 0; fSide270= 0;
263  delete fpPolyhedron; fpPolyhedron= 0;
269 
270  CreateSurfaces();
271 
272  return *this;
273 }
274 
275 //=====================================================================
276 //* ComputeDimensions -------------------------------------------------
277 
279  const G4int ,
280  const G4VPhysicalVolume* )
281 {
282  G4Exception("G4VTwistedFaceted::ComputeDimensions()",
283  "GeomSolids0001", FatalException,
284  "G4VTwistedFaceted does not support Parameterisation.");
285 }
286 
287 //=====================================================================
288 //* CalculateExtent ---------------------------------------------------
289 
290 G4bool
292  const G4VoxelLimits &pVoxelLimit,
293  const G4AffineTransform &pTransform,
294  G4double &pMin,
295  G4double &pMax ) const
296 {
297  G4double maxRad = std::sqrt( fDx*fDx + fDy*fDy);
298 
299  if (!pTransform.IsRotated())
300  {
301  // Special case handling for unrotated boxes
302  // Compute x/y/z mins and maxs respecting limits, with early returns
303  // if outside limits. Then switch() on pAxis
304 
305  G4double xoffset,xMin,xMax;
306  G4double yoffset,yMin,yMax;
307  G4double zoffset,zMin,zMax;
308 
309  xoffset = pTransform.NetTranslation().x() ;
310  xMin = xoffset - maxRad ;
311  xMax = xoffset + maxRad ;
312 
313  if (pVoxelLimit.IsXLimited())
314  {
315  if ( xMin > pVoxelLimit.GetMaxXExtent()+kCarTolerance ||
316  xMax < pVoxelLimit.GetMinXExtent()-kCarTolerance ) return false;
317  else
318  {
319  if (xMin < pVoxelLimit.GetMinXExtent())
320  {
321  xMin = pVoxelLimit.GetMinXExtent() ;
322  }
323  if (xMax > pVoxelLimit.GetMaxXExtent())
324  {
325  xMax = pVoxelLimit.GetMaxXExtent() ;
326  }
327  }
328  }
329  yoffset = pTransform.NetTranslation().y() ;
330  yMin = yoffset - maxRad ;
331  yMax = yoffset + maxRad ;
332 
333  if (pVoxelLimit.IsYLimited())
334  {
335  if ( yMin > pVoxelLimit.GetMaxYExtent()+kCarTolerance ||
336  yMax < pVoxelLimit.GetMinYExtent()-kCarTolerance ) return false;
337  else
338  {
339  if (yMin < pVoxelLimit.GetMinYExtent())
340  {
341  yMin = pVoxelLimit.GetMinYExtent() ;
342  }
343  if (yMax > pVoxelLimit.GetMaxYExtent())
344  {
345  yMax = pVoxelLimit.GetMaxYExtent() ;
346  }
347  }
348  }
349  zoffset = pTransform.NetTranslation().z() ;
350  zMin = zoffset - fDz ;
351  zMax = zoffset + fDz ;
352 
353  if (pVoxelLimit.IsZLimited())
354  {
355  if ( zMin > pVoxelLimit.GetMaxZExtent()+kCarTolerance ||
356  zMax < pVoxelLimit.GetMinZExtent()-kCarTolerance ) return false;
357  else
358  {
359  if (zMin < pVoxelLimit.GetMinZExtent())
360  {
361  zMin = pVoxelLimit.GetMinZExtent() ;
362  }
363  if (zMax > pVoxelLimit.GetMaxZExtent())
364  {
365  zMax = pVoxelLimit.GetMaxZExtent() ;
366  }
367  }
368  }
369  switch (pAxis)
370  {
371  case kXAxis:
372  pMin = xMin ;
373  pMax = xMax ;
374  break ;
375  case kYAxis:
376  pMin=yMin;
377  pMax=yMax;
378  break;
379  case kZAxis:
380  pMin=zMin;
381  pMax=zMax;
382  break;
383  default:
384  break;
385  }
386  pMin -= kCarTolerance ;
387  pMax += kCarTolerance ;
388 
389  return true;
390  }
391  else // General rotated case - create and clip mesh to boundaries
392  {
393  G4bool existsAfterClip = false ;
394  G4ThreeVectorList* vertices ;
395 
396  pMin = +kInfinity ;
397  pMax = -kInfinity ;
398 
399  // Calculate rotated vertex coordinates
400 
401  vertices = CreateRotatedVertices(pTransform) ;
402  ClipCrossSection(vertices,0,pVoxelLimit,pAxis,pMin,pMax) ;
403  ClipCrossSection(vertices,4,pVoxelLimit,pAxis,pMin,pMax) ;
404  ClipBetweenSections(vertices,0,pVoxelLimit,pAxis,pMin,pMax) ;
405 
406  if (pVoxelLimit.IsLimited(pAxis) == false)
407  {
408  if ( pMin != kInfinity || pMax != -kInfinity )
409  {
410  existsAfterClip = true ;
411 
412  // Add 2*tolerance to avoid precision troubles
413 
414  pMin -= kCarTolerance;
415  pMax += kCarTolerance;
416  }
417  }
418  else
419  {
420  G4ThreeVector clipCentre(
421  ( pVoxelLimit.GetMinXExtent()+pVoxelLimit.GetMaxXExtent())*0.5,
422  ( pVoxelLimit.GetMinYExtent()+pVoxelLimit.GetMaxYExtent())*0.5,
423  ( pVoxelLimit.GetMinZExtent()+pVoxelLimit.GetMaxZExtent())*0.5 );
424 
425  if ( pMin != kInfinity || pMax != -kInfinity )
426  {
427  existsAfterClip = true ;
428 
429  // Check to see if endpoints are in the solid
430 
431  clipCentre(pAxis) = pVoxelLimit.GetMinExtent(pAxis);
432 
433  if (Inside(pTransform.Inverse().TransformPoint(clipCentre))
434  != kOutside)
435  {
436  pMin = pVoxelLimit.GetMinExtent(pAxis);
437  }
438  else
439  {
440  pMin -= kCarTolerance;
441  }
442  clipCentre(pAxis) = pVoxelLimit.GetMaxExtent(pAxis);
443 
444  if (Inside(pTransform.Inverse().TransformPoint(clipCentre))
445  != kOutside)
446  {
447  pMax = pVoxelLimit.GetMaxExtent(pAxis);
448  }
449  else
450  {
451  pMax += kCarTolerance;
452  }
453  }
454 
455  // Check for case where completely enveloping clipping volume
456  // If point inside then we are confident that the solid completely
457  // envelopes the clipping volume. Hence set min/max extents according
458  // to clipping volume extents along the specified axis.
459 
460  else if (Inside(pTransform.Inverse().TransformPoint(clipCentre))
461  != kOutside)
462  {
463  existsAfterClip = true ;
464  pMin = pVoxelLimit.GetMinExtent(pAxis) ;
465  pMax = pVoxelLimit.GetMaxExtent(pAxis) ;
466  }
467  }
468  delete vertices;
469  return existsAfterClip;
470  }
471 
472 
473 }
474 
476 CreateRotatedVertices(const G4AffineTransform& pTransform) const
477 {
478 
479  G4ThreeVectorList* vertices = new G4ThreeVectorList();
480 
481  if (vertices)
482  {
483  vertices->reserve(8);
484 
485  G4double maxRad = std::sqrt( fDx*fDx + fDy*fDy);
486 
487  G4ThreeVector vertex0(-maxRad,-maxRad,-fDz) ;
488  G4ThreeVector vertex1(maxRad,-maxRad,-fDz) ;
489  G4ThreeVector vertex2(maxRad,maxRad,-fDz) ;
490  G4ThreeVector vertex3(-maxRad,maxRad,-fDz) ;
491  G4ThreeVector vertex4(-maxRad,-maxRad,fDz) ;
492  G4ThreeVector vertex5(maxRad,-maxRad,fDz) ;
493  G4ThreeVector vertex6(maxRad,maxRad,fDz) ;
494  G4ThreeVector vertex7(-maxRad,maxRad,fDz) ;
495 
496  vertices->push_back(pTransform.TransformPoint(vertex0));
497  vertices->push_back(pTransform.TransformPoint(vertex1));
498  vertices->push_back(pTransform.TransformPoint(vertex2));
499  vertices->push_back(pTransform.TransformPoint(vertex3));
500  vertices->push_back(pTransform.TransformPoint(vertex4));
501  vertices->push_back(pTransform.TransformPoint(vertex5));
502  vertices->push_back(pTransform.TransformPoint(vertex6));
503  vertices->push_back(pTransform.TransformPoint(vertex7));
504  }
505  else
506  {
507  DumpInfo();
508  G4Exception("G4VTwistedFaceted::CreateRotatedVertices()",
509  "GeomSolids0003", FatalException,
510  "Error in allocation of vertices. Out of memory !");
511  }
512  return vertices;
513 }
514 
515 //=====================================================================
516 //* Inside ------------------------------------------------------------
517 
519 {
520 
521  G4ThreeVector *tmpp;
522  EInside *tmpin;
523  if (fLastInside.p == p) {
524  return fLastInside.inside;
525  } else {
526  tmpp = const_cast<G4ThreeVector*>(&(fLastInside.p));
527  tmpin = const_cast<EInside*>(&(fLastInside.inside));
528  tmpp->set(p.x(), p.y(), p.z());
529  }
530 
531  *tmpin = kOutside ;
532 
533  G4double phi = p.z()/(2*fDz) * fPhiTwist ; // rotate the point to z=0
534  G4double cphi = std::cos(-phi) ;
535  G4double sphi = std::sin(-phi) ;
536 
537  G4double px = p.x() + fdeltaX * ( -phi/fPhiTwist) ; // shift
538  G4double py = p.y() + fdeltaY * ( -phi/fPhiTwist) ;
539  G4double pz = p.z() ;
540 
541  G4double posx = px * cphi - py * sphi ; // rotation
542  G4double posy = px * sphi + py * cphi ;
543  G4double posz = pz ;
544 
545  G4double xMin = Xcoef(posy,phi,fTAlph) - 2*Xcoef(posy,phi,0.) ;
546  G4double xMax = Xcoef(posy,phi,fTAlph) ;
547 
548  G4double yMax = GetValueB(phi)/2. ; // b(phi)/2 is limit
549  G4double yMin = -yMax ;
550 
551 #ifdef G4TWISTDEBUG
552 
553  G4cout << "inside called: p = " << p << G4endl ;
554  G4cout << "fDx1 = " << fDx1 << G4endl ;
555  G4cout << "fDx2 = " << fDx2 << G4endl ;
556  G4cout << "fDx3 = " << fDx3 << G4endl ;
557  G4cout << "fDx4 = " << fDx4 << G4endl ;
558 
559  G4cout << "fDy1 = " << fDy1 << G4endl ;
560  G4cout << "fDy2 = " << fDy2 << G4endl ;
561 
562  G4cout << "fDz = " << fDz << G4endl ;
563 
564  G4cout << "Tilt angle alpha = " << fAlph << G4endl ;
565  G4cout << "phi,theta = " << fPhi << " , " << fTheta << G4endl ;
566 
567  G4cout << "Twist angle = " << fPhiTwist << G4endl ;
568 
569  G4cout << "posx = " << posx << G4endl ;
570  G4cout << "posy = " << posy << G4endl ;
571  G4cout << "xMin = " << xMin << G4endl ;
572  G4cout << "xMax = " << xMax << G4endl ;
573  G4cout << "yMin = " << yMin << G4endl ;
574  G4cout << "yMax = " << yMax << G4endl ;
575 
576 #endif
577 
578 
579  if ( posx <= xMax - kCarTolerance*0.5
580  && posx >= xMin + kCarTolerance*0.5 )
581  {
582  if ( posy <= yMax - kCarTolerance*0.5
583  && posy >= yMin + kCarTolerance*0.5 )
584  {
585  if (std::fabs(posz) <= fDz - kCarTolerance*0.5 ) *tmpin = kInside ;
586  else if (std::fabs(posz) <= fDz + kCarTolerance*0.5 ) *tmpin = kSurface ;
587  }
588  else if ( posy <= yMax + kCarTolerance*0.5
589  && posy >= yMin - kCarTolerance*0.5 )
590  {
591  if (std::fabs(posz) <= fDz + kCarTolerance*0.5 ) *tmpin = kSurface ;
592  }
593  }
594  else if ( posx <= xMax + kCarTolerance*0.5
595  && posx >= xMin - kCarTolerance*0.5 )
596  {
597  if ( posy <= yMax + kCarTolerance*0.5
598  && posy >= yMin - kCarTolerance*0.5 )
599  {
600  if (std::fabs(posz) <= fDz + kCarTolerance*0.5) *tmpin = kSurface ;
601  }
602  }
603 
604 #ifdef G4TWISTDEBUG
605  G4cout << "inside = " << fLastInside.inside << G4endl ;
606 #endif
607 
608  return fLastInside.inside;
609 
610 }
611 
612 //=====================================================================
613 //* SurfaceNormal -----------------------------------------------------
614 
616 {
617  //
618  // return the normal unit vector to the Hyperbolical Surface at a point
619  // p on (or nearly on) the surface
620  //
621  // Which of the three or four surfaces are we closest to?
622  //
623 
624  if (fLastNormal.p == p)
625  {
626  return fLastNormal.vec;
627  }
628 
629  G4ThreeVector *tmpp = const_cast<G4ThreeVector*>(&(fLastNormal.p));
630  G4ThreeVector *tmpnormal = const_cast<G4ThreeVector*>(&(fLastNormal.vec));
631  G4VTwistSurface **tmpsurface = const_cast<G4VTwistSurface**>(fLastNormal.surface);
632  tmpp->set(p.x(), p.y(), p.z());
633 
634  G4double distance = kInfinity;
635 
636  G4VTwistSurface *surfaces[6];
637 
638  surfaces[0] = fSide0 ;
639  surfaces[1] = fSide90 ;
640  surfaces[2] = fSide180 ;
641  surfaces[3] = fSide270 ;
642  surfaces[4] = fLowerEndcap;
643  surfaces[5] = fUpperEndcap;
644 
645  G4ThreeVector xx;
646  G4ThreeVector bestxx;
647  G4int i;
648  G4int besti = -1;
649  for (i=0; i< 6; i++)
650  {
651  G4double tmpdistance = surfaces[i]->DistanceTo(p, xx);
652  if (tmpdistance < distance)
653  {
654  distance = tmpdistance;
655  bestxx = xx;
656  besti = i;
657  }
658  }
659 
660  tmpsurface[0] = surfaces[besti];
661  *tmpnormal = tmpsurface[0]->GetNormal(bestxx, true);
662 
663  return fLastNormal.vec;
664 }
665 
666 //=====================================================================
667 //* DistanceToIn (p, v) -----------------------------------------------
668 
670  const G4ThreeVector& v ) const
671 {
672 
673  // DistanceToIn (p, v):
674  // Calculate distance to surface of shape from `outside'
675  // along with the v, allowing for tolerance.
676  // The function returns kInfinity if no intersection or
677  // just grazing within tolerance.
678 
679  //
680  // checking last value
681  //
682 
683  G4ThreeVector *tmpp;
684  G4ThreeVector *tmpv;
685  G4double *tmpdist;
687  {
688  return fLastDistanceToIn.value;
689  }
690  else
691  {
692  tmpp = const_cast<G4ThreeVector*>(&(fLastDistanceToInWithV.p));
693  tmpv = const_cast<G4ThreeVector*>(&(fLastDistanceToInWithV.vec));
694  tmpdist = const_cast<G4double*>(&(fLastDistanceToInWithV.value));
695  tmpp->set(p.x(), p.y(), p.z());
696  tmpv->set(v.x(), v.y(), v.z());
697  }
698 
699  //
700  // Calculate DistanceToIn(p,v)
701  //
702 
703  EInside currentside = Inside(p);
704 
705  if (currentside == kInside)
706  {
707  }
708  else if (currentside == kSurface)
709  {
710  // particle is just on a boundary.
711  // if the particle is entering to the volume, return 0
712  //
714  if (normal*v < 0)
715  {
716  *tmpdist = 0;
718  }
719  }
720 
721  // now, we can take smallest positive distance.
722 
723  // Initialize
724  //
725  G4double distance = kInfinity;
726 
727  // Find intersections and choose nearest one
728  //
729  G4VTwistSurface *surfaces[6];
730 
731  surfaces[0] = fSide0;
732  surfaces[1] = fSide90 ;
733  surfaces[2] = fSide180 ;
734  surfaces[3] = fSide270 ;
735  surfaces[4] = fLowerEndcap;
736  surfaces[5] = fUpperEndcap;
737 
738  G4ThreeVector xx;
739  G4ThreeVector bestxx;
740  G4int i;
741  for (i=0; i < 6 ; i++)
742  {
743 #ifdef G4TWISTDEBUG
744  G4cout << G4endl << "surface " << i << ": " << G4endl << G4endl ;
745 #endif
746  G4double tmpdistance = surfaces[i]->DistanceToIn(p, v, xx);
747 #ifdef G4TWISTDEBUG
748  G4cout << "Solid DistanceToIn : distance = " << tmpdistance << G4endl ;
749  G4cout << "intersection point = " << xx << G4endl ;
750 #endif
751  if (tmpdistance < distance)
752  {
753  distance = tmpdistance;
754  bestxx = xx;
755  }
756  }
757 
758 #ifdef G4TWISTDEBUG
759  G4cout << "best distance = " << distance << G4endl ;
760 #endif
761 
762  *tmpdist = distance;
763  // timer.Stop();
765 }
766 
767 
769 {
770  // DistanceToIn(p):
771  // Calculate distance to surface of shape from `outside',
772  // allowing for tolerance
773  //
774 
775  //
776  // checking last value
777  //
778 
779  G4ThreeVector *tmpp;
780  G4double *tmpdist;
781  if (fLastDistanceToIn.p == p)
782  {
783  return fLastDistanceToIn.value;
784  }
785  else
786  {
787  tmpp = const_cast<G4ThreeVector*>(&(fLastDistanceToIn.p));
788  tmpdist = const_cast<G4double*>(&(fLastDistanceToIn.value));
789  tmpp->set(p.x(), p.y(), p.z());
790  }
791 
792  //
793  // Calculate DistanceToIn(p)
794  //
795 
796  EInside currentside = Inside(p);
797 
798  switch (currentside)
799  {
800  case (kInside) :
801  {
802  }
803 
804  case (kSurface) :
805  {
806  *tmpdist = 0.;
807  return fLastDistanceToIn.value;
808  }
809 
810  case (kOutside) :
811  {
812  // Initialize
813  //
814  G4double distance = kInfinity;
815 
816  // Find intersections and choose nearest one
817  //
818  G4VTwistSurface *surfaces[6];
819 
820  surfaces[0] = fSide0;
821  surfaces[1] = fSide90 ;
822  surfaces[2] = fSide180 ;
823  surfaces[3] = fSide270 ;
824  surfaces[4] = fLowerEndcap;
825  surfaces[5] = fUpperEndcap;
826 
827  G4int i;
828  G4ThreeVector xx;
829  G4ThreeVector bestxx;
830  for (i=0; i< 6; i++)
831  {
832  G4double tmpdistance = surfaces[i]->DistanceTo(p, xx);
833  if (tmpdistance < distance)
834  {
835  distance = tmpdistance;
836  bestxx = xx;
837  }
838  }
839  *tmpdist = distance;
840  return fLastDistanceToIn.value;
841  }
842 
843  default :
844  {
845  G4Exception("G4VTwistedFaceted::DistanceToIn(p)", "GeomSolids0003",
846  FatalException, "Unknown point location!");
847  }
848  } // switch end
849 
850  return 0;
851 }
852 
853 
854 //=====================================================================
855 //* DistanceToOut (p, v) ----------------------------------------------
856 
857 G4double
859  const G4ThreeVector& v,
860  const G4bool calcNorm,
861  G4bool *validNorm,
862  G4ThreeVector *norm ) const
863 {
864  // DistanceToOut (p, v):
865  // Calculate distance to surface of shape from `inside'
866  // along with the v, allowing for tolerance.
867  // The function returns kInfinity if no intersection or
868  // just grazing within tolerance.
869 
870  //
871  // checking last value
872  //
873 
874  G4ThreeVector *tmpp;
875  G4ThreeVector *tmpv;
876  G4double *tmpdist;
878  {
880  }
881  else
882  {
883  tmpp = const_cast<G4ThreeVector*>(&(fLastDistanceToOutWithV.p));
884  tmpv = const_cast<G4ThreeVector*>(&(fLastDistanceToOutWithV.vec));
885  tmpdist = const_cast<G4double*>(&(fLastDistanceToOutWithV.value));
886  tmpp->set(p.x(), p.y(), p.z());
887  tmpv->set(v.x(), v.y(), v.z());
888  }
889 
890  //
891  // Calculate DistanceToOut(p,v)
892  //
893 
894  EInside currentside = Inside(p);
895 
896  if (currentside == kOutside)
897  {
898  }
899  else if (currentside == kSurface)
900  {
901  // particle is just on a boundary.
902  // if the particle is exiting from the volume, return 0
903  //
905  G4VTwistSurface *blockedsurface = fLastNormal.surface[0];
906  if (normal*v > 0)
907  {
908  if (calcNorm)
909  {
910  *norm = (blockedsurface->GetNormal(p, true));
911  *validNorm = blockedsurface->IsValidNorm();
912  }
913  *tmpdist = 0.;
914  // timer.Stop();
916  }
917  }
918 
919  // now, we can take smallest positive distance.
920 
921  // Initialize
922  G4double distance = kInfinity;
923 
924  // find intersections and choose nearest one.
925  G4VTwistSurface *surfaces[6];
926 
927  surfaces[0] = fSide0;
928  surfaces[1] = fSide90 ;
929  surfaces[2] = fSide180 ;
930  surfaces[3] = fSide270 ;
931  surfaces[4] = fLowerEndcap;
932  surfaces[5] = fUpperEndcap;
933 
934  G4int i;
935  G4int besti = -1;
936  G4ThreeVector xx;
937  G4ThreeVector bestxx;
938  for (i=0; i< 6 ; i++) {
939  G4double tmpdistance = surfaces[i]->DistanceToOut(p, v, xx);
940  if (tmpdistance < distance)
941  {
942  distance = tmpdistance;
943  bestxx = xx;
944  besti = i;
945  }
946  }
947 
948  if (calcNorm)
949  {
950  if (besti != -1)
951  {
952  *norm = (surfaces[besti]->GetNormal(p, true));
953  *validNorm = surfaces[besti]->IsValidNorm();
954  }
955  }
956 
957  *tmpdist = distance;
958  // timer.Stop();
960 }
961 
962 
963 //=====================================================================
964 //* DistanceToOut (p) -------------------------------------------------
965 
967 {
968  // DistanceToOut(p):
969  // Calculate distance to surface of shape from `inside',
970  // allowing for tolerance
971 
972  //
973  // checking last value
974  //
975 
976  G4ThreeVector *tmpp;
977  G4double *tmpdist;
978 
979  if (fLastDistanceToOut.p == p)
980  {
981  return fLastDistanceToOut.value;
982  }
983  else
984  {
985  tmpp = const_cast<G4ThreeVector*>(&(fLastDistanceToOut.p));
986  tmpdist = const_cast<G4double*>(&(fLastDistanceToOut.value));
987  tmpp->set(p.x(), p.y(), p.z());
988  }
989 
990  //
991  // Calculate DistanceToOut(p)
992  //
993 
994  EInside currentside = Inside(p);
995  G4double retval = kInfinity;
996 
997  switch (currentside)
998  {
999  case (kOutside) :
1000  {
1001 #ifdef G4SPECSDEBUG
1002  G4int oldprc = G4cout.precision(16) ;
1003  G4cout << G4endl ;
1004  DumpInfo();
1005  G4cout << "Position:" << G4endl << G4endl ;
1006  G4cout << "p.x() = " << p.x()/mm << " mm" << G4endl ;
1007  G4cout << "p.y() = " << p.y()/mm << " mm" << G4endl ;
1008  G4cout << "p.z() = " << p.z()/mm << " mm" << G4endl << G4endl ;
1009  G4cout.precision(oldprc) ;
1010  G4Exception("G4VTwistedFaceted::DistanceToOut(p)", "GeomSolids1002",
1011  JustWarning, "Point p is outside !?" );
1012 #endif
1013  break;
1014  }
1015  case (kSurface) :
1016  {
1017  *tmpdist = 0.;
1018  retval = fLastDistanceToOut.value;
1019  break;
1020  }
1021 
1022  case (kInside) :
1023  {
1024  // Initialize
1025  //
1026  G4double distance = kInfinity;
1027 
1028  // find intersections and choose nearest one
1029  //
1030  G4VTwistSurface *surfaces[6];
1031 
1032  surfaces[0] = fSide0;
1033  surfaces[1] = fSide90 ;
1034  surfaces[2] = fSide180 ;
1035  surfaces[3] = fSide270 ;
1036  surfaces[4] = fLowerEndcap;
1037  surfaces[5] = fUpperEndcap;
1038 
1039  G4int i;
1040  G4ThreeVector xx;
1041  G4ThreeVector bestxx;
1042  for (i=0; i< 6; i++)
1043  {
1044  G4double tmpdistance = surfaces[i]->DistanceTo(p, xx);
1045  if (tmpdistance < distance)
1046  {
1047  distance = tmpdistance;
1048  bestxx = xx;
1049  }
1050  }
1051  *tmpdist = distance;
1052 
1053  retval = fLastDistanceToOut.value;
1054  break;
1055  }
1056 
1057  default :
1058  {
1059  G4Exception("G4VTwistedFaceted::DistanceToOut(p)", "GeomSolids0003",
1060  FatalException, "Unknown point location!");
1061  break;
1062  }
1063  } // switch end
1064 
1065  return retval;
1066 }
1067 
1068 
1069 //=====================================================================
1070 //* StreamInfo --------------------------------------------------------
1071 
1072 std::ostream& G4VTwistedFaceted::StreamInfo(std::ostream& os) const
1073 {
1074  //
1075  // Stream object contents to an output stream
1076  //
1077  G4int oldprc = os.precision(16);
1078  os << "-----------------------------------------------------------\n"
1079  << " *** Dump for solid - " << GetName() << " ***\n"
1080  << " ===================================================\n"
1081  << " Solid type: G4VTwistedFaceted\n"
1082  << " Parameters: \n"
1083  << " polar angle theta = " << fTheta/degree << " deg" << G4endl
1084  << " azimuthal angle phi = " << fPhi/degree << " deg" << G4endl
1085  << " tilt angle alpha = " << fAlph/degree << " deg" << G4endl
1086  << " TWIST angle = " << fPhiTwist/degree << " deg" << G4endl
1087  << " Half length along y (lower endcap) = " << fDy1/cm << " cm"
1088  << G4endl
1089  << " Half length along x (lower endcap, bottom) = " << fDx1/cm << " cm"
1090  << G4endl
1091  << " Half length along x (lower endcap, top) = " << fDx2/cm << " cm"
1092  << G4endl
1093  << " Half length along y (upper endcap) = " << fDy2/cm << " cm"
1094  << G4endl
1095  << " Half length along x (upper endcap, bottom) = " << fDx3/cm << " cm"
1096  << G4endl
1097  << " Half length along x (upper endcap, top) = " << fDx4/cm << " cm"
1098  << G4endl
1099  << "-----------------------------------------------------------\n";
1100  os.precision(oldprc);
1101 
1102  return os;
1103 }
1104 
1105 
1106 //=====================================================================
1107 //* DiscribeYourselfTo ------------------------------------------------
1108 
1110 {
1111  scene.AddSolid (*this);
1112 }
1113 
1114 //=====================================================================
1115 //* GetExtent ---------------------------------------------------------
1116 
1118 {
1119  G4double maxRad = std::sqrt( fDx*fDx + fDy*fDy);
1120 
1121  return G4VisExtent(-maxRad, maxRad ,
1122  -maxRad, maxRad ,
1123  -fDz, fDz );
1124 }
1125 
1126 
1127 //=====================================================================
1128 //* CreateSurfaces ----------------------------------------------------
1129 
1131 {
1132 
1133  // create 6 surfaces of TwistedTub.
1134 
1135  if ( fDx1 == fDx2 && fDx3 == fDx4 ) // special case : Box
1136  {
1137  fSide0 = new G4TwistBoxSide("0deg", fPhiTwist, fDz, fTheta, fPhi,
1138  fDy1, fDx1, fDx1, fDy2, fDx3, fDx3, fAlph, 0.*deg);
1139  fSide180 = new G4TwistBoxSide("180deg", fPhiTwist, fDz, fTheta, fPhi+pi,
1140  fDy1, fDx1, fDx1, fDy2, fDx3, fDx3, fAlph, 180.*deg);
1141  }
1142  else // default general case
1143  {
1145  fPhi, fDy1, fDx1, fDx2, fDy2, fDx3, fDx4, fAlph, 0.*deg);
1146  fSide180 = new G4TwistTrapAlphaSide("180deg", fPhiTwist, fDz, fTheta,
1147  fPhi+pi, fDy1, fDx2, fDx1, fDy2, fDx4, fDx3, fAlph, 180.*deg);
1148  }
1149 
1150  // create parallel sides
1151  //
1153  fPhi, fDy1, fDx1, fDx2, fDy2, fDx3, fDx4, fAlph, 0.*deg);
1155  fPhi+pi, fDy1, fDx2, fDx1, fDy2, fDx4, fDx3, fAlph, 180.*deg);
1156 
1157  // create endcaps
1158  //
1160  fDz, fAlph, fPhi, fTheta, 1 );
1162  fDz, fAlph, fPhi, fTheta, -1 );
1163 
1164  // Set neighbour surfaces
1165 
1172 
1173 }
1174 
1175 
1176 //=====================================================================
1177 //* GetEntityType -----------------------------------------------------
1178 
1180 {
1181  return G4String("G4VTwistedFaceted");
1182 }
1183 
1184 
1185 //=====================================================================
1186 //* GetPolyhedron -----------------------------------------------------
1187 
1189 {
1190  if (!fpPolyhedron ||
1192  fpPolyhedron->GetNumberOfRotationSteps())
1193  {
1194  delete fpPolyhedron;
1196  }
1197 
1198  return fpPolyhedron;
1199 }
1200 
1201 
1202 //=====================================================================
1203 //* GetPointInSolid ---------------------------------------------------
1204 
1206 {
1207 
1208 
1209  // this routine is only used for a test
1210  // can be deleted ...
1211 
1212  if ( z == fDz ) z -= 0.1*fDz ;
1213  if ( z == -fDz ) z += 0.1*fDz ;
1214 
1215  G4double phi = z/(2*fDz)*fPhiTwist ;
1216 
1217  return G4ThreeVector(fdeltaX * phi/fPhiTwist, fdeltaY * phi/fPhiTwist, z ) ;
1218 }
1219 
1220 
1221 //=====================================================================
1222 //* GetPointOnSurface -------------------------------------------------
1223 
1225 {
1226 
1228  G4double u , umin, umax ; // variable for twisted surfaces
1229  G4double y ; // variable for flat surface (top and bottom)
1230 
1231  // Compute the areas. Attention: Only correct for trapezoids
1232  // where the twisting is done along the z-axis. In the general case
1233  // the computed surface area is more difficult. However this simplification
1234  // does not affect the tracking through the solid.
1235 
1242 
1243 #ifdef G4TWISTDEBUG
1244  G4cout << "Surface 0 deg = " << a1 << G4endl ;
1245  G4cout << "Surface 90 deg = " << a2 << G4endl ;
1246  G4cout << "Surface 180 deg = " << a3 << G4endl ;
1247  G4cout << "Surface 270 deg = " << a4 << G4endl ;
1248  G4cout << "Surface Lower = " << a5 << G4endl ;
1249  G4cout << "Surface Upper = " << a6 << G4endl ;
1250 #endif
1251 
1252  G4double chose = G4RandFlat::shoot(0.,a1 + a2 + a3 + a4 + a5 + a6) ;
1253 
1254  if(chose < a1)
1255  {
1256 
1257  umin = fSide0->GetBoundaryMin(phi) ;
1258  umax = fSide0->GetBoundaryMax(phi) ;
1259  u = G4RandFlat::shoot(umin,umax) ;
1260 
1261  return fSide0->SurfacePoint(phi, u, true) ; // point on 0deg surface
1262  }
1263 
1264  else if( (chose >= a1) && (chose < a1 + a2 ) )
1265  {
1266 
1267  umin = fSide90->GetBoundaryMin(phi) ;
1268  umax = fSide90->GetBoundaryMax(phi) ;
1269 
1270  u = G4RandFlat::shoot(umin,umax) ;
1271 
1272  return fSide90->SurfacePoint(phi, u, true); // point on 90deg surface
1273  }
1274 
1275  else if( (chose >= a1 + a2 ) && (chose < a1 + a2 + a3 ) )
1276  {
1277 
1278  umin = fSide180->GetBoundaryMin(phi) ;
1279  umax = fSide180->GetBoundaryMax(phi) ;
1280  u = G4RandFlat::shoot(umin,umax) ;
1281 
1282  return fSide180->SurfacePoint(phi, u, true); // point on 180 deg surface
1283  }
1284 
1285  else if( (chose >= a1 + a2 + a3 ) && (chose < a1 + a2 + a3 + a4 ) )
1286  {
1287 
1288  umin = fSide270->GetBoundaryMin(phi) ;
1289  umax = fSide270->GetBoundaryMax(phi) ;
1290  u = G4RandFlat::shoot(umin,umax) ;
1291 
1292  return fSide270->SurfacePoint(phi, u, true); // point on 270 deg surface
1293  }
1294 
1295  else if( (chose >= a1 + a2 + a3 + a4 ) && (chose < a1 + a2 + a3 + a4 + a5 ) )
1296  {
1297 
1298  y = G4RandFlat::shoot(-fDy1,fDy1) ;
1299  umin = fLowerEndcap->GetBoundaryMin(y) ;
1300  umax = fLowerEndcap->GetBoundaryMax(y) ;
1301  u = G4RandFlat::shoot(umin,umax) ;
1302 
1303  return fLowerEndcap->SurfacePoint(u,y,true); // point on lower endcap
1304  }
1305  else {
1306 
1307  y = G4RandFlat::shoot(-fDy2,fDy2) ;
1308  umin = fUpperEndcap->GetBoundaryMin(y) ;
1309  umax = fUpperEndcap->GetBoundaryMax(y) ;
1310  u = G4RandFlat::shoot(umin,umax) ;
1311 
1312  return fUpperEndcap->SurfacePoint(u,y,true) ; // point on upper endcap
1313 
1314  }
1315 }
1316 
1317 
1318 //=====================================================================
1319 //* CreatePolyhedron --------------------------------------------------
1320 
1322 {
1323  // number of meshes
1324  const G4int k =
1325  G4int(G4Polyhedron::GetNumberOfRotationSteps() * fPhiTwist / twopi) + 2;
1326  const G4int n = k;
1327 
1328  const G4int nnodes = 4*(k-1)*(n-2) + 2*k*k ;
1329  const G4int nfaces = 4*(k-1)*(n-1) + 2*(k-1)*(k-1) ;
1330 
1331  G4Polyhedron *ph=new G4Polyhedron;
1332  typedef G4double G4double3[3];
1333  typedef G4int G4int4[4];
1334  G4double3* xyz = new G4double3[nnodes]; // number of nodes
1335  G4int4* faces = new G4int4[nfaces] ; // number of faces
1336 
1337  fLowerEndcap->GetFacets(k,k,xyz,faces,0) ;
1338  fUpperEndcap->GetFacets(k,k,xyz,faces,1) ;
1339  fSide270->GetFacets(k,n,xyz,faces,2) ;
1340  fSide0->GetFacets(k,n,xyz,faces,3) ;
1341  fSide90->GetFacets(k,n,xyz,faces,4) ;
1342  fSide180->GetFacets(k,n,xyz,faces,5) ;
1343 
1344  ph->createPolyhedron(nnodes,nfaces,xyz,faces);
1345 
1346  return ph;
1347 }
static const double cm
Definition: G4SIunits.hh:106
G4String GetName() const
void ClipCrossSection(G4ThreeVectorList *pVertices, const G4int pSectionIndex, const G4VoxelLimits &pVoxelLimit, const EAxis pAxis, G4double &pMin, G4double &pMax) const
Definition: G4VSolid.cc:347
ThreeVector shoot(const G4int Ap, const G4int Af)
virtual void ComputeDimensions(G4VPVParameterisation *, const G4int, const G4VPhysicalVolume *)
G4ThreeVectorList * CreateRotatedVertices(const G4AffineTransform &pTransform) const
G4VTwistSurface * fSide90
static const G4double kInfinity
Definition: geomdefs.hh:42
G4double GetMinYExtent() const
G4VTwistedFaceted(const G4String &pname, G4double PhiTwist, G4double pDz, G4double pTheta, G4double pPhi, G4double pDy1, G4double pDx1, G4double pDx2, G4double pDy2, G4double pDx3, G4double pDx4, G4double pAlph)
G4VTwistSurface * fUpperEndcap
CLHEP::Hep3Vector G4ThreeVector
LastValueWithDoubleVector fLastDistanceToOutWithV
virtual G4ThreeVector GetNormal(const G4ThreeVector &xx, G4bool isGlobal)=0
G4AffineTransform Inverse() const
G4double z
Definition: TRTMaterials.hh:39
G4bool IsYLimited() const
virtual G4GeometryType GetEntityType() const
static const G4double a1
G4ThreeVector GetPointOnSurface() const
const G4double pi
G4ThreeVector GetPointInSolid(G4double z) const
G4bool IsRotated() const
virtual G4Polyhedron * CreatePolyhedron() const
virtual G4double DistanceToIn(const G4ThreeVector &p, const G4ThreeVector &v) const
G4ThreeVector NetTranslation() const
static const G4double a4
G4bool IsXLimited() const
G4double a
Definition: TRTMaterials.hh:39
G4VTwistedFaceted & operator=(const G4VTwistedFaceted &rhs)
virtual void AddSolid(const G4Box &)=0
int G4int
Definition: G4Types.hh:78
virtual G4ThreeVector SurfaceNormal(const G4ThreeVector &p) const
G4bool IsValidNorm() const
G4VTwistSurface * fSide180
void DumpInfo() const
virtual G4double DistanceToIn(const G4ThreeVector &gp, const G4ThreeVector &gv, G4ThreeVector &gxxbest)
G4double Xcoef(G4double u, G4double phi, G4double ftg) const
static double normal(HepRandomEngine *eptr)
Definition: RandPoisson.cc:77
G4double GetMaxXExtent() const
virtual G4double GetSurfaceArea()=0
G4VTwistSurface * fSide270
G4double GetMinZExtent() const
G4GLOB_DLL std::ostream G4cout
G4bool IsLimited() const
virtual G4bool CalculateExtent(const EAxis pAxis, const G4VoxelLimits &pVoxelLimit, const G4AffineTransform &pTransform, G4double &pMin, G4double &pMax) const
void SetNeighbours(G4VTwistSurface *axis0min, G4VTwistSurface *axis1min, G4VTwistSurface *axis0max, G4VTwistSurface *axis1max)
virtual G4double DistanceTo(const G4ThreeVector &gp, G4ThreeVector &gxx)
virtual G4double DistanceToOut(const G4ThreeVector &gp, const G4ThreeVector &gv, G4ThreeVector &gxxbest)
static const double deg
Definition: G4SIunits.hh:133
virtual G4ThreeVector SurfacePoint(G4double, G4double, G4bool isGlobal=false)=0
bool G4bool
Definition: G4Types.hh:79
G4double GetValueB(G4double phi) const
G4VTwistSurface * fLowerEndcap
std::vector< G4ThreeVector > G4ThreeVectorList
Definition: G4VSolid.hh:79
const G4int n
LastValueWithDoubleVector fLastDistanceToInWithV
virtual G4double GetBoundaryMax(G4double)=0
static const G4double a3
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *comments)
Definition: G4Exception.cc:41
virtual void GetFacets(G4int m, G4int n, G4double xyz[][3], G4int faces[][4], G4int iside)=0
virtual G4double DistanceToOut(const G4ThreeVector &p, const G4ThreeVector &v, const G4bool calcnorm=false, G4bool *validnorm=0, G4ThreeVector *n=0) const
virtual G4double GetBoundaryMin(G4double)=0
G4double GetMinXExtent() const
G4ThreeVector TransformPoint(const G4ThreeVector &vec) const
G4double GetMaxZExtent() const
virtual G4Polyhedron * GetPolyhedron() const
EInside
Definition: geomdefs.hh:58
virtual G4VisExtent GetExtent() const
virtual EInside Inside(const G4ThreeVector &p) const
EAxis
Definition: geomdefs.hh:54
virtual void DescribeYourselfTo(G4VGraphicsScene &scene) const
static const double degree
Definition: G4SIunits.hh:125
#define G4endl
Definition: G4ios.hh:61
G4double GetMaxYExtent() const
G4VSolid & operator=(const G4VSolid &rhs)
Definition: G4VSolid.cc:110
G4double kCarTolerance
Definition: G4VSolid.hh:305
G4int GetNumberOfRotationStepsAtTimeOfCreation() const
G4VTwistSurface * fSide0
static const G4double a5
double G4double
Definition: G4Types.hh:76
virtual std::ostream & StreamInfo(std::ostream &os) const
G4double GetMaxExtent(const EAxis pAxis) const
G4bool IsZLimited() const
static const double mm
Definition: G4SIunits.hh:102
G4Polyhedron * fpPolyhedron
G4double GetAngularTolerance() const
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
static const G4double a2
static G4GeometryTolerance * GetInstance()