Geant4  10.01.p02
G4TwistedTubs.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: G4TwistedTubs.cc 83572 2014-09-01 15:23:27Z gcosmo $
28 //
29 //
30 // --------------------------------------------------------------------
31 // GEANT 4 class source file
32 //
33 //
34 // G4TwistTubsSide.cc
35 //
36 // Author:
37 // 01-Aug-2002 - Kotoyo Hoshina (hoshina@hepburn.s.chiba-u.ac.jp)
38 //
39 // History:
40 // 13-Nov-2003 - O.Link (Oliver.Link@cern.ch), Integration in Geant4
41 // from original version in Jupiter-2.5.02 application.
42 // --------------------------------------------------------------------
43 
44 #include "G4TwistedTubs.hh"
45 
46 #include "G4PhysicalConstants.hh"
47 #include "G4SystemOfUnits.hh"
48 #include "G4GeometryTolerance.hh"
49 #include "G4VoxelLimits.hh"
50 #include "G4AffineTransform.hh"
51 #include "G4SolidExtentList.hh"
52 #include "G4ClippablePolygon.hh"
53 #include "G4VPVParameterisation.hh"
54 #include "meshdefs.hh"
55 
56 #include "G4VGraphicsScene.hh"
57 #include "G4Polyhedron.hh"
58 #include "G4VisExtent.hh"
59 
60 #include "Randomize.hh"
61 
62 #include "G4AutoLock.hh"
63 
64 namespace
65 {
66  G4Mutex polyhedronMutex = G4MUTEX_INITIALIZER;
67 }
68 
69 //=====================================================================
70 //* constructors ------------------------------------------------------
71 
73  G4double twistedangle,
74  G4double endinnerrad,
75  G4double endouterrad,
76  G4double halfzlen,
77  G4double dphi)
78  : G4VSolid(pname), fDPhi(dphi),
79  fLowerEndcap(0), fUpperEndcap(0), fLatterTwisted(0),
80  fFormerTwisted(0), fInnerHype(0), fOuterHype(0),
81  fCubicVolume(0.), fSurfaceArea(0.),
82  fRebuildPolyhedron(false), fpPolyhedron(0)
83 {
84  if (endinnerrad < DBL_MIN)
85  {
86  G4Exception("G4TwistedTubs::G4TwistedTubs()", "GeomSolids0002",
87  FatalErrorInArgument, "Invalid end-inner-radius!");
88  }
89 
90  G4double sinhalftwist = std::sin(0.5 * twistedangle);
91 
92  G4double endinnerradX = endinnerrad * sinhalftwist;
93  G4double innerrad = std::sqrt( endinnerrad * endinnerrad
94  - endinnerradX * endinnerradX );
95 
96  G4double endouterradX = endouterrad * sinhalftwist;
97  G4double outerrad = std::sqrt( endouterrad * endouterrad
98  - endouterradX * endouterradX );
99 
100  // temporary treatment!!
101  SetFields(twistedangle, innerrad, outerrad, -halfzlen, halfzlen);
102  CreateSurfaces();
103 }
104 
106  G4double twistedangle,
107  G4double endinnerrad,
108  G4double endouterrad,
109  G4double halfzlen,
110  G4int nseg,
111  G4double totphi)
112  : G4VSolid(pname),
113  fLowerEndcap(0), fUpperEndcap(0), fLatterTwisted(0),
114  fFormerTwisted(0), fInnerHype(0), fOuterHype(0),
115  fCubicVolume(0.), fSurfaceArea(0.),
116  fRebuildPolyhedron(false), fpPolyhedron(0)
117 {
118 
119  if (!nseg)
120  {
121  std::ostringstream message;
122  message << "Invalid number of segments." << G4endl
123  << " nseg = " << nseg;
124  G4Exception("G4TwistedTubs::G4TwistedTubs()", "GeomSolids0002",
125  FatalErrorInArgument, message);
126  }
127  if (totphi == DBL_MIN || endinnerrad < DBL_MIN)
128  {
129  G4Exception("G4TwistedTubs::G4TwistedTubs()", "GeomSolids0002",
130  FatalErrorInArgument, "Invalid total-phi or end-inner-radius!");
131  }
132 
133  G4double sinhalftwist = std::sin(0.5 * twistedangle);
134 
135  G4double endinnerradX = endinnerrad * sinhalftwist;
136  G4double innerrad = std::sqrt( endinnerrad * endinnerrad
137  - endinnerradX * endinnerradX );
138 
139  G4double endouterradX = endouterrad * sinhalftwist;
140  G4double outerrad = std::sqrt( endouterrad * endouterrad
141  - endouterradX * endouterradX );
142 
143  // temporary treatment!!
144  fDPhi = totphi / nseg;
145  SetFields(twistedangle, innerrad, outerrad, -halfzlen, halfzlen);
146  CreateSurfaces();
147 }
148 
150  G4double twistedangle,
151  G4double innerrad,
152  G4double outerrad,
153  G4double negativeEndz,
154  G4double positiveEndz,
155  G4double dphi)
156  : G4VSolid(pname), fDPhi(dphi),
157  fLowerEndcap(0), fUpperEndcap(0), fLatterTwisted(0),
158  fFormerTwisted(0), fInnerHype(0), fOuterHype(0),
159  fCubicVolume(0.), fSurfaceArea(0.),
160  fRebuildPolyhedron(false), fpPolyhedron(0)
161 {
162  if (innerrad < DBL_MIN)
163  {
164  G4Exception("G4TwistedTubs::G4TwistedTubs()", "GeomSolids0002",
165  FatalErrorInArgument, "Invalid end-inner-radius!");
166  }
167 
168  SetFields(twistedangle, innerrad, outerrad, negativeEndz, positiveEndz);
169  CreateSurfaces();
170 }
171 
173  G4double twistedangle,
174  G4double innerrad,
175  G4double outerrad,
176  G4double negativeEndz,
177  G4double positiveEndz,
178  G4int nseg,
179  G4double totphi)
180  : G4VSolid(pname),
181  fLowerEndcap(0), fUpperEndcap(0), fLatterTwisted(0),
182  fFormerTwisted(0), fInnerHype(0), fOuterHype(0),
183  fCubicVolume(0.), fSurfaceArea(0.),
184  fRebuildPolyhedron(false), fpPolyhedron(0)
185 {
186  if (!nseg)
187  {
188  std::ostringstream message;
189  message << "Invalid number of segments." << G4endl
190  << " nseg = " << nseg;
191  G4Exception("G4TwistedTubs::G4TwistedTubs()", "GeomSolids0002",
192  FatalErrorInArgument, message);
193  }
194  if (totphi == DBL_MIN || innerrad < DBL_MIN)
195  {
196  G4Exception("G4TwistedTubs::G4TwistedTubs()", "GeomSolids0002",
197  FatalErrorInArgument, "Invalid total-phi or end-inner-radius!");
198  }
199 
200  fDPhi = totphi / nseg;
201  SetFields(twistedangle, innerrad, outerrad, negativeEndz, positiveEndz);
202  CreateSurfaces();
203 }
204 
205 //=====================================================================
206 //* Fake default constructor ------------------------------------------
207 
209  : G4VSolid(a), fPhiTwist(0.), fInnerRadius(0.), fOuterRadius(0.), fDPhi(0.),
210  fZHalfLength(0.), fInnerStereo(0.), fOuterStereo(0.), fTanInnerStereo(0.),
211  fTanOuterStereo(0.), fKappa(0.), fInnerRadius2(0.), fOuterRadius2(0.),
212  fTanInnerStereo2(0.), fTanOuterStereo2(0.), fLowerEndcap(0), fUpperEndcap(0),
213  fLatterTwisted(0), fFormerTwisted(0), fInnerHype(0), fOuterHype(0),
214  fCubicVolume(0.), fSurfaceArea(0.),
215  fRebuildPolyhedron(false), fpPolyhedron(0)
216 {
217 }
218 
219 //=====================================================================
220 //* destructor --------------------------------------------------------
221 
223 {
224  if (fLowerEndcap) { delete fLowerEndcap; }
225  if (fUpperEndcap) { delete fUpperEndcap; }
226  if (fLatterTwisted) { delete fLatterTwisted; }
227  if (fFormerTwisted) { delete fFormerTwisted; }
228  if (fInnerHype) { delete fInnerHype; }
229  if (fOuterHype) { delete fOuterHype; }
230  if (fpPolyhedron) { delete fpPolyhedron; fpPolyhedron = 0; }
231 }
232 
233 //=====================================================================
234 //* Copy constructor --------------------------------------------------
235 
237  : G4VSolid(rhs), fPhiTwist(rhs.fPhiTwist),
238  fInnerRadius(rhs.fInnerRadius), fOuterRadius(rhs.fOuterRadius),
239  fDPhi(rhs.fDPhi), fZHalfLength(rhs.fZHalfLength),
240  fInnerStereo(rhs.fInnerStereo), fOuterStereo(rhs.fOuterStereo),
241  fTanInnerStereo(rhs.fTanInnerStereo), fTanOuterStereo(rhs.fTanOuterStereo),
242  fKappa(rhs.fKappa), fInnerRadius2(rhs.fInnerRadius2),
243  fOuterRadius2(rhs.fOuterRadius2), fTanInnerStereo2(rhs.fTanInnerStereo2),
244  fTanOuterStereo2(rhs.fTanOuterStereo2),
245  fLowerEndcap(0), fUpperEndcap(0), fLatterTwisted(0), fFormerTwisted(0),
246  fInnerHype(0), fOuterHype(0),
247  fCubicVolume(rhs.fCubicVolume), fSurfaceArea(rhs.fSurfaceArea),
248  fRebuildPolyhedron(false), fpPolyhedron(0),
249  fLastInside(rhs.fLastInside), fLastNormal(rhs.fLastNormal),
250  fLastDistanceToIn(rhs.fLastDistanceToIn),
251  fLastDistanceToOut(rhs.fLastDistanceToOut),
252  fLastDistanceToInWithV(rhs.fLastDistanceToInWithV),
253  fLastDistanceToOutWithV(rhs.fLastDistanceToOutWithV)
254 {
255  for (size_t i=0; i<2; ++i)
256  {
257  fEndZ[i] = rhs.fEndZ[i];
258  fEndInnerRadius[i] = rhs.fEndInnerRadius[i];
259  fEndOuterRadius[i] = rhs.fEndOuterRadius[i];
260  fEndPhi[i] = rhs.fEndPhi[i];
261  fEndZ2[i] = rhs.fEndZ2[i];
262  }
263  CreateSurfaces();
264 }
265 
266 
267 //=====================================================================
268 //* Assignment operator -----------------------------------------------
269 
271 {
272  // Check assignment to self
273  //
274  if (this == &rhs) { return *this; }
275 
276  // Copy base class data
277  //
278  G4VSolid::operator=(rhs);
279 
280  // Copy data
281  //
282  fPhiTwist= rhs.fPhiTwist;
298 
299  for (size_t i=0; i<2; ++i)
300  {
301  fEndZ[i] = rhs.fEndZ[i];
302  fEndInnerRadius[i] = rhs.fEndInnerRadius[i];
303  fEndOuterRadius[i] = rhs.fEndOuterRadius[i];
304  fEndPhi[i] = rhs.fEndPhi[i];
305  fEndZ2[i] = rhs.fEndZ2[i];
306  }
307 
308  CreateSurfaces();
309  fRebuildPolyhedron = false;
310  delete fpPolyhedron; fpPolyhedron = 0;
311 
312  return *this;
313 }
314 
315 //=====================================================================
316 //* ComputeDimensions -------------------------------------------------
317 
319  const G4int /* n */ ,
320  const G4VPhysicalVolume* /* pRep */ )
321 {
322  G4Exception("G4TwistedTubs::ComputeDimensions()",
323  "GeomSolids0001", FatalException,
324  "G4TwistedTubs does not support Parameterisation.");
325 }
326 
327 
328 //=====================================================================
329 //* CalculateExtent ---------------------------------------------------
330 
332  const G4VoxelLimits &voxelLimit,
333  const G4AffineTransform &transform,
334  G4double &min,
335  G4double &max ) const
336 {
337 
338  G4SolidExtentList extentList( axis, voxelLimit );
339  G4double maxEndOuterRad = (fEndOuterRadius[0] > fEndOuterRadius[1] ?
341  G4double maxEndInnerRad = (fEndInnerRadius[0] > fEndInnerRadius[1] ?
343  G4double maxphi = (std::fabs(fEndPhi[0]) > std::fabs(fEndPhi[1]) ?
344  std::fabs(fEndPhi[0]) : std::fabs(fEndPhi[1]));
345 
346  //
347  // Choose phi size of our segment(s) based on constants as
348  // defined in meshdefs.hh
349  //
350  // G4int numPhi = kMaxMeshSections;
351  G4double sigPhi = 2*maxphi + fDPhi;
352  G4double rFudge = 1.0/std::cos(0.5*sigPhi);
353  G4double fudgeEndOuterRad = rFudge * maxEndOuterRad;
354 
355  //
356  // We work around in phi building polygons along the way.
357  // As a reasonable compromise between accuracy and
358  // complexity (=cpu time), the following facets are chosen:
359  //
360  // 1. If fOuterRadius/maxEndOuterRad > 0.95, approximate
361  // the outer surface as a cylinder, and use one
362  // rectangular polygon (0-1) to build its mesh.
363  //
364  // Otherwise, use two trapazoidal polygons that
365  // meet at z = 0 (0-4-1)
366  //
367  // 2. If there is no inner surface, then use one
368  // polygon for each entire endcap. (0) and (1)
369  //
370  // Otherwise, use a trapazoidal polygon for each
371  // phi segment of each endcap. (0-2) and (1-3)
372  //
373  // 3. For the inner surface, if fInnerRadius/maxEndInnerRad > 0.95,
374  // approximate the inner surface as a cylinder of
375  // radius fInnerRadius and use one rectangular polygon
376  // to build each phi segment of its mesh. (2-3)
377  //
378  // Otherwise, use one rectangular polygon centered
379  // at z = 0 (5-6) and two connecting trapazoidal polygons
380  // for each phi segment (2-5) and (3-6).
381  //
382 
383  G4bool splitOuter = (fOuterRadius/maxEndOuterRad < 0.95);
384  G4bool splitInner = (fInnerRadius/maxEndInnerRad < 0.95);
385 
386  //
387  // Vertex assignments (v and w arrays)
388  // [0] and [1] are mandatory
389  // the rest are optional
390  //
391  // + -
392  // [0]------[4]------[1] <--- outer radius
393  // | |
394  // | |
395  // [2]---[5]---[6]---[3] <--- inner radius
396  //
397 
398  G4ClippablePolygon endPoly1, endPoly2;
399 
400  G4double phimax = maxphi + 0.5*fDPhi;
401  if ( phimax > pi/2) { phimax = pi-phimax; }
402  G4double phimin = - phimax;
403 
404  G4ThreeVector v0, v1, v2, v3, v4, v5, v6; // -ve phi verticies for polygon
405  G4ThreeVector w0, w1, w2, w3, w4, w5, w6; // +ve phi verticies for polygon
406 
407  //
408  // decide verticies of -ve phi boundary
409  //
410 
411  G4double cosPhi = std::cos(phimin);
412  G4double sinPhi = std::sin(phimin);
413 
414  // Outer hyperbolic surface
415 
416  v0 = transform.TransformPoint(
417  G4ThreeVector(fudgeEndOuterRad*cosPhi, fudgeEndOuterRad*sinPhi,
418  + fZHalfLength));
419  v1 = transform.TransformPoint(
420  G4ThreeVector(fudgeEndOuterRad*cosPhi, fudgeEndOuterRad*sinPhi,
421  - fZHalfLength));
422  if (splitOuter)
423  {
424  v4 = transform.TransformPoint(
425  G4ThreeVector(fudgeEndOuterRad*cosPhi, fudgeEndOuterRad*sinPhi, 0));
426  }
427 
428  // Inner hyperbolic surface
429 
430  G4double zInnerSplit = 0.;
431  if (splitInner)
432  {
433  v2 = transform.TransformPoint(
434  G4ThreeVector(maxEndInnerRad*cosPhi, maxEndInnerRad*sinPhi,
435  + fZHalfLength));
436  v3 = transform.TransformPoint(
437  G4ThreeVector(maxEndInnerRad*cosPhi, maxEndInnerRad*sinPhi,
438  - fZHalfLength));
439 
440  // Find intersection of tangential line of inner
441  // surface at z = fZHalfLength and line r=fInnerRadius.
443  G4double dz = maxEndInnerRad;
444  zInnerSplit = fZHalfLength + (fInnerRadius - maxEndInnerRad) * dz / dr;
445 
446  // Build associated vertices
447  v5 = transform.TransformPoint(
448  G4ThreeVector(fInnerRadius*cosPhi, fInnerRadius*sinPhi,
449  + zInnerSplit));
450  v6 = transform.TransformPoint(
451  G4ThreeVector(fInnerRadius*cosPhi, fInnerRadius*sinPhi,
452  - zInnerSplit));
453  }
454  else
455  {
456  v2 = transform.TransformPoint(
457  G4ThreeVector(fInnerRadius*cosPhi, fInnerRadius*sinPhi,
458  + fZHalfLength));
459  v3 = transform.TransformPoint(
460  G4ThreeVector(fInnerRadius*cosPhi, fInnerRadius*sinPhi,
461  - fZHalfLength));
462  }
463 
464  //
465  // decide vertices of +ve phi boundary
466  //
467 
468  cosPhi = std::cos(phimax);
469  sinPhi = std::sin(phimax);
470 
471  // Outer hyperbolic surface
472 
473  w0 = transform.TransformPoint(
474  G4ThreeVector(fudgeEndOuterRad*cosPhi, fudgeEndOuterRad*sinPhi,
475  + fZHalfLength));
476  w1 = transform.TransformPoint(
477  G4ThreeVector(fudgeEndOuterRad*cosPhi, fudgeEndOuterRad*sinPhi,
478  - fZHalfLength));
479  if (splitOuter)
480  {
481  G4double r = rFudge*fOuterRadius;
482 
483  w4 = transform.TransformPoint(G4ThreeVector( r*cosPhi, r*sinPhi, 0 ));
484 
485  AddPolyToExtent( v0, v4, w4, w0, voxelLimit, axis, extentList );
486  AddPolyToExtent( v4, v1, w1, w4, voxelLimit, axis, extentList );
487  }
488  else
489  {
490  AddPolyToExtent( v0, v1, w1, w0, voxelLimit, axis, extentList );
491  }
492 
493  // Inner hyperbolic surface
494 
495  if (splitInner)
496  {
497  w2 = transform.TransformPoint(
498  G4ThreeVector(maxEndInnerRad*cosPhi, maxEndInnerRad*sinPhi,
499  + fZHalfLength));
500  w3 = transform.TransformPoint(
501  G4ThreeVector(maxEndInnerRad*cosPhi, maxEndInnerRad*sinPhi,
502  - fZHalfLength));
503 
504  w5 = transform.TransformPoint(
505  G4ThreeVector(fInnerRadius*cosPhi, fInnerRadius*sinPhi,
506  + zInnerSplit));
507  w6 = transform.TransformPoint(
508  G4ThreeVector(fInnerRadius*cosPhi, fInnerRadius*sinPhi,
509  - zInnerSplit));
510 
511  AddPolyToExtent( v3, v6, w6, w3, voxelLimit, axis, extentList );
512  AddPolyToExtent( v6, v5, w5, w6, voxelLimit, axis, extentList );
513  AddPolyToExtent( v5, v2, w2, w5, voxelLimit, axis, extentList );
514 
515  }
516  else
517  {
518  w2 = transform.TransformPoint(
519  G4ThreeVector(fInnerRadius*cosPhi, fInnerRadius*sinPhi,
520  + fZHalfLength));
521  w3 = transform.TransformPoint(
522  G4ThreeVector(fInnerRadius*cosPhi, fInnerRadius*sinPhi,
523  - fZHalfLength));
524 
525  AddPolyToExtent( v3, v2, w2, w3, voxelLimit, axis, extentList );
526  }
527 
528  //
529  // Endplate segments
530  //
531  AddPolyToExtent( v1, v3, w3, w1, voxelLimit, axis, extentList );
532  AddPolyToExtent( v2, v0, w0, w2, voxelLimit, axis, extentList );
533 
534  //
535  // Return min/max value
536  //
537  return extentList.GetExtent( min, max );
538 }
539 
540 
541 //=====================================================================
542 //* AddPolyToExtent ---------------------------------------------------
543 
545  const G4ThreeVector &v1,
546  const G4ThreeVector &w1,
547  const G4ThreeVector &w0,
548  const G4VoxelLimits &voxelLimit,
549  const EAxis axis,
550  G4SolidExtentList &extentList )
551 {
552  // Utility function for CalculateExtent
553  //
554  G4ClippablePolygon phiPoly;
555 
556  phiPoly.AddVertexInOrder( v0 );
557  phiPoly.AddVertexInOrder( v1 );
558  phiPoly.AddVertexInOrder( w1 );
559  phiPoly.AddVertexInOrder( w0 );
560 
561  if (phiPoly.PartialClip( voxelLimit, axis ))
562  {
563  phiPoly.SetNormal( (v1-v0).cross(w0-v0).unit() );
564  extentList.AddSurface( phiPoly );
565  }
566 }
567 
568 
569 //=====================================================================
570 //* Inside ------------------------------------------------------------
571 
573 {
574 
575  const G4double halftol
577  // static G4int timerid = -1;
578  // G4Timer timer(timerid, "G4TwistedTubs", "Inside");
579  // timer.Start();
580 
581  G4ThreeVector *tmpp;
582  EInside *tmpinside;
583  if (fLastInside.p == p)
584  {
585  return fLastInside.inside;
586  }
587  else
588  {
589  tmpp = const_cast<G4ThreeVector*>(&(fLastInside.p));
590  tmpinside = const_cast<EInside*>(&(fLastInside.inside));
591  tmpp->set(p.x(), p.y(), p.z());
592  }
593 
594  EInside outerhypearea = ((G4TwistTubsHypeSide *)fOuterHype)->Inside(p);
595  G4double innerhyperho = ((G4TwistTubsHypeSide *)fInnerHype)->GetRhoAtPZ(p);
596  G4double distanceToOut = p.getRho() - innerhyperho; // +ve: inside
597 
598  if ((outerhypearea == kOutside) || (distanceToOut < -halftol))
599  {
600  *tmpinside = kOutside;
601  }
602  else if (outerhypearea == kSurface)
603  {
604  *tmpinside = kSurface;
605  }
606  else
607  {
608  if (distanceToOut <= halftol)
609  {
610  *tmpinside = kSurface;
611  }
612  else
613  {
614  *tmpinside = kInside;
615  }
616  }
617 
618  return fLastInside.inside;
619 }
620 
621 //=====================================================================
622 //* SurfaceNormal -----------------------------------------------------
623 
625 {
626  //
627  // return the normal unit vector to the Hyperbolical Surface at a point
628  // p on (or nearly on) the surface
629  //
630  // Which of the three or four surfaces are we closest to?
631  //
632 
633  if (fLastNormal.p == p)
634  {
635  return fLastNormal.vec;
636  }
637  G4ThreeVector *tmpp =
638  const_cast<G4ThreeVector*>(&(fLastNormal.p));
639  G4ThreeVector *tmpnormal =
640  const_cast<G4ThreeVector*>(&(fLastNormal.vec));
641  G4VTwistSurface **tmpsurface =
642  const_cast<G4VTwistSurface**>(fLastNormal.surface);
643  tmpp->set(p.x(), p.y(), p.z());
644 
645  G4double distance = kInfinity;
646 
647  G4VTwistSurface *surfaces[6];
648  surfaces[0] = fLatterTwisted;
649  surfaces[1] = fFormerTwisted;
650  surfaces[2] = fInnerHype;
651  surfaces[3] = fOuterHype;
652  surfaces[4] = fLowerEndcap;
653  surfaces[5] = fUpperEndcap;
654 
655  G4ThreeVector xx;
656  G4ThreeVector bestxx;
657  G4int i;
658  G4int besti = -1;
659  for (i=0; i< 6; i++)
660  {
661  G4double tmpdistance = surfaces[i]->DistanceTo(p, xx);
662  if (tmpdistance < distance)
663  {
664  distance = tmpdistance;
665  bestxx = xx;
666  besti = i;
667  }
668  }
669 
670  tmpsurface[0] = surfaces[besti];
671  *tmpnormal = tmpsurface[0]->GetNormal(bestxx, true);
672 
673  return fLastNormal.vec;
674 }
675 
676 //=====================================================================
677 //* DistanceToIn (p, v) -----------------------------------------------
678 
680  const G4ThreeVector& v ) const
681 {
682 
683  // DistanceToIn (p, v):
684  // Calculate distance to surface of shape from `outside'
685  // along with the v, allowing for tolerance.
686  // The function returns kInfinity if no intersection or
687  // just grazing within tolerance.
688 
689  //
690  // checking last value
691  //
692 
693  G4ThreeVector *tmpp;
694  G4ThreeVector *tmpv;
695  G4double *tmpdist;
696  if ((fLastDistanceToInWithV.p == p) && (fLastDistanceToInWithV.vec == v))
697  {
698  return fLastDistanceToIn.value;
699  }
700  else
701  {
702  tmpp = const_cast<G4ThreeVector*>(&(fLastDistanceToInWithV.p));
703  tmpv = const_cast<G4ThreeVector*>(&(fLastDistanceToInWithV.vec));
704  tmpdist = const_cast<G4double*>(&(fLastDistanceToInWithV.value));
705  tmpp->set(p.x(), p.y(), p.z());
706  tmpv->set(v.x(), v.y(), v.z());
707  }
708 
709  //
710  // Calculate DistanceToIn(p,v)
711  //
712 
713  EInside currentside = Inside(p);
714 
715  if (currentside == kInside)
716  {
717  }
718  else
719  {
720  if (currentside == kSurface)
721  {
722  // particle is just on a boundary.
723  // If the particle is entering to the volume, return 0.
724  //
726  if (normal*v < 0)
727  {
728  *tmpdist = 0;
730  }
731  }
732  }
733 
734  // now, we can take smallest positive distance.
735 
736  // Initialize
737  //
738  G4double distance = kInfinity;
739 
740  // find intersections and choose nearest one.
741  //
742  G4VTwistSurface *surfaces[6];
743  surfaces[0] = fLowerEndcap;
744  surfaces[1] = fUpperEndcap;
745  surfaces[2] = fLatterTwisted;
746  surfaces[3] = fFormerTwisted;
747  surfaces[4] = fInnerHype;
748  surfaces[5] = fOuterHype;
749 
750  G4ThreeVector xx;
751  G4ThreeVector bestxx;
752  G4int i;
753  for (i=0; i< 6; i++)
754  {
755  G4double tmpdistance = surfaces[i]->DistanceToIn(p, v, xx);
756  if (tmpdistance < distance)
757  {
758  distance = tmpdistance;
759  bestxx = xx;
760  }
761  }
762  *tmpdist = distance;
763 
765 }
766 
767 //=====================================================================
768 //* DistanceToIn (p) --------------------------------------------------
769 
771 {
772  // DistanceToIn(p):
773  // Calculate distance to surface of shape from `outside',
774  // allowing for tolerance
775 
776  //
777  // checking last value
778  //
779 
780  G4ThreeVector *tmpp;
781  G4double *tmpdist;
782  if (fLastDistanceToIn.p == p)
783  {
784  return fLastDistanceToIn.value;
785  }
786  else
787  {
788  tmpp = const_cast<G4ThreeVector*>(&(fLastDistanceToIn.p));
789  tmpdist = const_cast<G4double*>(&(fLastDistanceToIn.value));
790  tmpp->set(p.x(), p.y(), p.z());
791  }
792 
793  //
794  // Calculate DistanceToIn(p)
795  //
796 
797  EInside currentside = Inside(p);
798 
799  switch (currentside)
800  {
801  case (kInside) :
802  {}
803  case (kSurface) :
804  {
805  *tmpdist = 0.;
806  return fLastDistanceToIn.value;
807  }
808  case (kOutside) :
809  {
810  // Initialize
811  G4double distance = kInfinity;
812 
813  // find intersections and choose nearest one.
814  G4VTwistSurface *surfaces[6];
815  surfaces[0] = fLowerEndcap;
816  surfaces[1] = fUpperEndcap;
817  surfaces[2] = fLatterTwisted;
818  surfaces[3] = fFormerTwisted;
819  surfaces[4] = fInnerHype;
820  surfaces[5] = fOuterHype;
821 
822  G4int i;
823  G4ThreeVector xx;
824  G4ThreeVector bestxx;
825  for (i=0; i< 6; i++)
826  {
827  G4double tmpdistance = surfaces[i]->DistanceTo(p, xx);
828  if (tmpdistance < distance)
829  {
830  distance = tmpdistance;
831  bestxx = xx;
832  }
833  }
834  *tmpdist = distance;
835  return fLastDistanceToIn.value;
836  }
837  default :
838  {
839  G4Exception("G4TwistedTubs::DistanceToIn(p)", "GeomSolids0003",
840  FatalException, "Unknown point location!");
841  }
842  } // switch end
843 
844  return kInfinity;
845 }
846 
847 //=====================================================================
848 //* DistanceToOut (p, v) ----------------------------------------------
849 
851  const G4ThreeVector& v,
852  const G4bool calcNorm,
853  G4bool *validNorm,
854  G4ThreeVector *norm ) const
855 {
856  // DistanceToOut (p, v):
857  // Calculate distance to surface of shape from `inside'
858  // along with the v, allowing for tolerance.
859  // The function returns kInfinity if no intersection or
860  // just grazing within tolerance.
861 
862  //
863  // checking last value
864  //
865 
866  G4ThreeVector *tmpp;
867  G4ThreeVector *tmpv;
868  G4double *tmpdist;
870  {
872  }
873  else
874  {
875  tmpp = const_cast<G4ThreeVector*>(&(fLastDistanceToOutWithV.p));
876  tmpv = const_cast<G4ThreeVector*>(&(fLastDistanceToOutWithV.vec));
877  tmpdist = const_cast<G4double*>(&(fLastDistanceToOutWithV.value));
878  tmpp->set(p.x(), p.y(), p.z());
879  tmpv->set(v.x(), v.y(), v.z());
880  }
881 
882  //
883  // Calculate DistanceToOut(p,v)
884  //
885 
886  EInside currentside = Inside(p);
887 
888  if (currentside == kOutside)
889  {
890  }
891  else
892  {
893  if (currentside == kSurface)
894  {
895  // particle is just on a boundary.
896  // If the particle is exiting from the volume, return 0.
897  //
899  G4VTwistSurface *blockedsurface = fLastNormal.surface[0];
900  if (normal*v > 0)
901  {
902  if (calcNorm)
903  {
904  *norm = (blockedsurface->GetNormal(p, true));
905  *validNorm = blockedsurface->IsValidNorm();
906  }
907  *tmpdist = 0.;
909  }
910  }
911  }
912 
913  // now, we can take smallest positive distance.
914 
915  // Initialize
916  //
917  G4double distance = kInfinity;
918 
919  // find intersections and choose nearest one.
920  //
921  G4VTwistSurface *surfaces[6];
922  surfaces[0] = fLatterTwisted;
923  surfaces[1] = fFormerTwisted;
924  surfaces[2] = fInnerHype;
925  surfaces[3] = fOuterHype;
926  surfaces[4] = fLowerEndcap;
927  surfaces[5] = fUpperEndcap;
928 
929  G4int i;
930  G4int besti = -1;
931  G4ThreeVector xx;
932  G4ThreeVector bestxx;
933  for (i=0; i< 6; i++)
934  {
935  G4double tmpdistance = surfaces[i]->DistanceToOut(p, v, xx);
936  if (tmpdistance < distance)
937  {
938  distance = tmpdistance;
939  bestxx = xx;
940  besti = i;
941  }
942  }
943 
944  if (calcNorm)
945  {
946  if (besti != -1)
947  {
948  *norm = (surfaces[besti]->GetNormal(p, true));
949  *validNorm = surfaces[besti]->IsValidNorm();
950  }
951  }
952 
953  *tmpdist = distance;
954 
956 }
957 
958 
959 //=====================================================================
960 //* DistanceToOut (p) ----------------------------------------------
961 
963 {
964  // DistanceToOut(p):
965  // Calculate distance to surface of shape from `inside',
966  // allowing for tolerance
967 
968  //
969  // checking last value
970  //
971 
972  G4ThreeVector *tmpp;
973  G4double *tmpdist;
974  if (fLastDistanceToOut.p == p)
975  {
976  return fLastDistanceToOut.value;
977  }
978  else
979  {
980  tmpp = const_cast<G4ThreeVector*>(&(fLastDistanceToOut.p));
981  tmpdist = const_cast<G4double*>(&(fLastDistanceToOut.value));
982  tmpp->set(p.x(), p.y(), p.z());
983  }
984 
985  //
986  // Calculate DistanceToOut(p)
987  //
988 
989  EInside currentside = Inside(p);
990 
991  switch (currentside)
992  {
993  case (kOutside) :
994  {
995  }
996  case (kSurface) :
997  {
998  *tmpdist = 0.;
999  return fLastDistanceToOut.value;
1000  }
1001  case (kInside) :
1002  {
1003  // Initialize
1004  G4double distance = kInfinity;
1005 
1006  // find intersections and choose nearest one.
1007  G4VTwistSurface *surfaces[6];
1008  surfaces[0] = fLatterTwisted;
1009  surfaces[1] = fFormerTwisted;
1010  surfaces[2] = fInnerHype;
1011  surfaces[3] = fOuterHype;
1012  surfaces[4] = fLowerEndcap;
1013  surfaces[5] = fUpperEndcap;
1014 
1015  G4int i;
1016  G4ThreeVector xx;
1017  G4ThreeVector bestxx;
1018  for (i=0; i< 6; i++)
1019  {
1020  G4double tmpdistance = surfaces[i]->DistanceTo(p, xx);
1021  if (tmpdistance < distance)
1022  {
1023  distance = tmpdistance;
1024  bestxx = xx;
1025  }
1026  }
1027  *tmpdist = distance;
1028 
1029  return fLastDistanceToOut.value;
1030  }
1031  default :
1032  {
1033  G4Exception("G4TwistedTubs::DistanceToOut(p)", "GeomSolids0003",
1034  FatalException, "Unknown point location!");
1035  }
1036  } // switch end
1037 
1038  return 0;
1039 }
1040 
1041 //=====================================================================
1042 //* StreamInfo --------------------------------------------------------
1043 
1044 std::ostream& G4TwistedTubs::StreamInfo(std::ostream& os) const
1045 {
1046  //
1047  // Stream object contents to an output stream
1048  //
1049  G4int oldprc = os.precision(16);
1050  os << "-----------------------------------------------------------\n"
1051  << " *** Dump for solid - " << GetName() << " ***\n"
1052  << " ===================================================\n"
1053  << " Solid type: G4TwistedTubs\n"
1054  << " Parameters: \n"
1055  << " -ve end Z : " << fEndZ[0]/mm << " mm \n"
1056  << " +ve end Z : " << fEndZ[1]/mm << " mm \n"
1057  << " inner end radius(-ve z): " << fEndInnerRadius[0]/mm << " mm \n"
1058  << " inner end radius(+ve z): " << fEndInnerRadius[1]/mm << " mm \n"
1059  << " outer end radius(-ve z): " << fEndOuterRadius[0]/mm << " mm \n"
1060  << " outer end radius(+ve z): " << fEndOuterRadius[1]/mm << " mm \n"
1061  << " inner radius (z=0) : " << fInnerRadius/mm << " mm \n"
1062  << " outer radius (z=0) : " << fOuterRadius/mm << " mm \n"
1063  << " twisted angle : " << fPhiTwist/degree << " degrees \n"
1064  << " inner stereo angle : " << fInnerStereo/degree << " degrees \n"
1065  << " outer stereo angle : " << fOuterStereo/degree << " degrees \n"
1066  << " phi-width of a piece : " << fDPhi/degree << " degrees \n"
1067  << "-----------------------------------------------------------\n";
1068  os.precision(oldprc);
1069 
1070  return os;
1071 }
1072 
1073 
1074 //=====================================================================
1075 //* DiscribeYourselfTo ------------------------------------------------
1076 
1078 {
1079  scene.AddSolid (*this);
1080 }
1081 
1082 //=====================================================================
1083 //* GetExtent ---------------------------------------------------------
1084 
1086 {
1087  // Define the sides of the box into which the G4Tubs instance would fit.
1088 
1089  G4double maxEndOuterRad = (fEndOuterRadius[0] > fEndOuterRadius[1] ? 0 : 1);
1090  return G4VisExtent( -maxEndOuterRad, maxEndOuterRad,
1091  -maxEndOuterRad, maxEndOuterRad,
1093 }
1094 
1095 //=====================================================================
1096 //* CreatePolyhedron --------------------------------------------------
1097 
1099 {
1100  // number of meshes
1101  //
1103  const G4int k =
1104  G4int(G4Polyhedron::GetNumberOfRotationSteps() * dA / twopi) + 2;
1105  const G4int n =
1106  G4int(G4Polyhedron::GetNumberOfRotationSteps() * fPhiTwist / twopi) + 2;
1107 
1108  const G4int nnodes = 4*(k-1)*(n-2) + 2*k*k ;
1109  const G4int nfaces = 4*(k-1)*(n-1) + 2*(k-1)*(k-1) ;
1110 
1111  G4Polyhedron *ph=new G4Polyhedron;
1112  typedef G4double G4double3[3];
1113  typedef G4int G4int4[4];
1114  G4double3* xyz = new G4double3[nnodes]; // number of nodes
1115  G4int4* faces = new G4int4[nfaces] ; // number of faces
1116  fLowerEndcap->GetFacets(k,k,xyz,faces,0) ;
1117  fUpperEndcap->GetFacets(k,k,xyz,faces,1) ;
1118  fInnerHype->GetFacets(k,n,xyz,faces,2) ;
1119  fFormerTwisted->GetFacets(k,n,xyz,faces,3) ;
1120  fOuterHype->GetFacets(k,n,xyz,faces,4) ;
1121  fLatterTwisted->GetFacets(k,n,xyz,faces,5) ;
1122 
1123  ph->createPolyhedron(nnodes,nfaces,xyz,faces);
1124 
1125  delete[] xyz;
1126  delete[] faces;
1127 
1128  return ph;
1129 }
1130 
1131 //=====================================================================
1132 //* GetPolyhedron -----------------------------------------------------
1133 
1135 {
1136  if (!fpPolyhedron ||
1139  fpPolyhedron->GetNumberOfRotationSteps())
1140  {
1141  G4AutoLock l(&polyhedronMutex);
1142  delete fpPolyhedron;
1144  fRebuildPolyhedron = false;
1145  l.unlock();
1146  }
1147  return fpPolyhedron;
1148 }
1149 
1150 //=====================================================================
1151 //* CreateSurfaces ----------------------------------------------------
1152 
1154 {
1155  // create 6 surfaces of TwistedTub
1156 
1157  G4ThreeVector x0(0, 0, fEndZ[0]);
1158  G4ThreeVector n (0, 0, -1);
1159 
1160  fLowerEndcap = new G4TwistTubsFlatSide("LowerEndcap",
1162  fDPhi, fEndPhi, fEndZ, -1) ;
1163 
1164  fUpperEndcap = new G4TwistTubsFlatSide("UpperEndcap",
1166  fDPhi, fEndPhi, fEndZ, 1) ;
1167 
1168  G4RotationMatrix rotHalfDPhi;
1169  rotHalfDPhi.rotateZ(0.5*fDPhi);
1170 
1171  fLatterTwisted = new G4TwistTubsSide("LatterTwisted",
1173  fDPhi, fEndPhi, fEndZ,
1175  1 ) ;
1176  fFormerTwisted = new G4TwistTubsSide("FormerTwisted",
1178  fDPhi, fEndPhi, fEndZ,
1180  -1 ) ;
1181 
1182  fInnerHype = new G4TwistTubsHypeSide("InnerHype",
1184  fDPhi, fEndPhi, fEndZ,
1187  fOuterHype = new G4TwistTubsHypeSide("OuterHype",
1189  fDPhi, fEndPhi, fEndZ,
1192 
1193 
1194  // set neighbour surfaces
1195  //
1208 }
1209 
1210 
1211 //=====================================================================
1212 //* GetEntityType -----------------------------------------------------
1213 
1215 {
1216  return G4String("G4TwistedTubs");
1217 }
1218 
1219 //=====================================================================
1220 //* Clone -------------------------------------------------------------
1221 
1223 {
1224  return new G4TwistedTubs(*this);
1225 }
1226 
1227 //=====================================================================
1228 //* GetCubicVolume ----------------------------------------------------
1229 
1231 {
1232  if(fCubicVolume != 0.) {;}
1235  return fCubicVolume;
1236 }
1237 
1238 //=====================================================================
1239 //* GetSurfaceArea ----------------------------------------------------
1240 
1242 {
1243  if(fSurfaceArea != 0.) {;}
1245  return fSurfaceArea;
1246 }
1247 
1248 //=====================================================================
1249 //* GetPointOnSurface -------------------------------------------------
1250 
1252 {
1253 
1255  G4double phi , phimin, phimax ;
1256  G4double x , xmin, xmax ;
1257  G4double r , rmin, rmax ;
1258 
1265 
1266  G4double chose = G4RandFlat::shoot(0.,a1 + a2 + a3 + a4 + a5 + a6) ;
1267 
1268  if(chose < a1)
1269  {
1270 
1271  phimin = fOuterHype->GetBoundaryMin(z) ;
1272  phimax = fOuterHype->GetBoundaryMax(z) ;
1273  phi = G4RandFlat::shoot(phimin,phimax) ;
1274 
1275  return fOuterHype->SurfacePoint(phi,z,true) ;
1276 
1277  }
1278  else if ( (chose >= a1) && (chose < a1 + a2 ) )
1279  {
1280 
1281  phimin = fInnerHype->GetBoundaryMin(z) ;
1282  phimax = fInnerHype->GetBoundaryMax(z) ;
1283  phi = G4RandFlat::shoot(phimin,phimax) ;
1284 
1285  return fInnerHype->SurfacePoint(phi,z,true) ;
1286 
1287  }
1288  else if ( (chose >= a1 + a2 ) && (chose < a1 + a2 + a3 ) )
1289  {
1290 
1291  xmin = fLatterTwisted->GetBoundaryMin(z) ;
1292  xmax = fLatterTwisted->GetBoundaryMax(z) ;
1293  x = G4RandFlat::shoot(xmin,xmax) ;
1294 
1295  return fLatterTwisted->SurfacePoint(x,z,true) ;
1296 
1297  }
1298  else if ( (chose >= a1 + a2 + a3 ) && (chose < a1 + a2 + a3 + a4 ) )
1299  {
1300 
1301  xmin = fFormerTwisted->GetBoundaryMin(z) ;
1302  xmax = fFormerTwisted->GetBoundaryMax(z) ;
1303  x = G4RandFlat::shoot(xmin,xmax) ;
1304 
1305  return fFormerTwisted->SurfacePoint(x,z,true) ;
1306  }
1307  else if( (chose >= a1 + a2 + a3 + a4 )&&(chose < a1 + a2 + a3 + a4 + a5 ) )
1308  {
1309  rmin = GetEndInnerRadius(0) ;
1310  rmax = GetEndOuterRadius(0) ;
1311  r = std::sqrt(G4RandFlat::shoot()*(sqr(rmax)-sqr(rmin))+sqr(rmin));
1312 
1313  phimin = fLowerEndcap->GetBoundaryMin(r) ;
1314  phimax = fLowerEndcap->GetBoundaryMax(r) ;
1315  phi = G4RandFlat::shoot(phimin,phimax) ;
1316 
1317  return fLowerEndcap->SurfacePoint(phi,r,true) ;
1318  }
1319  else
1320  {
1321  rmin = GetEndInnerRadius(1) ;
1322  rmax = GetEndOuterRadius(1) ;
1323  r = rmin + (rmax-rmin)*std::sqrt(G4RandFlat::shoot());
1324 
1325  phimin = fUpperEndcap->GetBoundaryMin(r) ;
1326  phimax = fUpperEndcap->GetBoundaryMax(r) ;
1327  phi = G4RandFlat::shoot(phimin,phimax) ;
1328 
1329  return fUpperEndcap->SurfacePoint(phi,r,true) ;
1330  }
1331 }
G4double fZHalfLength
G4String GetName() const
ThreeVector shoot(const G4int Ap, const G4int Af)
G4double GetEndInnerRadius() const
static const G4double kInfinity
Definition: geomdefs.hh:42
G4double fPhiTwist
CLHEP::Hep3Vector G4ThreeVector
G4ThreeVector GetPointOnSurface() const
CLHEP::HepRotation G4RotationMatrix
virtual G4ThreeVector GetNormal(const G4ThreeVector &xx, G4bool isGlobal)=0
G4double z
Definition: TRTMaterials.hh:39
static void AddPolyToExtent(const G4ThreeVector &v0, const G4ThreeVector &v1, const G4ThreeVector &w1, const G4ThreeVector &w0, const G4VoxelLimits &voxellimit, const EAxis axis, G4SolidExtentList &extentlist)
static const G4double a1
std::ostream & StreamInfo(std::ostream &os) const
G4bool GetExtent(G4double &min, G4double &max) const
const G4double pi
G4Polyhedron * CreatePolyhedron() const
G4VTwistSurface * fFormerTwisted
void SetNormal(const G4ThreeVector &newNormal)
G4double fEndOuterRadius[2]
LastValueWithDoubleVector fLastDistanceToInWithV
static const G4double a4
virtual G4bool PartialClip(const G4VoxelLimits &voxelLimit, const EAxis IgnoreMe)
virtual void AddVertexInOrder(const G4ThreeVector vertex)
LastValue fLastDistanceToIn
G4double a
Definition: TRTMaterials.hh:39
EInside Inside(const G4ThreeVector &p) const
virtual void AddSolid(const G4Box &)=0
int G4int
Definition: G4Types.hh:78
void ComputeDimensions(G4VPVParameterisation *, const G4int, const G4VPhysicalVolume *)
G4double fEndInnerRadius[2]
#define G4MUTEX_INITIALIZER
Definition: G4Threading.hh:175
G4bool IsValidNorm() const
G4GeometryType GetEntityType() const
G4VTwistSurface * fUpperEndcap
G4double fEndPhi[2]
virtual G4double DistanceToIn(const G4ThreeVector &gp, const G4ThreeVector &gv, G4ThreeVector &gxxbest)
G4double fInnerRadius
G4double fEndZ[2]
G4double GetEndOuterRadius() const
G4ThreeVector SurfaceNormal(const G4ThreeVector &p) const
static double normal(HepRandomEngine *eptr)
Definition: RandPoisson.cc:77
G4VTwistSurface * fOuterHype
G4double fSurfaceArea
virtual G4double GetSurfaceArea()=0
G4double fInnerRadius2
G4double fOuterRadius2
void SetNeighbours(G4VTwistSurface *axis0min, G4VTwistSurface *axis1min, G4VTwistSurface *axis0max, G4VTwistSurface *axis1max)
virtual G4double DistanceTo(const G4ThreeVector &gp, G4ThreeVector &gxx)
void DescribeYourselfTo(G4VGraphicsScene &scene) const
virtual G4double DistanceToOut(const G4ThreeVector &gp, const G4ThreeVector &gv, G4ThreeVector &gxxbest)
virtual G4ThreeVector SurfacePoint(G4double, G4double, G4bool isGlobal=false)=0
G4double GetRadialTolerance() const
bool G4bool
Definition: G4Types.hh:79
G4VTwistSurface ** surface
void SetFields(G4double phitwist, G4double innerrad, G4double outerrad, G4double negativeEndz, G4double positiveEndz)
G4bool fRebuildPolyhedron
void AddSurface(const G4ClippablePolygon &surface)
LastValueWithDoubleVector fLastDistanceToOutWithV
G4double fEndZ2[2]
G4double DistanceToOut(const G4ThreeVector &p, const G4ThreeVector &v, const G4bool calcnorm=G4bool(false), G4bool *validnorm=0, G4ThreeVector *n=0) const
const G4int n
G4VSolid * Clone() const
virtual G4double GetBoundaryMax(G4double)=0
static const G4double a3
G4double GetSurfaceArea()
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *comments)
Definition: G4Exception.cc:41
LastValue fLastDistanceToOut
virtual void GetFacets(G4int m, G4int n, G4double xyz[][3], G4int faces[][4], G4int iside)=0
virtual G4double GetBoundaryMin(G4double)=0
LastState fLastInside
G4int G4Mutex
Definition: G4Threading.hh:173
G4ThreeVector TransformPoint(const G4ThreeVector &vec) const
G4VTwistSurface * fLatterTwisted
G4double fOuterRadius
G4double DistanceToIn(const G4ThreeVector &p, const G4ThreeVector &v) const
virtual ~G4TwistedTubs()
T max(const T t1, const T t2)
brief Return the largest of the two arguments
EInside
Definition: geomdefs.hh:58
G4VTwistSurface * fInnerHype
EAxis
Definition: geomdefs.hh:54
#define DBL_MIN
Definition: templates.hh:75
T min(const T t1, const T t2)
brief Return the smallest of the two arguments
G4double fTanOuterStereo
static const double degree
Definition: G4SIunits.hh:125
G4double fTanInnerStereo2
G4Polyhedron * fpPolyhedron
G4TwistedTubs(const G4String &pname, G4double twistedangle, G4double endinnerrad, G4double endouterrad, G4double halfzlen, G4double dphi)
#define G4endl
Definition: G4ios.hh:61
G4VSolid & operator=(const G4VSolid &rhs)
Definition: G4VSolid.cc:110
G4int GetNumberOfRotationStepsAtTimeOfCreation() const
LastVector fLastNormal
G4double fTanOuterStereo2
G4double fTanInnerStereo
T sqr(const T &x)
Definition: templates.hh:145
static const G4double a5
double G4double
Definition: G4Types.hh:76
G4double fInnerStereo
G4double GetCubicVolume()
G4double fCubicVolume
G4VTwistSurface * fLowerEndcap
G4VisExtent GetExtent() const
static const double mm
Definition: G4SIunits.hh:102
virtual G4double GetSurfaceArea()
Definition: G4VSolid.cc:250
G4double fOuterStereo
static const G4double a2
static G4GeometryTolerance * GetInstance()
G4Polyhedron * GetPolyhedron() const
G4bool CalculateExtent(const EAxis paxis, const G4VoxelLimits &pvoxellimit, const G4AffineTransform &ptransform, G4double &pmin, G4double &pmax) const
G4TwistedTubs & operator=(const G4TwistedTubs &rhs)