Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/geometry/solids/specific/src/G4TwistTubsHypeSide.cc

Version: [ ReleaseNotes ] [ 1.0 ] [ 1.1 ] [ 2.0 ] [ 3.0 ] [ 3.1 ] [ 3.2 ] [ 4.0 ] [ 4.0.p1 ] [ 4.0.p2 ] [ 4.1 ] [ 4.1.p1 ] [ 5.0 ] [ 5.0.p1 ] [ 5.1 ] [ 5.1.p1 ] [ 5.2 ] [ 5.2.p1 ] [ 5.2.p2 ] [ 6.0 ] [ 6.0.p1 ] [ 6.1 ] [ 6.2 ] [ 6.2.p1 ] [ 6.2.p2 ] [ 7.0 ] [ 7.0.p1 ] [ 7.1 ] [ 7.1.p1 ] [ 8.0 ] [ 8.0.p1 ] [ 8.1 ] [ 8.1.p1 ] [ 8.1.p2 ] [ 8.2 ] [ 8.2.p1 ] [ 8.3 ] [ 8.3.p1 ] [ 8.3.p2 ] [ 9.0 ] [ 9.0.p1 ] [ 9.0.p2 ] [ 9.1 ] [ 9.1.p1 ] [ 9.1.p2 ] [ 9.1.p3 ] [ 9.2 ] [ 9.2.p1 ] [ 9.2.p2 ] [ 9.2.p3 ] [ 9.2.p4 ] [ 9.3 ] [ 9.3.p1 ] [ 9.3.p2 ] [ 9.4 ] [ 9.4.p1 ] [ 9.4.p2 ] [ 9.4.p3 ] [ 9.4.p4 ] [ 9.5 ] [ 9.5.p1 ] [ 9.5.p2 ] [ 9.6 ] [ 9.6.p1 ] [ 9.6.p2 ] [ 9.6.p3 ] [ 9.6.p4 ] [ 10.0 ] [ 10.0.p1 ] [ 10.0.p2 ] [ 10.0.p3 ] [ 10.0.p4 ] [ 10.1 ] [ 10.1.p1 ] [ 10.1.p2 ] [ 10.1.p3 ] [ 10.2 ] [ 10.2.p1 ] [ 10.2.p2 ] [ 10.2.p3 ] [ 10.3 ] [ 10.3.p1 ] [ 10.3.p2 ] [ 10.3.p3 ] [ 10.4 ] [ 10.4.p1 ] [ 10.4.p2 ] [ 10.4.p3 ] [ 10.5 ] [ 10.5.p1 ] [ 10.6 ] [ 10.6.p1 ] [ 10.6.p2 ] [ 10.6.p3 ] [ 10.7 ] [ 10.7.p1 ] [ 10.7.p2 ] [ 10.7.p3 ] [ 10.7.p4 ] [ 11.0 ] [ 11.0.p1 ] [ 11.0.p2 ] [ 11.0.p3, ] [ 11.0.p4 ] [ 11.1 ] [ 11.1.1 ] [ 11.1.2 ] [ 11.1.3 ] [ 11.2 ] [ 11.2.1 ] [ 11.2.2 ] [ 11.3.0 ]

Diff markup

Differences between /geometry/solids/specific/src/G4TwistTubsHypeSide.cc (Version 11.3.0) and /geometry/solids/specific/src/G4TwistTubsHypeSide.cc (Version 10.6.p3)


  1 //                                                  1 //
  2 // *******************************************      2 // ********************************************************************
  3 // * License and Disclaimer                         3 // * License and Disclaimer                                           *
  4 // *                                                4 // *                                                                  *
  5 // * The  Geant4 software  is  copyright of th      5 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
  6 // * the Geant4 Collaboration.  It is provided      6 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
  7 // * conditions of the Geant4 Software License      7 // * conditions of the Geant4 Software License,  included in the file *
  8 // * LICENSE and available at  http://cern.ch/      8 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
  9 // * include a list of copyright holders.           9 // * include a list of copyright holders.                             *
 10 // *                                               10 // *                                                                  *
 11 // * Neither the authors of this software syst     11 // * Neither the authors of this software system, nor their employing *
 12 // * institutes,nor the agencies providing fin     12 // * institutes,nor the agencies providing financial support for this *
 13 // * work  make  any representation or  warran     13 // * work  make  any representation or  warranty, express or implied, *
 14 // * regarding  this  software system or assum     14 // * regarding  this  software system or assume any liability for its *
 15 // * use.  Please see the license in the file      15 // * use.  Please see the license in the file  LICENSE  and URL above *
 16 // * for the full disclaimer and the limitatio     16 // * for the full disclaimer and the limitation of liability.         *
 17 // *                                               17 // *                                                                  *
 18 // * This  code  implementation is the result      18 // * This  code  implementation is the result of  the  scientific and *
 19 // * technical work of the GEANT4 collaboratio     19 // * technical work of the GEANT4 collaboration.                      *
 20 // * By using,  copying,  modifying or  distri     20 // * By using,  copying,  modifying or  distributing the software (or *
 21 // * any work based  on the software)  you  ag     21 // * any work based  on the software)  you  agree  to acknowledge its *
 22 // * use  in  resulting  scientific  publicati     22 // * use  in  resulting  scientific  publications,  and indicate your *
 23 // * acceptance of all terms of the Geant4 Sof     23 // * acceptance of all terms of the Geant4 Software license.          *
 24 // *******************************************     24 // ********************************************************************
 25 //                                                 25 //
 26 // G4TwistTubsHypeSide implementation              26 // G4TwistTubsHypeSide implementation
 27 //                                                 27 //
 28 // 01-Aug-2002 - Kotoyo Hoshina (hoshina@hepbu     28 // 01-Aug-2002 - Kotoyo Hoshina (hoshina@hepburn.s.chiba-u.ac.jp), created.
 29 // 13-Nov-2003 - O.Link (Oliver.Link@cern.ch),     29 // 13-Nov-2003 - O.Link (Oliver.Link@cern.ch), Integration in Geant4
 30 //               from original version in Jupi     30 //               from original version in Jupiter-2.5.02 application.
 31 // -------------------------------------------     31 // --------------------------------------------------------------------
 32                                                    32 
 33 #include "G4TwistTubsHypeSide.hh"                  33 #include "G4TwistTubsHypeSide.hh"
 34 #include "G4PhysicalConstants.hh"                  34 #include "G4PhysicalConstants.hh"
 35 #include "G4GeometryTolerance.hh"                  35 #include "G4GeometryTolerance.hh"
 36                                                    36 
 37 //============================================     37 //=====================================================================
 38 //* constructors -----------------------------     38 //* constructors ------------------------------------------------------
 39                                                    39 
 40 G4TwistTubsHypeSide::G4TwistTubsHypeSide(const     40 G4TwistTubsHypeSide::G4TwistTubsHypeSide(const G4String&         name,
 41                                          const     41                                          const G4RotationMatrix& rot,
 42                                          const     42                                          const G4ThreeVector&    tlate,
 43                                          const     43                                          const G4int             handedness,
 44                                          const     44                                          const G4double          kappa,
 45                                          const     45                                          const G4double          tanstereo,
 46                                          const     46                                          const G4double          r0,
 47                                          const     47                                          const EAxis             axis0,
 48                                          const     48                                          const EAxis             axis1,
 49                                                    49                                                G4double          axis0min,
 50                                                    50                                                G4double          axis1min,
 51                                                    51                                                G4double          axis0max,
 52                                                    52                                                G4double          axis1max )
 53   : G4VTwistSurface(name, rot, tlate, handedne     53   : G4VTwistSurface(name, rot, tlate, handedness, axis0, axis1,
 54                     axis0min, axis1min, axis0m     54                     axis0min, axis1min, axis0max, axis1max),
 55     fKappa(kappa), fTanStereo(tanstereo),          55     fKappa(kappa), fTanStereo(tanstereo),
 56     fTan2Stereo(tanstereo*tanstereo), fR0(r0),     56     fTan2Stereo(tanstereo*tanstereo), fR0(r0), fR02(r0*r0), fDPhi(twopi)
 57 {                                                  57 {
 58    if ( (axis0 == kZAxis) && (axis1 == kPhi) )     58    if ( (axis0 == kZAxis) && (axis1 == kPhi) )
 59    {                                               59    {
 60       G4Exception("G4TwistTubsHypeSide::G4Twis     60       G4Exception("G4TwistTubsHypeSide::G4TwistTubsHypeSide()",
 61                   "GeomSolids0002", FatalError     61                   "GeomSolids0002", FatalErrorInArgument,
 62                   "Should swap axis0 and axis1     62                   "Should swap axis0 and axis1!");
 63    }                                               63    }
 64    fInside.gp.set(kInfinity, kInfinity, kInfin     64    fInside.gp.set(kInfinity, kInfinity, kInfinity);
 65    fInside.inside = kOutside;                      65    fInside.inside = kOutside;
 66    fIsValidNorm = false;                           66    fIsValidNorm = false;
 67    SetCorners();                                   67    SetCorners();
 68    SetBoundaries();                                68    SetBoundaries();
 69 }                                                  69 }
 70                                                    70 
 71 G4TwistTubsHypeSide::G4TwistTubsHypeSide(const     71 G4TwistTubsHypeSide::G4TwistTubsHypeSide(const G4String& name,
 72                                                    72                                                G4double EndInnerRadius[2],
 73                                                    73                                                G4double EndOuterRadius[2],
 74                                                    74                                                G4double DPhi,
 75                                                    75                                                G4double EndPhi[2],
 76                                                    76                                                G4double EndZ[2], 
 77                                                    77                                                G4double InnerRadius,
 78                                                    78                                                G4double OuterRadius,
 79                                                    79                                                G4double Kappa,
 80                                                    80                                                G4double TanInnerStereo,
 81                                                    81                                                G4double TanOuterStereo,
 82                                                    82                                                G4int    handedness)
 83    : G4VTwistSurface(name)                         83    : G4VTwistSurface(name)
 84 {                                                  84 {
 85                                                    85 
 86    fHandedness = handedness;   // +z = +ve, -z     86    fHandedness = handedness;   // +z = +ve, -z = -ve
 87    fAxis[0]    = kPhi;                             87    fAxis[0]    = kPhi;
 88    fAxis[1]    = kZAxis;                           88    fAxis[1]    = kZAxis;
 89    fAxisMin[0] = kInfinity;         // we cann     89    fAxisMin[0] = kInfinity;         // we cannot fix boundary min of Phi, 
 90    fAxisMax[0] = kInfinity;         // because     90    fAxisMax[0] = kInfinity;         // because it depends on z.
 91    fAxisMin[1] = EndZ[0];                          91    fAxisMin[1] = EndZ[0];
 92    fAxisMax[1] = EndZ[1];                          92    fAxisMax[1] = EndZ[1];
 93    fKappa      = Kappa;                            93    fKappa      = Kappa;
 94    fDPhi       = DPhi ;                            94    fDPhi       = DPhi ;
 95                                                    95 
 96    if (handedness < 0)  // inner hyperbolic su     96    if (handedness < 0)  // inner hyperbolic surface
 97    {                                               97    {
 98       fTanStereo  = TanInnerStereo;                98       fTanStereo  = TanInnerStereo;
 99       fR0         = InnerRadius;                   99       fR0         = InnerRadius;
100    }                                              100    }
101    else                 // outer hyperbolic su    101    else                 // outer hyperbolic surface
102    {                                              102    {
103       fTanStereo  = TanOuterStereo;               103       fTanStereo  = TanOuterStereo;
104       fR0         = OuterRadius;                  104       fR0         = OuterRadius;
105    }                                              105    }
106    fTan2Stereo = fTanStereo * fTanStereo;         106    fTan2Stereo = fTanStereo * fTanStereo;
107    fR02        = fR0 * fR0;                       107    fR02        = fR0 * fR0;
108                                                   108    
109    fTrans.set(0, 0, 0);                           109    fTrans.set(0, 0, 0);
110    fIsValidNorm = false;                          110    fIsValidNorm = false;
111                                                   111 
112    fInside.gp.set(kInfinity, kInfinity, kInfin    112    fInside.gp.set(kInfinity, kInfinity, kInfinity);
113    fInside.inside = kOutside;                     113    fInside.inside = kOutside;
114                                                   114    
115    SetCorners(EndInnerRadius, EndOuterRadius,     115    SetCorners(EndInnerRadius, EndOuterRadius, DPhi, EndPhi, EndZ) ; 
116                                                   116 
117    SetBoundaries();                               117    SetBoundaries();
118 }                                                 118 }
119                                                   119 
120 //============================================    120 //=====================================================================
121 //* Fake default constructor -----------------    121 //* Fake default constructor ------------------------------------------
122                                                   122 
123 G4TwistTubsHypeSide::G4TwistTubsHypeSide( __vo    123 G4TwistTubsHypeSide::G4TwistTubsHypeSide( __void__& a )
124   : G4VTwistSurface(a)                         << 124   : G4VTwistSurface(a), fKappa(0.), fTanStereo(0.), fTan2Stereo(0.),
                                                   >> 125     fR0(0.), fR02(0.), fDPhi(0.)
125 {                                                 126 {
126 }                                                 127 }
127                                                   128 
128 //============================================    129 //=====================================================================
129 //* destructor -------------------------------    130 //* destructor --------------------------------------------------------
130                                                   131 
131 G4TwistTubsHypeSide::~G4TwistTubsHypeSide() =  << 132 G4TwistTubsHypeSide::~G4TwistTubsHypeSide()
                                                   >> 133 {
                                                   >> 134 }
132                                                   135 
133 //============================================    136 //=====================================================================
134 //* GetNormal --------------------------------    137 //* GetNormal ---------------------------------------------------------
135                                                   138 
136 G4ThreeVector G4TwistTubsHypeSide::GetNormal(c    139 G4ThreeVector G4TwistTubsHypeSide::GetNormal(const G4ThreeVector& tmpxx, 
137                                                   140                                                    G4bool isGlobal) 
138 {                                                 141 {
139    // GetNormal returns a normal vector at a s    142    // GetNormal returns a normal vector at a surface (or very close
140    // to surface) point at tmpxx.                 143    // to surface) point at tmpxx.
141    // If isGlobal=true, it returns the normal     144    // If isGlobal=true, it returns the normal in global coordinate.
142                                                   145    
143    G4ThreeVector xx;                              146    G4ThreeVector xx;
144    if (isGlobal)                                  147    if (isGlobal)
145    {                                              148    {
146       xx = ComputeLocalPoint(tmpxx);              149       xx = ComputeLocalPoint(tmpxx);
147       if ((xx - fCurrentNormal.p).mag() < 0.5     150       if ((xx - fCurrentNormal.p).mag() < 0.5 * kCarTolerance)
148       {                                           151       {
149          return ComputeGlobalDirection(fCurren    152          return ComputeGlobalDirection(fCurrentNormal.normal);
150       }                                           153       }
151    }                                              154    }
152    else                                           155    else
153    {                                              156    {
154       xx = tmpxx;                                 157       xx = tmpxx;
155       if (xx == fCurrentNormal.p)                 158       if (xx == fCurrentNormal.p)
156       {                                           159       {
157          return fCurrentNormal.normal;            160          return fCurrentNormal.normal;
158       }                                           161       }
159    }                                              162    }
160                                                   163    
161    fCurrentNormal.p = xx;                         164    fCurrentNormal.p = xx;
162                                                   165 
163    G4ThreeVector normal( xx.x(), xx.y(), -xx.z    166    G4ThreeVector normal( xx.x(), xx.y(), -xx.z() * fTan2Stereo);
164    normal *= fHandedness;                         167    normal *= fHandedness;
165    normal = normal.unit();                        168    normal = normal.unit();
166                                                   169 
167    if (isGlobal)                                  170    if (isGlobal)
168    {                                              171    {
169       fCurrentNormal.normal = ComputeLocalDire    172       fCurrentNormal.normal = ComputeLocalDirection(normal);
170    }                                              173    }
171    else                                           174    else
172    {                                              175    {
173       fCurrentNormal.normal = normal;             176       fCurrentNormal.normal = normal;
174    }                                              177    }
175    return fCurrentNormal.normal;                  178    return fCurrentNormal.normal;
176 }                                                 179 }
177                                                   180 
178 //============================================    181 //=====================================================================
179 //* Inside() ---------------------------------    182 //* Inside() ----------------------------------------------------------
180                                                   183 
181 EInside G4TwistTubsHypeSide::Inside(const G4Th    184 EInside G4TwistTubsHypeSide::Inside(const G4ThreeVector& gp) 
182 {                                                 185 {
183    // Inside returns                              186    // Inside returns 
184    const G4double halftol                         187    const G4double halftol
185      = 0.5 * G4GeometryTolerance::GetInstance(    188      = 0.5 * G4GeometryTolerance::GetInstance()->GetRadialTolerance();
186                                                   189 
187    if (fInside.gp == gp)                          190    if (fInside.gp == gp)
188    {                                              191    {
189       return fInside.inside;                      192       return fInside.inside;
190    }                                              193    }
191    fInside.gp = gp;                               194    fInside.gp = gp;
192                                                   195    
193    G4ThreeVector p = ComputeLocalPoint(gp);       196    G4ThreeVector p = ComputeLocalPoint(gp);
194                                                   197   
195                                                   198 
196    if (p.mag() < DBL_MIN)                         199    if (p.mag() < DBL_MIN)
197    {                                              200    {
198       fInside.inside = kOutside;                  201       fInside.inside = kOutside;
199       return fInside.inside;                      202       return fInside.inside;
200    }                                              203    }
201                                                   204    
202    G4double rhohype = GetRhoAtPZ(p);              205    G4double rhohype = GetRhoAtPZ(p);
203    G4double distanceToOut = fHandedness * (rho    206    G4double distanceToOut = fHandedness * (rhohype - p.getRho());
204                             // +ve : inside       207                             // +ve : inside
205                                                   208 
206    if (distanceToOut < -halftol)                  209    if (distanceToOut < -halftol)
207    {                                              210    {
208      fInside.inside = kOutside;                   211      fInside.inside = kOutside;
209    }                                              212    }
210    else                                           213    else
211    {                                              214    {
212       G4int areacode = GetAreaCode(p);            215       G4int areacode = GetAreaCode(p);
213       if (IsOutside(areacode))                    216       if (IsOutside(areacode))
214       {                                           217       {
215          fInside.inside = kOutside;               218          fInside.inside = kOutside;
216       }                                           219       }
217       else if (IsBoundary(areacode))              220       else if (IsBoundary(areacode))
218       {                                           221       {
219          fInside.inside = kSurface;               222          fInside.inside = kSurface;
220       }                                           223       }
221       else if (IsInside(areacode))                224       else if (IsInside(areacode))
222       {                                           225       {
223          if (distanceToOut <= halftol)            226          if (distanceToOut <= halftol)
224          {                                        227          {
225             fInside.inside = kSurface;            228             fInside.inside = kSurface;
226          }                                        229          }
227          else                                     230          else
228          {                                        231          {
229             fInside.inside = kInside;             232             fInside.inside = kInside;
230          }                                        233          }
231       }                                           234       }
232       else                                        235       else
233       {                                           236       {
234          G4cout << "WARNING - G4TwistTubsHypeS    237          G4cout << "WARNING - G4TwistTubsHypeSide::Inside()" << G4endl
235                 << "          Invalid option !    238                 << "          Invalid option !" << G4endl
236                 << "          name, areacode,     239                 << "          name, areacode, distanceToOut = "
237                 << GetName() << ", " << std::h    240                 << GetName() << ", " << std::hex << areacode
238                 << std::dec << ", " << distanc    241                 << std::dec << ", " << distanceToOut << G4endl;
239       }                                           242       }
240    }                                              243    }
241                                                   244 
242    return fInside.inside;                         245    return fInside.inside; 
243 }                                                 246 }
244                                                   247 
245 //============================================    248 //=====================================================================
246 //* DistanceToSurface ------------------------    249 //* DistanceToSurface -------------------------------------------------
247                                                   250 
248 G4int G4TwistTubsHypeSide::DistanceToSurface(c    251 G4int G4TwistTubsHypeSide::DistanceToSurface(const G4ThreeVector& gp,
249                                              c    252                                              const G4ThreeVector& gv,
250                                                   253                                                    G4ThreeVector  gxx[],
251                                                   254                                                    G4double       distance[],
252                                                   255                                                    G4int          areacode[],
253                                                   256                                                    G4bool         isvalid[],
254                                                   257                                                    EValidate      validate)
255 {                                                 258 {
256    // Decide if and where a line intersects wi    259    // Decide if and where a line intersects with a hyperbolic
257    // surface (of infinite extent)                260    // surface (of infinite extent)
258    //                                             261    //
259    // Arguments:                                  262    // Arguments:
260    //     p       - (in) Point on trajectory      263    //     p       - (in) Point on trajectory
261    //     v       - (in) Vector along trajecto    264    //     v       - (in) Vector along trajectory
262    //     r2      - (in) Square of radius at z    265    //     r2      - (in) Square of radius at z = 0
263    //     tan2phi - (in) std::tan(stereo)**2      266    //     tan2phi - (in) std::tan(stereo)**2
264    //     s       - (out) Up to two points of     267    //     s       - (out) Up to two points of intersection, where the
265    //                     intersection point i    268    //                     intersection point is p + s*v, and if there are
266    //                     two intersections, s    269    //                     two intersections, s[0] < s[1]. May be negative.
267    // Returns:                                    270    // Returns:
268    //     The number of intersections. If 0, t    271    //     The number of intersections. If 0, the trajectory misses.
269    //                                             272    //
270    //                                             273    //
271    // Equation of a line:                         274    // Equation of a line:
272    //                                             275    //
273    //       x = x0 + s*tx      y = y0 + s*ty      276    //       x = x0 + s*tx      y = y0 + s*ty      z = z0 + s*tz
274    //                                             277    //
275    // Equation of a hyperbolic surface:           278    // Equation of a hyperbolic surface:
276    //                                             279    //
277    //       x**2 + y**2 = r**2 + (z*tanPhi)**2    280    //       x**2 + y**2 = r**2 + (z*tanPhi)**2
278    //                                             281    //
279    // Solution is quadratic:                      282    // Solution is quadratic:
280    //                                             283    //
281    //  a*s**2 + b*s + c = 0                       284    //  a*s**2 + b*s + c = 0
282    //                                             285    //
283    // where:                                      286    // where:
284    //                                             287    //
285    //  a = tx**2 + ty**2 - (tz*tanPhi)**2         288    //  a = tx**2 + ty**2 - (tz*tanPhi)**2
286    //                                             289    //
287    //  b = 2*( x0*tx + y0*ty - z0*tz*tanPhi**2    290    //  b = 2*( x0*tx + y0*ty - z0*tz*tanPhi**2 )
288    //                                             291    //
289    //  c = x0**2 + y0**2 - r**2 - (z0*tanPhi)*    292    //  c = x0**2 + y0**2 - r**2 - (z0*tanPhi)**2
290    //                                             293    //
291                                                   294       
292    fCurStatWithV.ResetfDone(validate, &gp, &gv    295    fCurStatWithV.ResetfDone(validate, &gp, &gv);
293                                                   296 
294    if (fCurStatWithV.IsDone())                    297    if (fCurStatWithV.IsDone())
295    {                                              298    {
296       for (G4int i=0; i<fCurStatWithV.GetNXX()    299       for (G4int i=0; i<fCurStatWithV.GetNXX(); ++i)
297       {                                           300       {
298          gxx[i] = fCurStatWithV.GetXX(i);         301          gxx[i] = fCurStatWithV.GetXX(i);
299          distance[i] = fCurStatWithV.GetDistan    302          distance[i] = fCurStatWithV.GetDistance(i);
300          areacode[i] = fCurStatWithV.GetAreaco    303          areacode[i] = fCurStatWithV.GetAreacode(i);
301          isvalid[i]  = fCurStatWithV.IsValid(i    304          isvalid[i]  = fCurStatWithV.IsValid(i);
302       }                                           305       }
303       return fCurStatWithV.GetNXX();              306       return fCurStatWithV.GetNXX();
304    }                                              307    }
305    else   // initialize                           308    else   // initialize
306    {                                              309    {
307       for (auto i=0; i<2; ++i)                    310       for (auto i=0; i<2; ++i)
308       {                                           311       {
309          distance[i] = kInfinity;                 312          distance[i] = kInfinity;
310          areacode[i] = sOutside;                  313          areacode[i] = sOutside;
311          isvalid[i]  = false;                     314          isvalid[i]  = false;
312          gxx[i].set(kInfinity, kInfinity, kInf    315          gxx[i].set(kInfinity, kInfinity, kInfinity);
313       }                                           316       }
314    }                                              317    }
315                                                   318    
316    G4ThreeVector p = ComputeLocalPoint(gp);       319    G4ThreeVector p = ComputeLocalPoint(gp);
317    G4ThreeVector v = ComputeLocalDirection(gv)    320    G4ThreeVector v = ComputeLocalDirection(gv);
318    G4ThreeVector xx[2];                           321    G4ThreeVector xx[2]; 
319                                                   322    
320    //                                             323    //
321    // special case!  p is on origin.              324    // special case!  p is on origin.
322    //                                             325    // 
323                                                   326 
324    if (p.mag() == 0)                              327    if (p.mag() == 0)
325    {                                              328    {
326       // p is origin.                             329       // p is origin. 
327       // unique solution of 2-dimension questi    330       // unique solution of 2-dimension question in r-z plane 
328       // Equations:                               331       // Equations:
329       //    r^2 = fR02 + z^2*fTan2Stere0          332       //    r^2 = fR02 + z^2*fTan2Stere0
330       //    r = beta*z                            333       //    r = beta*z
331       //        where                             334       //        where 
332       //        beta = vrho / vz                  335       //        beta = vrho / vz
333       // Solution (z value of intersection poi    336       // Solution (z value of intersection point):
334       //    xxz = +- std::sqrt (fR02 / (beta^2    337       //    xxz = +- std::sqrt (fR02 / (beta^2 - fTan2Stereo))
335       //                                          338       //
336                                                   339 
337       G4double vz    = v.z();                     340       G4double vz    = v.z();
338       G4double absvz = std::fabs(vz);             341       G4double absvz = std::fabs(vz);
339       G4double vrho  = v.getRho();                342       G4double vrho  = v.getRho();       
340       G4double vslope = vrho/vz;                  343       G4double vslope = vrho/vz;
341       G4double vslope2 = vslope * vslope;         344       G4double vslope2 = vslope * vslope;
342       if (vrho == 0 || (vrho/absvz) <= (absvz*    345       if (vrho == 0 || (vrho/absvz) <= (absvz*std::fabs(fTanStereo)/absvz))
343       {                                           346       {
344          // vz/vrho is bigger than slope of as    347          // vz/vrho is bigger than slope of asymptonic line
345          distance[0] = kInfinity;                 348          distance[0] = kInfinity;
346          fCurStatWithV.SetCurrentStatus(0, gxx    349          fCurStatWithV.SetCurrentStatus(0, gxx[0], distance[0], areacode[0],
347                                         isvali    350                                         isvalid[0], 0, validate, &gp, &gv);
348          return 0;                                351          return 0;
349       }                                           352       }
350                                                   353        
351       if (vz != 0.0)                           << 354       if (vz)
352       {                                           355       { 
353          G4double xxz  = std::sqrt(fR02 / (vsl    356          G4double xxz  = std::sqrt(fR02 / (vslope2 - fTan2Stereo)) 
354                         * (vz / std::fabs(vz))    357                         * (vz / std::fabs(vz)) ;
355          G4double t = xxz / vz;                   358          G4double t = xxz / vz;
356          xx[0].set(t*v.x(), t*v.y(), xxz);        359          xx[0].set(t*v.x(), t*v.y(), xxz);
357       }                                           360       }
358       else                                        361       else
359       {                                           362       {
360          // p.z = 0 && v.z =0                     363          // p.z = 0 && v.z =0
361          xx[0].set(v.x()*fR0, v.y()*fR0, 0);      364          xx[0].set(v.x()*fR0, v.y()*fR0, 0);  // v is a unit vector.
362       }                                           365       }
363       distance[0] = xx[0].mag();                  366       distance[0] = xx[0].mag();
364       gxx[0]      = ComputeGlobalPoint(xx[0]);    367       gxx[0]      = ComputeGlobalPoint(xx[0]);
365                                                   368 
366       if (validate == kValidateWithTol)           369       if (validate == kValidateWithTol)
367       {                                           370       {
368          areacode[0] = GetAreaCode(xx[0]);        371          areacode[0] = GetAreaCode(xx[0]);
369          if (!IsOutside(areacode[0]))             372          if (!IsOutside(areacode[0]))
370          {                                        373          {
371             if (distance[0] >= 0) isvalid[0] =    374             if (distance[0] >= 0) isvalid[0] = true;
372          }                                        375          }
373       }                                           376       }
374       else if (validate == kValidateWithoutTol    377       else if (validate == kValidateWithoutTol)
375       {                                           378       {
376          areacode[0] = GetAreaCode(xx[0], fals    379          areacode[0] = GetAreaCode(xx[0], false);
377          if (IsInside(areacode[0]))               380          if (IsInside(areacode[0]))
378          {                                        381          {
379             if (distance[0] >= 0) isvalid[0] =    382             if (distance[0] >= 0) isvalid[0] = true;
380          }                                        383          }
381       }                                           384       }
382       else  // kDontValidate                      385       else  // kDontValidate                       
383       {                                           386       {
384          areacode[0] = sInside;                   387          areacode[0] = sInside;
385             if (distance[0] >= 0) isvalid[0] =    388             if (distance[0] >= 0) isvalid[0] = true;
386       }                                           389       }
387                                                   390                  
388       fCurStatWithV.SetCurrentStatus(0, gxx[0]    391       fCurStatWithV.SetCurrentStatus(0, gxx[0], distance[0], areacode[0],
389                                      isvalid[0    392                                      isvalid[0], 1, validate, &gp, &gv);
390       return 1;                                   393       return 1;
391    }                                              394    }
392                                                   395 
393    //                                             396    //
394    // special case end.                           397    // special case end.
395    //                                             398    // 
396                                                   399 
397    G4double a = v.x()*v.x() + v.y()*v.y() - v.    400    G4double a = v.x()*v.x() + v.y()*v.y() - v.z()*v.z()*fTan2Stereo;
398    G4double b = 2.0                               401    G4double b = 2.0
399               * ( p.x() * v.x() + p.y() * v.y(    402               * ( p.x() * v.x() + p.y() * v.y() - p.z() * v.z() * fTan2Stereo );
400    G4double c = p.x()*p.x() + p.y()*p.y() - fR    403    G4double c = p.x()*p.x() + p.y()*p.y() - fR02 - p.z()*p.z()*fTan2Stereo;
401    G4double D = b*b - 4*a*c;          //discri    404    G4double D = b*b - 4*a*c;          //discriminant
402    G4int vout = 0;                                405    G4int vout = 0;
403                                                   406    
404    if (std::fabs(a) < DBL_MIN)                    407    if (std::fabs(a) < DBL_MIN)
405    {                                              408    {
406       if (std::fabs(b) > DBL_MIN)            /    409       if (std::fabs(b) > DBL_MIN)            // single solution
407       {                                           410       {
408          distance[0] = -c/b;                      411          distance[0] = -c/b;
409          xx[0] = p + distance[0]*v;               412          xx[0] = p + distance[0]*v;
410          gxx[0] = ComputeGlobalPoint(xx[0]);      413          gxx[0] = ComputeGlobalPoint(xx[0]);
411                                                   414 
412          if (validate == kValidateWithTol)        415          if (validate == kValidateWithTol)
413          {                                        416          {
414             areacode[0] = GetAreaCode(xx[0]);     417             areacode[0] = GetAreaCode(xx[0]);
415             if (!IsOutside(areacode[0]))          418             if (!IsOutside(areacode[0]))
416             {                                     419             {
417                if (distance[0] >= 0) isvalid[0    420                if (distance[0] >= 0) isvalid[0] = true;
418             }                                     421             }
419          }                                        422          }
420          else if (validate == kValidateWithout    423          else if (validate == kValidateWithoutTol)
421          {                                        424          {
422             areacode[0] = GetAreaCode(xx[0], f    425             areacode[0] = GetAreaCode(xx[0], false);
423             if (IsInside(areacode[0]))            426             if (IsInside(areacode[0]))
424             {                                     427             {
425                if (distance[0] >= 0) isvalid[0    428                if (distance[0] >= 0) isvalid[0] = true;
426             }                                     429             }
427          }                                        430          }
428          else  // kDontValidate                   431          else  // kDontValidate                       
429          {                                        432          {
430             areacode[0] = sInside;                433             areacode[0] = sInside;
431                if (distance[0] >= 0) isvalid[0    434                if (distance[0] >= 0) isvalid[0] = true;
432          }                                        435          }
433                                                   436                  
434          fCurStatWithV.SetCurrentStatus(0, gxx    437          fCurStatWithV.SetCurrentStatus(0, gxx[0], distance[0], areacode[0],
435                                         isvali    438                                         isvalid[0], 1, validate, &gp, &gv);
436          vout = 1;                                439          vout = 1;
437       }                                           440       }
438       else                                        441       else
439       {                                           442       {
440         // if a=b=0 and c != 0, p is origin an    443         // if a=b=0 and c != 0, p is origin and v is parallel to asymptotic line
441         // if a=b=c=0, p is on surface and v i    444         // if a=b=c=0, p is on surface and v is paralell to stereo wire.
442         // return distance = infinity             445         // return distance = infinity
443                                                   446 
444          fCurStatWithV.SetCurrentStatus(0, gxx    447          fCurStatWithV.SetCurrentStatus(0, gxx[0], distance[0], areacode[0],
445                                         isvali    448                                         isvalid[0], 0, validate, &gp, &gv);
446          vout = 0;                                449          vout = 0;
447       }                                           450       }
448    }                                              451    }
449    else if (D > DBL_MIN)          // double so    452    else if (D > DBL_MIN)          // double solutions
450    {                                              453    {
451       D = std::sqrt(D);                           454       D = std::sqrt(D);
452       G4double      factor = 0.5/a;               455       G4double      factor = 0.5/a;
453       G4double      tmpdist[2] = {kInfinity, k    456       G4double      tmpdist[2] = {kInfinity, kInfinity};
454       G4ThreeVector tmpxx[2] ;                    457       G4ThreeVector tmpxx[2] ;
455       G4int         tmpareacode[2] = {sOutside    458       G4int         tmpareacode[2] = {sOutside, sOutside};
456       G4bool        tmpisvalid[2]  = {false, f    459       G4bool        tmpisvalid[2]  = {false, false};
457                                                   460 
458       for (auto i=0; i<2; ++i)                    461       for (auto i=0; i<2; ++i)
459       {                                           462       {
460          tmpdist[i] = factor*(-b - D);            463          tmpdist[i] = factor*(-b - D);
461          D = -D;                                  464          D = -D;
462          tmpxx[i] = p + tmpdist[i]*v;             465          tmpxx[i] = p + tmpdist[i]*v;
463                                                   466         
464          if (validate == kValidateWithTol)        467          if (validate == kValidateWithTol)
465          {                                        468          {
466             tmpareacode[i] = GetAreaCode(tmpxx    469             tmpareacode[i] = GetAreaCode(tmpxx[i]);
467             if (!IsOutside(tmpareacode[i]))       470             if (!IsOutside(tmpareacode[i]))
468             {                                     471             {
469                if (tmpdist[i] >= 0) tmpisvalid    472                if (tmpdist[i] >= 0) tmpisvalid[i] = true;
470                continue;                          473                continue;
471             }                                     474             }
472          }                                        475          }
473          else if (validate == kValidateWithout    476          else if (validate == kValidateWithoutTol)
474          {                                        477          {
475             tmpareacode[i] = GetAreaCode(tmpxx    478             tmpareacode[i] = GetAreaCode(tmpxx[i], false);
476             if (IsInside(tmpareacode[i]))         479             if (IsInside(tmpareacode[i]))
477             {                                     480             {
478                if (tmpdist[i] >= 0) tmpisvalid    481                if (tmpdist[i] >= 0) tmpisvalid[i] = true;
479                continue;                          482                continue;
480             }                                     483             }
481          }                                        484          }
482          else  // kDontValidate                   485          else  // kDontValidate
483          {                                        486          {
484             tmpareacode[i] = sInside;             487             tmpareacode[i] = sInside;
485                if (tmpdist[i] >= 0) tmpisvalid    488                if (tmpdist[i] >= 0) tmpisvalid[i] = true;
486             continue;                             489             continue;
487          }                                        490          }
488       }                                           491       }      
489                                                   492 
490       if (tmpdist[0] <= tmpdist[1])               493       if (tmpdist[0] <= tmpdist[1])
491       {                                           494       {
492           distance[0] = tmpdist[0];               495           distance[0] = tmpdist[0];
493           distance[1] = tmpdist[1];               496           distance[1] = tmpdist[1];
494           xx[0]       = tmpxx[0];                 497           xx[0]       = tmpxx[0];
495           xx[1]       = tmpxx[1];                 498           xx[1]       = tmpxx[1];
496           gxx[0]      = ComputeGlobalPoint(tmp    499           gxx[0]      = ComputeGlobalPoint(tmpxx[0]);
497           gxx[1]      = ComputeGlobalPoint(tmp    500           gxx[1]      = ComputeGlobalPoint(tmpxx[1]);
498           areacode[0] = tmpareacode[0];           501           areacode[0] = tmpareacode[0];
499           areacode[1] = tmpareacode[1];           502           areacode[1] = tmpareacode[1];
500           isvalid[0]  = tmpisvalid[0];            503           isvalid[0]  = tmpisvalid[0];
501           isvalid[1]  = tmpisvalid[1];            504           isvalid[1]  = tmpisvalid[1];
502       }                                           505       }
503       else                                        506       else
504       {                                           507       {
505           distance[0] = tmpdist[1];               508           distance[0] = tmpdist[1];
506           distance[1] = tmpdist[0];               509           distance[1] = tmpdist[0];
507           xx[0]       = tmpxx[1];                 510           xx[0]       = tmpxx[1];
508           xx[1]       = tmpxx[0];                 511           xx[1]       = tmpxx[0];
509           gxx[0]      = ComputeGlobalPoint(tmp    512           gxx[0]      = ComputeGlobalPoint(tmpxx[1]);
510           gxx[1]      = ComputeGlobalPoint(tmp    513           gxx[1]      = ComputeGlobalPoint(tmpxx[0]);
511           areacode[0] = tmpareacode[1];           514           areacode[0] = tmpareacode[1];
512           areacode[1] = tmpareacode[0];           515           areacode[1] = tmpareacode[0];
513           isvalid[0]  = tmpisvalid[1];            516           isvalid[0]  = tmpisvalid[1];
514           isvalid[1]  = tmpisvalid[0];            517           isvalid[1]  = tmpisvalid[0];
515       }                                           518       }
516                                                   519          
517       fCurStatWithV.SetCurrentStatus(0, gxx[0]    520       fCurStatWithV.SetCurrentStatus(0, gxx[0], distance[0], areacode[0],
518                                      isvalid[0    521                                      isvalid[0], 2, validate, &gp, &gv);
519       fCurStatWithV.SetCurrentStatus(1, gxx[1]    522       fCurStatWithV.SetCurrentStatus(1, gxx[1], distance[1], areacode[1],
520                                      isvalid[1    523                                      isvalid[1], 2, validate, &gp, &gv);
521       vout = 2;                                   524       vout = 2;
522    }                                              525    }
523    else                                           526    else
524    {                                              527    {
525       // if D<0, no solution                      528       // if D<0, no solution
526       // if D=0, just grazing the surfaces, re    529       // if D=0, just grazing the surfaces, return kInfinity
527                                                   530 
528       fCurStatWithV.SetCurrentStatus(0, gxx[0]    531       fCurStatWithV.SetCurrentStatus(0, gxx[0], distance[0], areacode[0],
529                                      isvalid[0    532                                      isvalid[0], 0, validate, &gp, &gv);
530       vout = 0;                                   533       vout = 0;
531    }                                              534    }
532    return vout;                                   535    return vout;
533 }                                                 536 }
534                                                   537 
535 //============================================    538 //=====================================================================
536 //* DistanceToSurface ------------------------    539 //* DistanceToSurface -------------------------------------------------
537                                                   540 
538 G4int G4TwistTubsHypeSide::DistanceToSurface(c    541 G4int G4TwistTubsHypeSide::DistanceToSurface(const G4ThreeVector& gp,
539                                                   542                                                    G4ThreeVector  gxx[],
540                                                   543                                                    G4double       distance[],
541                                                   544                                                    G4int          areacode[])
542 {                                                 545 {
543     // Find the approximate distance of a poin    546     // Find the approximate distance of a point of a hyperbolic surface.
544     // The distance must be an underestimate.     547     // The distance must be an underestimate. 
545     // It will also be nice (although not nece    548     // It will also be nice (although not necessary) that the estimate is
546     // always finite no matter how close the p    549     // always finite no matter how close the point is.
547     //                                            550     //
548     // We arranged G4Hype::ApproxDistOutside a    551     // We arranged G4Hype::ApproxDistOutside and G4Hype::ApproxDistInside
549     // for this function. See these discriptio    552     // for this function. See these discriptions.
550                                                   553     
551    const G4double halftol                         554    const G4double halftol
552      = 0.5 * G4GeometryTolerance::GetInstance(    555      = 0.5 * G4GeometryTolerance::GetInstance()->GetRadialTolerance();
553                                                   556 
554    fCurStat.ResetfDone(kDontValidate, &gp);       557    fCurStat.ResetfDone(kDontValidate, &gp);
555                                                   558 
556    if (fCurStat.IsDone())                         559    if (fCurStat.IsDone())
557    {                                              560    {
558       for (G4int i=0; i<fCurStat.GetNXX(); ++i    561       for (G4int i=0; i<fCurStat.GetNXX(); ++i)
559       {                                           562       {
560          gxx[i] = fCurStat.GetXX(i);              563          gxx[i] = fCurStat.GetXX(i);
561          distance[i] = fCurStat.GetDistance(i)    564          distance[i] = fCurStat.GetDistance(i);
562          areacode[i] = fCurStat.GetAreacode(i)    565          areacode[i] = fCurStat.GetAreacode(i);
563       }                                           566       }
564       return fCurStat.GetNXX();                   567       return fCurStat.GetNXX();
565    }                                              568    }
566    else  // initialize                            569    else  // initialize
567    {                                              570    {
568       for (auto i=0; i<2; ++i)                    571       for (auto i=0; i<2; ++i)
569       {                                           572       {
570          distance[i] = kInfinity;                 573          distance[i] = kInfinity;
571          areacode[i] = sOutside;                  574          areacode[i] = sOutside;
572          gxx[i].set(kInfinity, kInfinity, kInf    575          gxx[i].set(kInfinity, kInfinity, kInfinity);
573       }                                           576       }
574    }                                              577    }
575                                                   578    
576                                                   579 
577    G4ThreeVector p = ComputeLocalPoint(gp);       580    G4ThreeVector p = ComputeLocalPoint(gp);
578    G4ThreeVector xx;                              581    G4ThreeVector xx;
579                                                   582 
580    //                                             583    //
581    // special case!                               584    // special case!
582    // If p is on surface, return distance = 0     585    // If p is on surface, return distance = 0 immediatery .
583    //                                             586    //
584    G4ThreeVector  lastgxx[2];                     587    G4ThreeVector  lastgxx[2];
585    for (auto i=0; i<2; ++i)                       588    for (auto i=0; i<2; ++i)
586    {                                              589    {
587       lastgxx[i] = fCurStatWithV.GetXX(i);        590       lastgxx[i] = fCurStatWithV.GetXX(i);
588    }                                              591    }
589                                                   592 
590    if ((gp - lastgxx[0]).mag() < halftol || (g    593    if ((gp - lastgxx[0]).mag() < halftol || (gp - lastgxx[1]).mag() < halftol)
591    {                                              594    {
592       // last winner, or last poststep point i    595       // last winner, or last poststep point is on the surface.
593       xx = p;                                     596       xx = p;             
594       gxx[0] = gp;                                597       gxx[0] = gp;
595       distance[0] = 0;                            598       distance[0] = 0;      
596                                                   599 
597       G4bool isvalid = true;                      600       G4bool isvalid = true;
598       fCurStat.SetCurrentStatus(0, gxx[0], dis    601       fCurStat.SetCurrentStatus(0, gxx[0], distance[0], areacode[0],
599                                 isvalid, 1, kD    602                                 isvalid, 1, kDontValidate, &gp);
600                                                   603 
601       return 1;                                   604       return 1;
602    }                                              605    }
603    //                                             606    //
604    // special case end                            607    // special case end
605    //                                             608    //
606                                                   609        
607    G4double prho       = p.getRho();              610    G4double prho       = p.getRho();
608    G4double pz         = std::fabs(p.z());        611    G4double pz         = std::fabs(p.z());           // use symmetry
609    G4double r1         = std::sqrt(fR02 + pz *    612    G4double r1         = std::sqrt(fR02 + pz * pz * fTan2Stereo);
610                                                   613    
611    G4ThreeVector pabsz(p.x(), p.y(), pz);         614    G4ThreeVector pabsz(p.x(), p.y(), pz);
612                                                   615     
613    if (prho > r1 + halftol)   // p is outside     616    if (prho > r1 + halftol)   // p is outside of Hyperbolic surface
614    {                                              617    {
615       // First point xx1                          618       // First point xx1
616       G4double t = r1 / prho;                     619       G4double t = r1 / prho;
617       G4ThreeVector xx1(t * pabsz.x(), t * pab    620       G4ThreeVector xx1(t * pabsz.x(), t * pabsz.y() , pz);
618                                                   621       
619       // Second point xx2                         622       // Second point xx2
620       G4double z2 = (prho * fTanStereo + pz) /    623       G4double z2 = (prho * fTanStereo + pz) / (1 + fTan2Stereo);
621       G4double r2 = std::sqrt(fR02 + z2 * z2 *    624       G4double r2 = std::sqrt(fR02 + z2 * z2 * fTan2Stereo);
622       t = r2 / prho;                              625       t = r2 / prho;
623       G4ThreeVector xx2(t * pabsz.x(), t * pab    626       G4ThreeVector xx2(t * pabsz.x(), t * pabsz.y() , z2);
624                                                   627             
625       G4double len = (xx2 - xx1).mag();           628       G4double len = (xx2 - xx1).mag();
626       if (len < DBL_MIN)                          629       if (len < DBL_MIN)
627       {                                           630       {
628          // xx2 = xx1?? I guess we                631          // xx2 = xx1?? I guess we
629          // must have really bracketed the nor    632          // must have really bracketed the normal
630          distance[0] = (pabsz - xx1).mag();       633          distance[0] = (pabsz - xx1).mag();
631          xx = xx1;                                634          xx = xx1;
632       }                                           635       }
633       else                                        636       else
634       {                                           637       {
635          distance[0] = DistanceToLine(pabsz, x    638          distance[0] = DistanceToLine(pabsz, xx1, (xx2 - xx1) , xx);
636       }                                           639       }
637                                                   640       
638    }                                              641    }
639    else if (prho < r1 - halftol)  // p is insi    642    else if (prho < r1 - halftol)  // p is inside of Hyperbolic surface.
640    {                                              643    {
641       // First point xx1                          644       // First point xx1
642       G4double t;                                 645       G4double t;
643       G4ThreeVector xx1;                          646       G4ThreeVector xx1;
644       if (prho < DBL_MIN)                         647       if (prho < DBL_MIN)
645       {                                           648       {
646          xx1.set(r1, 0. , pz);                    649          xx1.set(r1, 0. , pz);
647       }                                           650       }
648       else                                        651       else
649       {                                           652       {
650          t = r1 / prho;                           653          t = r1 / prho;
651          xx1.set(t * pabsz.x(), t * pabsz.y()     654          xx1.set(t * pabsz.x(), t * pabsz.y() , pz);
652       }                                           655       }
653                                                   656       
654       // dr, dz is tangential vector of Hyparb    657       // dr, dz is tangential vector of Hyparbolic surface at xx1
655       // dr = r, dz = z*tan2stereo                658       // dr = r, dz = z*tan2stereo
656       G4double dr  = pz * fTan2Stereo;            659       G4double dr  = pz * fTan2Stereo;
657       G4double dz  = r1;                          660       G4double dz  = r1;
658       G4double tanbeta   = dr / dz;               661       G4double tanbeta   = dr / dz;
659       G4double pztanbeta = pz * tanbeta;          662       G4double pztanbeta = pz * tanbeta;
660                                                   663       
661       // Second point xx2                         664       // Second point xx2 
662       // xx2 is intersection between x-axis an    665       // xx2 is intersection between x-axis and tangential vector
663       G4double r2 = r1 - pztanbeta;               666       G4double r2 = r1 - pztanbeta;
664       G4ThreeVector xx2;                          667       G4ThreeVector xx2;
665       if (prho < DBL_MIN)                         668       if (prho < DBL_MIN)
666       {                                           669       {
667          xx2.set(r2, 0. , 0.);                    670          xx2.set(r2, 0. , 0.);
668       }                                           671       }
669       else                                        672       else
670       {                                           673       {
671          t  = r2 / prho;                          674          t  = r2 / prho;
672          xx2.set(t * pabsz.x(), t * pabsz.y()     675          xx2.set(t * pabsz.x(), t * pabsz.y() , 0.);
673       }                                           676       }
674                                                   677       
675       G4ThreeVector d = xx2 - xx1;                678       G4ThreeVector d = xx2 - xx1;
676       distance[0] = DistanceToLine(pabsz, xx1,    679       distance[0] = DistanceToLine(pabsz, xx1, d, xx);
677                                                   680           
678    }                                              681    }
679    else   // p is on Hyperbolic surface.          682    else   // p is on Hyperbolic surface.
680    {                                              683    {
681       distance[0] = 0;                            684       distance[0] = 0;
682       xx.set(p.x(), p.y(), pz);                   685       xx.set(p.x(), p.y(), pz);
683    }                                              686    }
684                                                   687 
685    if (p.z() < 0)                                 688    if (p.z() < 0)
686    {                                              689    {
687       G4ThreeVector tmpxx(xx.x(), xx.y(), -xx.    690       G4ThreeVector tmpxx(xx.x(), xx.y(), -xx.z());
688       xx = tmpxx;                                 691       xx = tmpxx;
689    }                                              692    }
690                                                   693        
691    gxx[0] = ComputeGlobalPoint(xx);               694    gxx[0] = ComputeGlobalPoint(xx);
692    areacode[0]    = sInside;                      695    areacode[0]    = sInside;
693    G4bool isvalid = true;                         696    G4bool isvalid = true;
694    fCurStat.SetCurrentStatus(0, gxx[0], distan    697    fCurStat.SetCurrentStatus(0, gxx[0], distance[0], areacode[0],
695                              isvalid, 1, kDont    698                              isvalid, 1, kDontValidate, &gp);
696    return 1;                                      699    return 1;
697 }                                                 700 }
698                                                   701 
699 //============================================    702 //=====================================================================
700 //* GetAreaCode ------------------------------    703 //* GetAreaCode -------------------------------------------------------
701                                                   704 
702 G4int G4TwistTubsHypeSide::GetAreaCode(const G    705 G4int G4TwistTubsHypeSide::GetAreaCode(const G4ThreeVector& xx, 
703                                              G    706                                              G4bool         withTol)
704 {                                                 707 {
705    const G4double ctol = 0.5 * kCarTolerance;     708    const G4double ctol = 0.5 * kCarTolerance;
706    G4int areacode = sInside;                      709    G4int areacode = sInside;
707                                                   710 
708    if ((fAxis[0] == kPhi && fAxis[1] == kZAxis    711    if ((fAxis[0] == kPhi && fAxis[1] == kZAxis))
709    {                                              712    {
710       G4int zaxis   = 1;                          713       G4int zaxis   = 1;
711                                                   714       
712       if (withTol)                                715       if (withTol)
713       {                                           716       {
714          G4bool isoutside      = false;           717          G4bool isoutside      = false;
715          G4int  phiareacode    = GetAreaCodeIn    718          G4int  phiareacode    = GetAreaCodeInPhi(xx);
716          G4bool isoutsideinphi = IsOutside(phi    719          G4bool isoutsideinphi = IsOutside(phiareacode);
717                                                   720 
718          // test boundary of phiaxis              721          // test boundary of phiaxis
719                                                   722 
720          if ((phiareacode & sAxisMin) == sAxis    723          if ((phiareacode & sAxisMin) == sAxisMin)
721          {                                        724          {
722             areacode |= (sAxis0 & (sAxisPhi |     725             areacode |= (sAxis0 & (sAxisPhi | sAxisMin)) | sBoundary;
723             if (isoutsideinphi) isoutside = tr    726             if (isoutsideinphi) isoutside = true;
724          }                                        727          }
725          else if ((phiareacode & sAxisMax)  ==    728          else if ((phiareacode & sAxisMax)  == sAxisMax)
726          {                                        729          {
727             areacode |= (sAxis0 & (sAxisPhi |     730             areacode |= (sAxis0 & (sAxisPhi | sAxisMax)) | sBoundary;
728             if (isoutsideinphi) isoutside = tr    731             if (isoutsideinphi) isoutside = true;
729          }                                        732          }
730                                                   733 
731          // test boundary of zaxis                734          // test boundary of zaxis
732                                                   735 
733          if (xx.z() < fAxisMin[zaxis] + ctol)     736          if (xx.z() < fAxisMin[zaxis] + ctol)
734          {                                        737          {
735             areacode |= (sAxis1 & (sAxisZ | sA    738             areacode |= (sAxis1 & (sAxisZ | sAxisMin));
736             if   ((areacode & sBoundary) != 0) << 739             if   (areacode & sBoundary) areacode |= sCorner;  // xx is on corner.
737             else                        areaco    740             else                        areacode |= sBoundary;
738                                                   741 
739             if (xx.z() <= fAxisMin[zaxis] - ct    742             if (xx.z() <= fAxisMin[zaxis] - ctol) isoutside = true;
740                                                   743 
741          }                                        744          }
742          else if (xx.z() > fAxisMax[zaxis] - c    745          else if (xx.z() > fAxisMax[zaxis] - ctol)
743          {                                        746          {
744             areacode |= (sAxis1 & (sAxisZ | sA    747             areacode |= (sAxis1 & (sAxisZ | sAxisMax));
745             if   ((areacode & sBoundary) != 0) << 748             if   (areacode & sBoundary) areacode |= sCorner;  // xx is on corner.
746             else                        areaco    749             else                        areacode |= sBoundary;
747                                                   750 
748             if (xx.z() >= fAxisMax[zaxis] + ct    751             if (xx.z() >= fAxisMax[zaxis] + ctol) isoutside = true;
749          }                                        752          }
750                                                   753 
751          // if isoutside = true, clear sInside    754          // if isoutside = true, clear sInside bit.
752          // if not on boundary, add boundary i    755          // if not on boundary, add boundary information. 
753                                                   756 
754          if (isoutside)                           757          if (isoutside)
755          {                                        758          {
756             G4int tmpareacode = areacode & (~s    759             G4int tmpareacode = areacode & (~sInside);
757             areacode = tmpareacode;               760             areacode = tmpareacode;
758          }                                        761          }
759          else if ((areacode & sBoundary) != sB    762          else if ((areacode & sBoundary) != sBoundary)
760          {                                        763          {
761             areacode |= (sAxis0 & sAxisPhi) |     764             areacode |= (sAxis0 & sAxisPhi) | (sAxis1 & sAxisZ);
762          }                                        765          }
763                                                   766 
764          return areacode;                         767          return areacode;
765       }                                           768       }
766       else                                        769       else
767       {                                           770       {
768          G4int phiareacode = GetAreaCodeInPhi(    771          G4int phiareacode = GetAreaCodeInPhi(xx, false);
769                                                   772          
770          // test boundary of z-axis               773          // test boundary of z-axis
771                                                   774 
772          if (xx.z() < fAxisMin[zaxis])            775          if (xx.z() < fAxisMin[zaxis])
773          {                                        776          {
774             areacode |= (sAxis1 & (sAxisZ | sA    777             areacode |= (sAxis1 & (sAxisZ | sAxisMin)) | sBoundary;
775                                                   778 
776          }                                        779          }
777          else if (xx.z() > fAxisMax[zaxis])       780          else if (xx.z() > fAxisMax[zaxis])
778          {                                        781          {
779             areacode |= (sAxis1 & (sAxisZ | sA    782             areacode |= (sAxis1 & (sAxisZ | sAxisMax)) | sBoundary;
780          }                                        783          }
781                                                   784 
782          // boundary of phi-axis                  785          // boundary of phi-axis
783                                                   786 
784          if (phiareacode == sAxisMin)             787          if (phiareacode == sAxisMin)
785          {                                        788          {
786             areacode |= (sAxis0 & (sAxisPhi |     789             areacode |= (sAxis0 & (sAxisPhi | sAxisMin));
787             if   ((areacode & sBoundary) != 0) << 790             if   (areacode & sBoundary) areacode |= sCorner;  // xx is on corner.
788             else                        areaco    791             else                        areacode |= sBoundary; 
789                                                   792              
790          }                                        793          }
791          else if (phiareacode == sAxisMax)        794          else if (phiareacode == sAxisMax)
792          {                                        795          {
793             areacode |= (sAxis0 & (sAxisPhi |     796             areacode |= (sAxis0 & (sAxisPhi | sAxisMax));
794             if   ((areacode & sBoundary) != 0) << 797             if   (areacode & sBoundary) areacode |= sCorner;  // xx is on corner.
795             else                        areaco    798             else                        areacode |= sBoundary;
796          }                                        799          }
797                                                   800 
798          // if not on boundary, add boundary i    801          // if not on boundary, add boundary information. 
799                                                   802 
800          if ((areacode & sBoundary) != sBounda    803          if ((areacode & sBoundary) != sBoundary)
801          {                                        804          {
802             areacode |= (sAxis0 & sAxisPhi) |     805             areacode |= (sAxis0 & sAxisPhi) | (sAxis1 & sAxisZ);
803          }                                        806          }
804          return areacode;                         807          return areacode;
805       }                                           808       }
806    }                                              809    }
807    else                                           810    else
808    {                                              811    {
809       std::ostringstream message;                 812       std::ostringstream message;
810       message << "Feature NOT implemented !" <    813       message << "Feature NOT implemented !" << G4endl
811               << "        fAxis[0] = " << fAxi    814               << "        fAxis[0] = " << fAxis[0] << G4endl
812               << "        fAxis[1] = " << fAxi    815               << "        fAxis[1] = " << fAxis[1];
813       G4Exception("G4TwistTubsHypeSide::GetAre    816       G4Exception("G4TwistTubsHypeSide::GetAreaCode()",
814                   "GeomSolids0001", FatalExcep    817                   "GeomSolids0001", FatalException, message);
815    }                                              818    }
816    return areacode;                               819    return areacode;
817 }                                                 820 }
818                                                   821 
819 //============================================    822 //=====================================================================
820 //* GetAreaCodeInPhi -------------------------    823 //* GetAreaCodeInPhi --------------------------------------------------
821                                                   824 
822 G4int G4TwistTubsHypeSide::GetAreaCodeInPhi(co    825 G4int G4TwistTubsHypeSide::GetAreaCodeInPhi(const G4ThreeVector& xx,
823                                                   826                                                   G4bool withTol)
824 {                                                 827 {
825                                                   828    
826    G4ThreeVector lowerlimit; // lower phi-boun    829    G4ThreeVector lowerlimit; // lower phi-boundary limit at z = xx.z()
827    G4ThreeVector upperlimit; // upper phi-boun    830    G4ThreeVector upperlimit; // upper phi-boundary limit at z = xx.z()
828    lowerlimit = GetBoundaryAtPZ(sAxis0 & sAxis    831    lowerlimit = GetBoundaryAtPZ(sAxis0 & sAxisMin, xx);
829    upperlimit = GetBoundaryAtPZ(sAxis0 & sAxis    832    upperlimit = GetBoundaryAtPZ(sAxis0 & sAxisMax, xx);
830                                                   833 
831    G4int  areacode  = sInside;                    834    G4int  areacode  = sInside;
832    G4bool isoutside = false;                      835    G4bool isoutside = false; 
833                                                   836    
834    if (withTol)                                   837    if (withTol)
835    {                                              838    {
836       if (AmIOnLeftSide(xx, lowerlimit) >= 0)     839       if (AmIOnLeftSide(xx, lowerlimit) >= 0)       // xx is on lowerlimit
837       {                                           840       {
838          areacode |= (sAxisMin | sBoundary);      841          areacode |= (sAxisMin | sBoundary);
839          if (AmIOnLeftSide(xx, lowerlimit) > 0    842          if (AmIOnLeftSide(xx, lowerlimit) > 0) isoutside = true; 
840                                                   843 
841       }                                           844       }
842       else if (AmIOnLeftSide(xx, upperlimit) <    845       else if (AmIOnLeftSide(xx, upperlimit) <= 0)  // xx is on upperlimit
843       {                                           846       {
844          areacode |= (sAxisMax | sBoundary);      847          areacode |= (sAxisMax | sBoundary);
845          if (AmIOnLeftSide(xx, upperlimit) < 0    848          if (AmIOnLeftSide(xx, upperlimit) < 0) isoutside = true; 
846       }                                           849       }
847                                                   850 
848       // if isoutside = true, clear inside bit    851       // if isoutside = true, clear inside bit.
849                                                   852 
850       if (isoutside)                              853       if (isoutside)
851       {                                           854       {
852          G4int tmpareacode = areacode & (~sIns    855          G4int tmpareacode = areacode & (~sInside);
853          areacode = tmpareacode;                  856          areacode = tmpareacode;
854       }                                           857       }
855    }                                              858    }
856    else                                           859    else
857    {                                              860    {
858       if (AmIOnLeftSide(xx, lowerlimit, false)    861       if (AmIOnLeftSide(xx, lowerlimit, false) >= 0)
859       {                                           862       {
860          areacode |= (sAxisMin | sBoundary);      863          areacode |= (sAxisMin | sBoundary);
861       }                                           864       }
862       else if (AmIOnLeftSide(xx, upperlimit, f    865       else if (AmIOnLeftSide(xx, upperlimit, false) <= 0)
863       {                                           866       {
864          areacode |= (sAxisMax | sBoundary);      867          areacode |= (sAxisMax | sBoundary);
865       }                                           868       }
866    }                                              869    }
867                                                   870 
868    return areacode;                               871    return areacode;
869 }                                                 872 }
870                                                   873 
871 //============================================    874 //=====================================================================
872 //* SetCorners(EndInnerRadius, EndOuterRadius,    875 //* SetCorners(EndInnerRadius, EndOuterRadius,DPhi,EndPhi,EndZ) -------
873                                                   876 
874 void G4TwistTubsHypeSide::SetCorners( G4double    877 void G4TwistTubsHypeSide::SetCorners( G4double         EndInnerRadius[2],
875                                       G4double    878                                       G4double         EndOuterRadius[2],
876                                       G4double    879                                       G4double         DPhi,
877                                       G4double    880                                       G4double         endPhi[2],
878                                       G4double    881                                       G4double         endZ[2] )
879 {                                                 882 {
880    // Set Corner points in local coodinate.       883    // Set Corner points in local coodinate.
881                                                   884 
882    if (fAxis[0] == kPhi && fAxis[1] == kZAxis)    885    if (fAxis[0] == kPhi && fAxis[1] == kZAxis) {
883                                                   886 
884       G4double endRad[2];                         887       G4double endRad[2];
885       G4double halfdphi = 0.5*DPhi;               888       G4double halfdphi = 0.5*DPhi;
886                                                   889       
887       for (auto i=0; i<2; ++i) // i=0,1 : -ve     890       for (auto i=0; i<2; ++i) // i=0,1 : -ve z, +ve z
888       {                                           891       {
889         endRad[i] = (fHandedness == 1 ? EndOut    892         endRad[i] = (fHandedness == 1 ? EndOuterRadius[i] : EndInnerRadius[i]);
890       }                                           893       }
891                                                   894 
892       G4int zmin = 0 ;  // at -ve z               895       G4int zmin = 0 ;  // at -ve z
893       G4int zmax = 1 ;  // at +ve z               896       G4int zmax = 1 ;  // at +ve z
894                                                   897 
895       G4double x, y, z;                           898       G4double x, y, z;
896                                                   899       
897       // corner of Axis0min and Axis1min          900       // corner of Axis0min and Axis1min
898       x = endRad[zmin]*std::cos(endPhi[zmin] -    901       x = endRad[zmin]*std::cos(endPhi[zmin] - halfdphi);
899       y = endRad[zmin]*std::sin(endPhi[zmin] -    902       y = endRad[zmin]*std::sin(endPhi[zmin] - halfdphi);
900       z = endZ[zmin];                             903       z = endZ[zmin];
901       SetCorner(sC0Min1Min, x, y, z);             904       SetCorner(sC0Min1Min, x, y, z);
902                                                   905       
903       // corner of Axis0max and Axis1min          906       // corner of Axis0max and Axis1min
904       x = endRad[zmin]*std::cos(endPhi[zmin] +    907       x = endRad[zmin]*std::cos(endPhi[zmin] + halfdphi);
905       y = endRad[zmin]*std::sin(endPhi[zmin] +    908       y = endRad[zmin]*std::sin(endPhi[zmin] + halfdphi);
906       z = endZ[zmin];                             909       z = endZ[zmin];
907       SetCorner(sC0Max1Min, x, y, z);             910       SetCorner(sC0Max1Min, x, y, z);
908                                                   911       
909       // corner of Axis0max and Axis1max          912       // corner of Axis0max and Axis1max
910       x = endRad[zmax]*std::cos(endPhi[zmax] +    913       x = endRad[zmax]*std::cos(endPhi[zmax] + halfdphi);
911       y = endRad[zmax]*std::sin(endPhi[zmax] +    914       y = endRad[zmax]*std::sin(endPhi[zmax] + halfdphi);
912       z = endZ[zmax];                             915       z = endZ[zmax];
913       SetCorner(sC0Max1Max, x, y, z);             916       SetCorner(sC0Max1Max, x, y, z);
914                                                   917       
915       // corner of Axis0min and Axis1max          918       // corner of Axis0min and Axis1max
916       x = endRad[zmax]*std::cos(endPhi[zmax] -    919       x = endRad[zmax]*std::cos(endPhi[zmax] - halfdphi);
917       y = endRad[zmax]*std::sin(endPhi[zmax] -    920       y = endRad[zmax]*std::sin(endPhi[zmax] - halfdphi);
918       z = endZ[zmax];                             921       z = endZ[zmax];
919       SetCorner(sC0Min1Max, x, y, z);             922       SetCorner(sC0Min1Max, x, y, z);
920                                                   923 
921    }                                              924    }
922    else                                           925    else
923    {                                              926    {
924       std::ostringstream message;                 927       std::ostringstream message;
925       message << "Feature NOT implemented !" <    928       message << "Feature NOT implemented !" << G4endl
926               << "        fAxis[0] = " << fAxi    929               << "        fAxis[0] = " << fAxis[0] << G4endl
927               << "        fAxis[1] = " << fAxi    930               << "        fAxis[1] = " << fAxis[1];
928       G4Exception("G4TwistTubsHypeSide::SetCor    931       G4Exception("G4TwistTubsHypeSide::SetCorners()",
929                   "GeomSolids0001", FatalExcep    932                   "GeomSolids0001", FatalException, message);
930    }                                              933    }
931 }                                                 934 }
932                                                   935 
933 //============================================    936 //=====================================================================
934 //* SetCorners() -----------------------------    937 //* SetCorners() ------------------------------------------------------
935                                                   938 
936 void G4TwistTubsHypeSide::SetCorners()            939 void G4TwistTubsHypeSide::SetCorners()
937 {                                                 940 {
938    G4Exception("G4TwistTubsHypeSide::SetCorner    941    G4Exception("G4TwistTubsHypeSide::SetCorners()",
939                "GeomSolids0001", FatalExceptio    942                "GeomSolids0001", FatalException,
940                "Method NOT implemented !");       943                "Method NOT implemented !");
941 }                                                 944 }
942                                                   945 
943 //============================================    946 //=====================================================================
944 //* SetBoundaries() --------------------------    947 //* SetBoundaries() ---------------------------------------------------
945                                                   948 
946 void G4TwistTubsHypeSide::SetBoundaries()         949 void G4TwistTubsHypeSide::SetBoundaries()
947 {                                                 950 {
948    // Set direction-unit vector of phi-boundar    951    // Set direction-unit vector of phi-boundary-lines in local coodinate.
949    // sAxis0 must be kPhi.                        952    // sAxis0 must be kPhi.
950    // This fanction set lower phi-boundary and    953    // This fanction set lower phi-boundary and upper phi-boundary.
951                                                   954 
952    if (fAxis[0] == kPhi && fAxis[1] == kZAxis)    955    if (fAxis[0] == kPhi && fAxis[1] == kZAxis)
953    {                                              956    {
954       G4ThreeVector direction;                    957       G4ThreeVector direction;
955       // sAxis0 & sAxisMin                        958       // sAxis0 & sAxisMin
956       direction = GetCorner(sC0Min1Max) - GetC    959       direction = GetCorner(sC0Min1Max) - GetCorner(sC0Min1Min);
957       direction = direction.unit();               960       direction = direction.unit();
958       SetBoundary(sAxis0 & (sAxisPhi | sAxisMi    961       SetBoundary(sAxis0 & (sAxisPhi | sAxisMin), direction, 
959                    GetCorner(sC0Min1Min), sAxi    962                    GetCorner(sC0Min1Min), sAxisZ);
960                                                   963 
961       // sAxis0 & sAxisMax                        964       // sAxis0 & sAxisMax
962       direction = GetCorner(sC0Max1Max) - GetC    965       direction = GetCorner(sC0Max1Max) - GetCorner(sC0Max1Min);
963       direction = direction.unit();               966       direction = direction.unit();
964       SetBoundary(sAxis0 & (sAxisPhi | sAxisMa    967       SetBoundary(sAxis0 & (sAxisPhi | sAxisMax), direction, 
965                   GetCorner(sC0Max1Min), sAxis    968                   GetCorner(sC0Max1Min), sAxisZ);
966                                                   969 
967       // sAxis1 & sAxisMin                        970       // sAxis1 & sAxisMin
968       direction = GetCorner(sC0Max1Min) - GetC    971       direction = GetCorner(sC0Max1Min) - GetCorner(sC0Min1Min);
969       direction = direction.unit();               972       direction = direction.unit();
970       SetBoundary(sAxis1 & (sAxisZ | sAxisMin)    973       SetBoundary(sAxis1 & (sAxisZ | sAxisMin), direction, 
971                    GetCorner(sC0Min1Min), sAxi    974                    GetCorner(sC0Min1Min), sAxisPhi);
972                                                   975 
973       // sAxis1 & sAxisMax                        976       // sAxis1 & sAxisMax
974       direction = GetCorner(sC0Max1Max) - GetC    977       direction = GetCorner(sC0Max1Max) - GetCorner(sC0Min1Max);
975       direction = direction.unit();               978       direction = direction.unit();
976       SetBoundary(sAxis1 & (sAxisZ | sAxisMax)    979       SetBoundary(sAxis1 & (sAxisZ | sAxisMax), direction, 
977                   GetCorner(sC0Min1Max), sAxis    980                   GetCorner(sC0Min1Max), sAxisPhi);
978    }                                              981    }
979    else                                           982    else
980    {                                              983    {
981       std::ostringstream message;                 984       std::ostringstream message;
982       message << "Feature NOT implemented !" <    985       message << "Feature NOT implemented !" << G4endl
983               << "        fAxis[0] = " << fAxi    986               << "        fAxis[0] = " << fAxis[0] << G4endl
984               << "        fAxis[1] = " << fAxi    987               << "        fAxis[1] = " << fAxis[1];
985       G4Exception("G4TwistTubsHypeSide::SetBou    988       G4Exception("G4TwistTubsHypeSide::SetBoundaries()",
986                   "GeomSolids0001", FatalExcep    989                   "GeomSolids0001", FatalException, message);
987    }                                              990    }
988 }                                                 991 }
989                                                   992 
990 //============================================    993 //=====================================================================
991 //* GetFacets() ------------------------------    994 //* GetFacets() -------------------------------------------------------
992                                                   995 
993 void G4TwistTubsHypeSide::GetFacets( G4int k,     996 void G4TwistTubsHypeSide::GetFacets( G4int k, G4int n, G4double xyz[][3],
994                                      G4int fac    997                                      G4int faces[][4], G4int iside ) 
995 {                                                 998 {
996   G4double z ;     // the two parameters for t    999   G4double z ;     // the two parameters for the surface equation
997   G4double x,xmin,xmax ;                          1000   G4double x,xmin,xmax ;
998                                                   1001 
999   G4ThreeVector p ;  // a point on the surface    1002   G4ThreeVector p ;  // a point on the surface, given by (z,u)
1000                                                  1003 
1001   G4int nnode ;                                  1004   G4int nnode ;
1002   G4int nface ;                                  1005   G4int nface ;
1003                                                  1006 
1004   // calculate the (n-1)*(k-1) vertices          1007   // calculate the (n-1)*(k-1) vertices
1005                                                  1008 
1006   for ( G4int i = 0 ; i<n ; ++i )                1009   for ( G4int i = 0 ; i<n ; ++i )
1007   {                                              1010   {
1008     z = fAxisMin[1] + i*(fAxisMax[1]-fAxisMin    1011     z = fAxisMin[1] + i*(fAxisMax[1]-fAxisMin[1])/(n-1) ;
1009                                                  1012 
1010     for ( G4int j = 0 ; j<k ; ++j )              1013     for ( G4int j = 0 ; j<k ; ++j )
1011     {                                            1014     {
1012       nnode = GetNode(i,j,k,n,iside) ;           1015       nnode = GetNode(i,j,k,n,iside) ;
1013                                                  1016 
1014       xmin = GetBoundaryMin(z) ;                 1017       xmin = GetBoundaryMin(z) ; 
1015       xmax = GetBoundaryMax(z) ;                 1018       xmax = GetBoundaryMax(z) ;
1016                                                  1019 
1017       if (fHandedness < 0)  // inner hyperbol    1020       if (fHandedness < 0)  // inner hyperbolic surface
1018       {                                          1021       {
1019         x = xmin + j*(xmax-xmin)/(k-1) ;         1022         x = xmin + j*(xmax-xmin)/(k-1) ;
1020       }                                          1023       }
1021       else                  // outer hyperbol    1024       else                  // outer hyperbolic surface
1022       {                                          1025       {
1023         x = xmax - j*(xmax-xmin)/(k-1) ;         1026         x = xmax - j*(xmax-xmin)/(k-1) ;
1024       }                                          1027       }
1025                                                  1028 
1026       p = SurfacePoint(x,z,true) ;  // surfac    1029       p = SurfacePoint(x,z,true) ;  // surface point in global coord.system
1027                                                  1030 
1028       xyz[nnode][0] = p.x() ;                    1031       xyz[nnode][0] = p.x() ;
1029       xyz[nnode][1] = p.y() ;                    1032       xyz[nnode][1] = p.y() ;
1030       xyz[nnode][2] = p.z() ;                    1033       xyz[nnode][2] = p.z() ;
1031                                                  1034 
1032       if ( i<n-1 && j<k-1 )    // clock wise     1035       if ( i<n-1 && j<k-1 )    // clock wise filling
1033       {                                          1036       {
1034         nface = GetFace(i,j,k,n,iside) ;         1037         nface = GetFace(i,j,k,n,iside) ;
1035   faces[nface][0] = GetEdgeVisibility(i,j,k,n    1038   faces[nface][0] = GetEdgeVisibility(i,j,k,n,0,1)
1036                         * ( GetNode(i  ,j  ,k    1039                         * ( GetNode(i  ,j  ,k,n,iside)+1) ;  
1037   faces[nface][1] = GetEdgeVisibility(i,j,k,n    1040   faces[nface][1] = GetEdgeVisibility(i,j,k,n,1,1)
1038                         * ( GetNode(i+1,j  ,k    1041                         * ( GetNode(i+1,j  ,k,n,iside)+1) ;
1039   faces[nface][2] = GetEdgeVisibility(i,j,k,n    1042   faces[nface][2] = GetEdgeVisibility(i,j,k,n,2,1)
1040                         * ( GetNode(i+1,j+1,k    1043                         * ( GetNode(i+1,j+1,k,n,iside)+1) ;
1041   faces[nface][3] = GetEdgeVisibility(i,j,k,n    1044   faces[nface][3] = GetEdgeVisibility(i,j,k,n,3,1)
1042                         * ( GetNode(i  ,j+1,k    1045                         * ( GetNode(i  ,j+1,k,n,iside)+1) ;
1043       }                                          1046       }
1044     }                                            1047     }
1045   }                                              1048   }
1046 }                                                1049 }
1047                                                  1050