G4TwistTubsHypeSide Class Reference

#include <G4TwistTubsHypeSide.hh>

Inheritance diagram for G4TwistTubsHypeSide:

G4VTwistSurface

Public Member Functions

 G4TwistTubsHypeSide (const G4String &name, const G4RotationMatrix &rot, const G4ThreeVector &tlate, const G4int handedness, const G4double kappa, const G4double tanstereo, const G4double r0, const EAxis axis0=kPhi, const EAxis axis1=kZAxis, G4double axis0min=-kInfinity, G4double axis1min=-kInfinity, G4double axis0max=kInfinity, G4double axis1max=kInfinity)
 G4TwistTubsHypeSide (const G4String &name, G4double EndInnerRadius[2], G4double EndOuterRadius[2], G4double DPhi, G4double EndPhi[2], G4double EndZ[2], G4double InnerRadius, G4double OuterRadius, G4double Kappa, G4double TanInnerStereo, G4double TanOuterStereo, G4int handedness)
virtual ~G4TwistTubsHypeSide ()
virtual G4int DistanceToSurface (const G4ThreeVector &gp, const G4ThreeVector &gv, G4ThreeVector gxx[], G4double distance[], G4int areacode[], G4bool isvalid[], EValidate validate=kValidateWithTol)
virtual G4int DistanceToSurface (const G4ThreeVector &gp, G4ThreeVector gxx[], G4double distance[], G4int areacode[])
virtual G4ThreeVector GetNormal (const G4ThreeVector &xx, G4bool isGlobal=false)
virtual EInside Inside (const G4ThreeVector &gp)
virtual G4double GetRhoAtPZ (const G4ThreeVector &p, G4bool isglobal=false) const
virtual G4ThreeVector SurfacePoint (G4double, G4double, G4bool isGlobal=false)
virtual G4double GetBoundaryMin (G4double phi)
virtual G4double GetBoundaryMax (G4double phi)
virtual G4double GetSurfaceArea ()
virtual void GetFacets (G4int m, G4int n, G4double xyz[][3], G4int faces[][4], G4int iside)
 G4TwistTubsHypeSide (__void__ &)

Data Structures

class  Insidetype

Detailed Description

Definition at line 54 of file G4TwistTubsHypeSide.hh.


Constructor & Destructor Documentation

G4TwistTubsHypeSide::G4TwistTubsHypeSide ( const G4String name,
const G4RotationMatrix rot,
const G4ThreeVector tlate,
const G4int  handedness,
const G4double  kappa,
const G4double  tanstereo,
const G4double  r0,
const EAxis  axis0 = kPhi,
const EAxis  axis1 = kZAxis,
G4double  axis0min = -kInfinity,
G4double  axis1min = -kInfinity,
G4double  axis0max = kInfinity,
G4double  axis1max = kInfinity 
)

Definition at line 51 of file G4TwistTubsHypeSide.cc.

References FatalErrorInArgument, G4VTwistSurface::fIsValidNorm, G4Exception(), kOutside, kPhi, and kZAxis.

00064   : G4VTwistSurface(name, rot, tlate, handedness, axis0, axis1,
00065                    axis0min, axis1min, axis0max, axis1max),
00066     fKappa(kappa), fTanStereo(tanstereo),
00067     fTan2Stereo(tanstereo*tanstereo), fR0(r0), fR02(r0*r0), fDPhi(twopi)
00068 {
00069    if ( (axis0 == kZAxis) && (axis1 == kPhi) )
00070    {
00071       G4Exception("G4TwistTubsHypeSide::G4TwistTubsHypeSide()",
00072                   "GeomSolids0002", FatalErrorInArgument,
00073                   "Should swap axis0 and axis1!");
00074    }
00075    
00076    fInside.gp.set(kInfinity, kInfinity, kInfinity);
00077    fInside.inside = kOutside;
00078    fIsValidNorm = false;
00079    
00080    SetCorners();
00081    SetBoundaries();
00082 
00083 }

G4TwistTubsHypeSide::G4TwistTubsHypeSide ( const G4String name,
G4double  EndInnerRadius[2],
G4double  EndOuterRadius[2],
G4double  DPhi,
G4double  EndPhi[2],
G4double  EndZ[2],
G4double  InnerRadius,
G4double  OuterRadius,
G4double  Kappa,
G4double  TanInnerStereo,
G4double  TanOuterStereo,
G4int  handedness 
)

Definition at line 85 of file G4TwistTubsHypeSide.cc.

References G4VTwistSurface::fAxis, G4VTwistSurface::fAxisMax, G4VTwistSurface::fAxisMin, G4VTwistSurface::fHandedness, G4VTwistSurface::fIsValidNorm, G4VTwistSurface::fTrans, kOutside, kPhi, and kZAxis.

00097    : G4VTwistSurface(name)
00098 {
00099 
00100    fHandedness = handedness;   // +z = +ve, -z = -ve
00101    fAxis[0]    = kPhi;
00102    fAxis[1]    = kZAxis;
00103    fAxisMin[0] = kInfinity;         // we cannot fix boundary min of Phi, 
00104    fAxisMax[0] = kInfinity;         // because it depends on z.
00105    fAxisMin[1] = EndZ[0];
00106    fAxisMax[1] = EndZ[1];
00107    fKappa      = Kappa;
00108    fDPhi       = DPhi ;
00109 
00110    if (handedness < 0) { // inner hyperbolic surface
00111       fTanStereo  = TanInnerStereo;
00112       fR0         = InnerRadius;
00113    } else {              // outer hyperbolic surface
00114       fTanStereo  = TanOuterStereo;
00115       fR0         = OuterRadius;
00116    }
00117    fTan2Stereo = fTanStereo * fTanStereo;
00118    fR02        = fR0 * fR0;
00119    
00120    fTrans.set(0, 0, 0);
00121    fIsValidNorm = false;
00122 
00123    fInside.gp.set(kInfinity, kInfinity, kInfinity);
00124    fInside.inside = kOutside;
00125    
00126    SetCorners(EndInnerRadius, EndOuterRadius, DPhi, EndPhi, EndZ) ; 
00127 
00128    SetBoundaries();
00129 }

G4TwistTubsHypeSide::~G4TwistTubsHypeSide (  )  [virtual]

Definition at line 143 of file G4TwistTubsHypeSide.cc.

00144 {
00145 }

G4TwistTubsHypeSide::G4TwistTubsHypeSide ( __void__ &   ) 

Definition at line 134 of file G4TwistTubsHypeSide.cc.

00135   : G4VTwistSurface(a), fKappa(0.), fTanStereo(0.), fTan2Stereo(0.),
00136     fR0(0.), fR02(0.), fDPhi(0.)
00137 {
00138 }


Member Function Documentation

G4int G4TwistTubsHypeSide::DistanceToSurface ( const G4ThreeVector gp,
G4ThreeVector  gxx[],
G4double  distance[],
G4int  areacode[] 
) [virtual]

Implements G4VTwistSurface.

Definition at line 501 of file G4TwistTubsHypeSide.cc.

References G4VTwistSurface::ComputeGlobalPoint(), G4VTwistSurface::ComputeLocalPoint(), DBL_MIN, G4VTwistSurface::DistanceToLine(), G4VTwistSurface::fCurStat, G4VTwistSurface::fCurStatWithV, G4GeometryTolerance::GetInstance(), G4GeometryTolerance::GetRadialTolerance(), G4VTwistSurface::kDontValidate, G4VTwistSurface::sInside, and G4VTwistSurface::sOutside.

00505 {
00506     // Find the approximate distance of a point of a hyperbolic surface.
00507     // The distance must be an underestimate. 
00508     // It will also be nice (although not necessary) that the estimate is
00509     // always finite no matter how close the point is.
00510     //
00511     // We arranged G4Hype::ApproxDistOutside and G4Hype::ApproxDistInside
00512     // for this function. See these discriptions.
00513     
00514    static const G4double halftol
00515      = 0.5 * G4GeometryTolerance::GetInstance()->GetRadialTolerance();
00516 
00517    fCurStat.ResetfDone(kDontValidate, &gp);
00518 
00519    if (fCurStat.IsDone()) {
00520       for (G4int i=0; i<fCurStat.GetNXX(); i++) {
00521          gxx[i] = fCurStat.GetXX(i);
00522          distance[i] = fCurStat.GetDistance(i);
00523          areacode[i] = fCurStat.GetAreacode(i);
00524       }
00525       return fCurStat.GetNXX();
00526    } else {
00527       // initialize
00528       for (G4int i=0; i<2; i++) {
00529          distance[i] = kInfinity;
00530          areacode[i] = sOutside;
00531          gxx[i].set(kInfinity, kInfinity, kInfinity);
00532       }
00533    }
00534    
00535 
00536    G4ThreeVector p = ComputeLocalPoint(gp);
00537    G4ThreeVector xx;
00538 
00539    //
00540    // special case!
00541    // If p is on surface, return distance = 0 immediatery .
00542    //
00543    G4ThreeVector  lastgxx[2];
00544    for (G4int i=0; i<2; i++) {
00545       lastgxx[i] = fCurStatWithV.GetXX(i);
00546    }
00547 
00548    if ((gp - lastgxx[0]).mag() < halftol || (gp - lastgxx[1]).mag() < halftol) {
00549       // last winner, or last poststep point is on the surface.
00550       xx = p;             
00551       gxx[0] = gp;
00552       distance[0] = 0;      
00553 
00554       G4bool isvalid = true;
00555       fCurStat.SetCurrentStatus(0, gxx[0], distance[0], areacode[0],
00556                                 isvalid, 1, kDontValidate, &gp);
00557 
00558       return 1;
00559 
00560    }
00561    //
00562    // special case end
00563    //
00564        
00565    G4double prho       = p.getRho();
00566    G4double pz         = std::fabs(p.z());           // use symmetry
00567    G4double r1         = std::sqrt(fR02 + pz * pz * fTan2Stereo);
00568    
00569    G4ThreeVector pabsz(p.x(), p.y(), pz);
00570     
00571    if (prho > r1 + halftol) {  // p is outside of Hyperbolic surface
00572 
00573       // First point xx1
00574       G4double t = r1 / prho;
00575       G4ThreeVector xx1(t * pabsz.x(), t * pabsz.y() , pz);
00576       
00577       // Second point xx2
00578       G4double z2 = (prho * fTanStereo + pz) / (1 + fTan2Stereo);
00579       G4double r2 = std::sqrt(fR02 + z2 * z2 * fTan2Stereo);
00580       t = r2 / prho;
00581       G4ThreeVector xx2(t * pabsz.x(), t * pabsz.y() , z2);
00582             
00583       G4double len = (xx2 - xx1).mag();
00584       if (len < DBL_MIN) {
00585          // xx2 = xx1?? I guess we
00586          // must have really bracketed the normal
00587          distance[0] = (pabsz - xx1).mag();
00588          xx = xx1;
00589       } else {
00590          distance[0] = DistanceToLine(pabsz, xx1, (xx2 - xx1) , xx);
00591       }
00592       
00593    } else if (prho < r1 - halftol) { // p is inside of Hyperbolic surface.
00594            
00595       // First point xx1
00596       G4double t;
00597       G4ThreeVector xx1;
00598       if (prho < DBL_MIN) {
00599          xx1.set(r1, 0. , pz);
00600       } else {
00601          t = r1 / prho;
00602          xx1.set(t * pabsz.x(), t * pabsz.y() , pz);
00603       }
00604       
00605       // dr, dz is tangential vector of Hyparbolic surface at xx1
00606       // dr = r, dz = z*tan2stereo
00607       G4double dr  = pz * fTan2Stereo;
00608       G4double dz  = r1;
00609       G4double tanbeta   = dr / dz;
00610       G4double pztanbeta = pz * tanbeta;
00611       
00612       // Second point xx2 
00613       // xx2 is intersection between x-axis and tangential vector
00614       G4double r2 = r1 - pztanbeta;
00615       G4ThreeVector xx2;
00616       if (prho < DBL_MIN) {
00617          xx2.set(r2, 0. , 0.);
00618       } else {
00619          t  = r2 / prho;
00620          xx2.set(t * pabsz.x(), t * pabsz.y() , 0.);
00621       }
00622       
00623       G4ThreeVector d = xx2 - xx1;
00624       distance[0] = DistanceToLine(pabsz, xx1, d, xx);
00625           
00626    } else {  // p is on Hyperbolic surface.
00627    
00628       distance[0] = 0;
00629       xx.set(p.x(), p.y(), pz);
00630 
00631    }
00632 
00633    if (p.z() < 0) {
00634       G4ThreeVector tmpxx(xx.x(), xx.y(), -xx.z());
00635       xx = tmpxx;
00636    }
00637        
00638    gxx[0] = ComputeGlobalPoint(xx);
00639    areacode[0]    = sInside;
00640    G4bool isvalid = true;
00641    fCurStat.SetCurrentStatus(0, gxx[0], distance[0], areacode[0],
00642                              isvalid, 1, kDontValidate, &gp);
00643    return 1;
00644 }

G4int G4TwistTubsHypeSide::DistanceToSurface ( const G4ThreeVector gp,
const G4ThreeVector gv,
G4ThreeVector  gxx[],
G4double  distance[],
G4int  areacode[],
G4bool  isvalid[],
EValidate  validate = kValidateWithTol 
) [virtual]

Definition at line 243 of file G4TwistTubsHypeSide.cc.

References G4VTwistSurface::ComputeGlobalPoint(), G4VTwistSurface::ComputeLocalDirection(), G4VTwistSurface::ComputeLocalPoint(), DBL_MIN, G4VTwistSurface::fCurStatWithV, G4VTwistSurface::IsInside(), G4VTwistSurface::IsOutside(), G4VTwistSurface::kValidateWithoutTol, G4VTwistSurface::kValidateWithTol, G4VTwistSurface::sInside, and G4VTwistSurface::sOutside.

00250 {
00251    //
00252    // Decide if and where a line intersects with a hyperbolic
00253    // surface (of infinite extent)
00254    //
00255    // Arguments:
00256    //     p       - (in) Point on trajectory
00257    //     v       - (in) Vector along trajectory
00258    //     r2      - (in) Square of radius at z = 0
00259    //     tan2phi - (in) std::tan(stereo)**2
00260    //     s       - (out) Up to two points of intersection, where the
00261    //                     intersection point is p + s*v, and if there are
00262    //                     two intersections, s[0] < s[1]. May be negative.
00263    // Returns:
00264    //     The number of intersections. If 0, the trajectory misses.
00265    //
00266    //
00267    // Equation of a line:
00268    //
00269    //       x = x0 + s*tx      y = y0 + s*ty      z = z0 + s*tz
00270    //
00271    // Equation of a hyperbolic surface:
00272    //
00273    //       x**2 + y**2 = r**2 + (z*tanPhi)**2
00274    //
00275    // Solution is quadratic:
00276    //
00277    //  a*s**2 + b*s + c = 0
00278    //
00279    // where:
00280    //
00281    //  a = tx**2 + ty**2 - (tz*tanPhi)**2
00282    //
00283    //  b = 2*( x0*tx + y0*ty - z0*tz*tanPhi**2 )
00284    //
00285    //  c = x0**2 + y0**2 - r**2 - (z0*tanPhi)**2
00286    //
00287       
00288    fCurStatWithV.ResetfDone(validate, &gp, &gv);
00289 
00290    if (fCurStatWithV.IsDone()) {
00291       G4int i;
00292       for (i=0; i<fCurStatWithV.GetNXX(); i++) {
00293          gxx[i] = fCurStatWithV.GetXX(i);
00294          distance[i] = fCurStatWithV.GetDistance(i);
00295          areacode[i] = fCurStatWithV.GetAreacode(i);
00296          isvalid[i]  = fCurStatWithV.IsValid(i);
00297       }
00298       return fCurStatWithV.GetNXX();
00299    } else {
00300       // initialize
00301       G4int i;
00302       for (i=0; i<2; i++) {
00303          distance[i] = kInfinity;
00304          areacode[i] = sOutside;
00305          isvalid[i]  = false;
00306          gxx[i].set(kInfinity, kInfinity, kInfinity);
00307       }
00308    }
00309    
00310    G4ThreeVector p = ComputeLocalPoint(gp);
00311    G4ThreeVector v = ComputeLocalDirection(gv);
00312    G4ThreeVector xx[2]; 
00313    
00314    //
00315    // special case!  p is on origin.
00316    // 
00317 
00318    if (p.mag() == 0) {
00319       // p is origin. 
00320       // unique solution of 2-dimension question in r-z plane 
00321       // Equations:
00322       //    r^2 = fR02 + z^2*fTan2Stere0
00323       //    r = beta*z
00324       //        where 
00325       //        beta = vrho / vz
00326       // Solution (z value of intersection point):
00327       //    xxz = +- std::sqrt (fR02 / (beta^2 - fTan2Stereo))
00328       //
00329 
00330       G4double vz    = v.z();
00331       G4double absvz = std::fabs(vz);
00332       G4double vrho  = v.getRho();       
00333       G4double vslope = vrho/vz;
00334       G4double vslope2 = vslope * vslope;
00335       if (vrho == 0 || (vrho/absvz) <= (absvz*std::fabs(fTanStereo)/absvz)) {
00336          // vz/vrho is bigger than slope of asymptonic line
00337          distance[0] = kInfinity;
00338          fCurStatWithV.SetCurrentStatus(0, gxx[0], distance[0], areacode[0],
00339                                         isvalid[0], 0, validate, &gp, &gv);
00340          return 0;
00341       }
00342        
00343       if (vz) { 
00344          G4double xxz  = std::sqrt(fR02 / (vslope2 - fTan2Stereo)) 
00345                         * (vz / std::fabs(vz)) ;
00346          G4double t = xxz / vz;
00347          xx[0].set(t*v.x(), t*v.y(), xxz);
00348       } else {
00349          // p.z = 0 && v.z =0
00350          xx[0].set(v.x()*fR0, v.y()*fR0, 0);  // v is a unit vector.
00351       }
00352       distance[0] = xx[0].mag();
00353       gxx[0]      = ComputeGlobalPoint(xx[0]);
00354 
00355       if (validate == kValidateWithTol) {
00356          areacode[0] = GetAreaCode(xx[0]);
00357          if (!IsOutside(areacode[0])) {
00358             if (distance[0] >= 0) isvalid[0] = true;
00359          }
00360       } else if (validate == kValidateWithoutTol) {
00361          areacode[0] = GetAreaCode(xx[0], false);
00362          if (IsInside(areacode[0])) {
00363             if (distance[0] >= 0) isvalid[0] = true;
00364          }
00365       } else { // kDontValidate                       
00366          areacode[0] = sInside;
00367             if (distance[0] >= 0) isvalid[0] = true;
00368       }
00369                  
00370       fCurStatWithV.SetCurrentStatus(0, gxx[0], distance[0], areacode[0],
00371                                         isvalid[0], 1, validate, &gp, &gv);
00372       return 1;
00373    }
00374 
00375    //
00376    // special case end.
00377    // 
00378 
00379    G4double a = v.x()*v.x() + v.y()*v.y() - v.z()*v.z()*fTan2Stereo;
00380    G4double b = 2.0 * ( p.x() * v.x() + p.y() * v.y() - p.z() * v.z() * fTan2Stereo );
00381    G4double c = p.x()*p.x() + p.y()*p.y() - fR02 - p.z()*p.z()*fTan2Stereo;
00382    G4double D = b*b - 4*a*c;          //discriminant
00383    G4int vout = 0;
00384    
00385    if (std::fabs(a) < DBL_MIN) {
00386       if (std::fabs(b) > DBL_MIN) {           // single solution
00387 
00388          distance[0] = -c/b;
00389          xx[0] = p + distance[0]*v;
00390          gxx[0] = ComputeGlobalPoint(xx[0]);
00391 
00392          if (validate == kValidateWithTol) {
00393             areacode[0] = GetAreaCode(xx[0]);
00394             if (!IsOutside(areacode[0])) {
00395                if (distance[0] >= 0) isvalid[0] = true;
00396             }
00397          } else if (validate == kValidateWithoutTol) {
00398             areacode[0] = GetAreaCode(xx[0], false);
00399             if (IsInside(areacode[0])) {
00400                if (distance[0] >= 0) isvalid[0] = true;
00401             }
00402          } else { // kDontValidate                       
00403             areacode[0] = sInside;
00404                if (distance[0] >= 0) isvalid[0] = true;
00405          }
00406                  
00407          fCurStatWithV.SetCurrentStatus(0, gxx[0], distance[0], areacode[0],
00408                                         isvalid[0], 1, validate, &gp, &gv);
00409          vout = 1;
00410          
00411       } else {
00412          // if a=b=0 and c != 0, p is origin and v is parallel to asymptotic line.
00413          // if a=b=c=0, p is on surface and v is paralell to stereo wire. 
00414          // return distance = infinity.
00415 
00416          fCurStatWithV.SetCurrentStatus(0, gxx[0], distance[0], areacode[0],
00417                                         isvalid[0], 0, validate, &gp, &gv);
00418 
00419          vout = 0;
00420       }
00421       
00422    } else if (D > DBL_MIN) {         // double solutions
00423       
00424       D = std::sqrt(D);
00425       G4double      factor = 0.5/a;
00426       G4double      tmpdist[2] = {kInfinity, kInfinity};
00427       G4ThreeVector tmpxx[2] ;
00428       G4int         tmpareacode[2] = {sOutside, sOutside};
00429       G4bool        tmpisvalid[2]  = {false, false};
00430       G4int i;
00431 
00432       for (i=0; i<2; i++) {
00433          tmpdist[i] = factor*(-b - D);
00434          D = -D;
00435          tmpxx[i] = p + tmpdist[i]*v;
00436         
00437          if (validate == kValidateWithTol) {
00438             tmpareacode[i] = GetAreaCode(tmpxx[i]);
00439             if (!IsOutside(tmpareacode[i])) {
00440                if (tmpdist[i] >= 0) tmpisvalid[i] = true;
00441                continue;
00442             }
00443          } else if (validate == kValidateWithoutTol) {
00444             tmpareacode[i] = GetAreaCode(tmpxx[i], false);
00445             if (IsInside(tmpareacode[i])) {
00446                if (tmpdist[i] >= 0) tmpisvalid[i] = true;
00447                continue;
00448             }
00449          } else { // kDontValidate
00450             tmpareacode[i] = sInside;
00451                if (tmpdist[i] >= 0) tmpisvalid[i] = true;
00452             continue;
00453          }
00454       }      
00455 
00456       if (tmpdist[0] <= tmpdist[1]) {
00457           distance[0] = tmpdist[0];
00458           distance[1] = tmpdist[1];
00459           xx[0]       = tmpxx[0];
00460           xx[1]       = tmpxx[1];
00461           gxx[0]      = ComputeGlobalPoint(tmpxx[0]);
00462           gxx[1]      = ComputeGlobalPoint(tmpxx[1]);
00463           areacode[0] = tmpareacode[0];
00464           areacode[1] = tmpareacode[1];
00465           isvalid[0]  = tmpisvalid[0];
00466           isvalid[1]  = tmpisvalid[1];
00467       } else {
00468           distance[0] = tmpdist[1];
00469           distance[1] = tmpdist[0];
00470           xx[0]       = tmpxx[1];
00471           xx[1]       = tmpxx[0];
00472           gxx[0]      = ComputeGlobalPoint(tmpxx[1]);
00473           gxx[1]      = ComputeGlobalPoint(tmpxx[0]);
00474           areacode[0] = tmpareacode[1];
00475           areacode[1] = tmpareacode[0];
00476           isvalid[0]  = tmpisvalid[1];
00477           isvalid[1]  = tmpisvalid[0];
00478       }
00479          
00480       fCurStatWithV.SetCurrentStatus(0, gxx[0], distance[0], areacode[0],
00481                                      isvalid[0], 2, validate, &gp, &gv);
00482       fCurStatWithV.SetCurrentStatus(1, gxx[1], distance[1], areacode[1],
00483                                      isvalid[1], 2, validate, &gp, &gv);
00484       vout = 2;
00485       
00486    } else {
00487       // if D<0, no solution
00488       // if D=0, just grazing the surfaces, return kInfinity
00489 
00490       fCurStatWithV.SetCurrentStatus(0, gxx[0], distance[0], areacode[0],
00491                                      isvalid[0], 0, validate, &gp, &gv);
00492       vout = 0;
00493    }
00494    return vout;
00495 }

G4double G4TwistTubsHypeSide::GetBoundaryMax ( G4double  phi  )  [inline, virtual]

Implements G4VTwistSurface.

Definition at line 195 of file G4TwistTubsHypeSide.hh.

References G4VTwistSurface::GetBoundaryAtPZ(), G4VTwistSurface::sAxis0, and G4VTwistSurface::sAxisMax.

Referenced by GetFacets().

00196 {
00197   G4ThreeVector ptmp(0,0,z) ;  // temporary point with z Komponent only
00198   G4ThreeVector upperlimit;    // upper phi-boundary limit at z = ptmp.z()
00199   upperlimit = GetBoundaryAtPZ(sAxis0 & sAxisMax, ptmp);
00200   return   std::atan2( upperlimit.y(), upperlimit.x() ) ;
00201 }

G4double G4TwistTubsHypeSide::GetBoundaryMin ( G4double  phi  )  [inline, virtual]

Implements G4VTwistSurface.

Definition at line 186 of file G4TwistTubsHypeSide.hh.

References G4VTwistSurface::GetBoundaryAtPZ(), G4VTwistSurface::sAxis0, and G4VTwistSurface::sAxisMin.

Referenced by GetFacets().

00187 {
00188   G4ThreeVector ptmp(0,0,z) ;  // temporary point with z Komponent only
00189   G4ThreeVector lowerlimit;    // lower phi-boundary limit at z = ptmp.z()
00190   lowerlimit = GetBoundaryAtPZ(sAxis0 & sAxisMin, ptmp);
00191   return  std::atan2( lowerlimit.y(), lowerlimit.x() ) ;  
00192 }

void G4TwistTubsHypeSide::GetFacets ( G4int  m,
G4int  n,
G4double  xyz[][3],
G4int  faces[][4],
G4int  iside 
) [virtual]

Implements G4VTwistSurface.

Definition at line 929 of file G4TwistTubsHypeSide.cc.

References G4VTwistSurface::fAxisMax, G4VTwistSurface::fAxisMin, G4VTwistSurface::fHandedness, GetBoundaryMax(), GetBoundaryMin(), G4VTwistSurface::GetEdgeVisibility(), G4VTwistSurface::GetFace(), G4VTwistSurface::GetNode(), and SurfacePoint().

00931 {
00932 
00933   G4double z ;     // the two parameters for the surface equation
00934   G4double x,xmin,xmax ;
00935 
00936   G4ThreeVector p ;  // a point on the surface, given by (z,u)
00937 
00938   G4int nnode ;
00939   G4int nface ;
00940 
00941   // calculate the (n-1)*(k-1) vertices
00942 
00943   G4int i,j ;
00944 
00945   for ( i = 0 ; i<n ; i++ ) {
00946 
00947     z = fAxisMin[1] + i*(fAxisMax[1]-fAxisMin[1])/(n-1) ;
00948 
00949     for ( j = 0 ; j<k ; j++ )
00950     {
00951       nnode = GetNode(i,j,k,n,iside) ;
00952 
00953       xmin = GetBoundaryMin(z) ; 
00954       xmax = GetBoundaryMax(z) ;
00955 
00956       if (fHandedness < 0) { // inner hyperbolic surface
00957         x = xmin + j*(xmax-xmin)/(k-1) ;
00958       } else {               // outer hyperbolic surface
00959         x = xmax - j*(xmax-xmin)/(k-1) ;
00960       }
00961 
00962       p = SurfacePoint(x,z,true) ;  // surface point in global coord.system
00963 
00964       xyz[nnode][0] = p.x() ;
00965       xyz[nnode][1] = p.y() ;
00966       xyz[nnode][2] = p.z() ;
00967 
00968       if ( i<n-1 && j<k-1 ) {   // clock wise filling
00969         
00970         nface = GetFace(i,j,k,n,iside) ;
00971 
00972         faces[nface][0] = GetEdgeVisibility(i,j,k,n,0,1) * ( GetNode(i  ,j  ,k,n,iside)+1) ;  
00973         faces[nface][1] = GetEdgeVisibility(i,j,k,n,1,1) * ( GetNode(i+1,j  ,k,n,iside)+1) ;
00974         faces[nface][2] = GetEdgeVisibility(i,j,k,n,2,1) * ( GetNode(i+1,j+1,k,n,iside)+1) ;
00975         faces[nface][3] = GetEdgeVisibility(i,j,k,n,3,1) * ( GetNode(i  ,j+1,k,n,iside)+1) ;
00976 
00977       }
00978     }
00979   }
00980 }

G4ThreeVector G4TwistTubsHypeSide::GetNormal ( const G4ThreeVector xx,
G4bool  isGlobal = false 
) [virtual]

Implements G4VTwistSurface.

Definition at line 150 of file G4TwistTubsHypeSide.cc.

References G4VTwistSurface::ComputeGlobalDirection(), G4VTwistSurface::ComputeLocalDirection(), G4VTwistSurface::ComputeLocalPoint(), G4VTwistSurface::fCurrentNormal, G4VTwistSurface::fHandedness, and G4VTwistSurface::kCarTolerance.

00152 {
00153    // GetNormal returns a normal vector at a surface (or very close
00154    // to surface) point at tmpxx.
00155    // If isGlobal=true, it returns the normal in global coordinate.
00156    //
00157    
00158    G4ThreeVector xx;
00159    if (isGlobal) {
00160       xx = ComputeLocalPoint(tmpxx);
00161       if ((xx - fCurrentNormal.p).mag() < 0.5 * kCarTolerance) {
00162          return ComputeGlobalDirection(fCurrentNormal.normal);
00163       }
00164    } else {
00165       xx = tmpxx;
00166       if (xx == fCurrentNormal.p) {
00167          return fCurrentNormal.normal;
00168       }
00169    }
00170    
00171    fCurrentNormal.p = xx;
00172 
00173    G4ThreeVector normal( xx.x(), xx.y(), -xx.z() * fTan2Stereo);
00174    normal *= fHandedness;
00175    normal = normal.unit();
00176 
00177    if (isGlobal) {
00178       fCurrentNormal.normal = ComputeLocalDirection(normal);
00179    } else {
00180       fCurrentNormal.normal = normal;
00181    }
00182    return fCurrentNormal.normal;
00183 }

G4double G4TwistTubsHypeSide::GetRhoAtPZ ( const G4ThreeVector p,
G4bool  isglobal = false 
) const [inline, virtual]

Definition at line 160 of file G4TwistTubsHypeSide.hh.

References G4VTwistSurface::fRot, and G4VTwistSurface::fTrans.

Referenced by Inside().

00162 {
00163   // Get Rho at p.z() on Hyperbolic Surface.
00164   G4ThreeVector tmpp;
00165   if (isglobal) {
00166      tmpp = fRot.inverse()*p - fTrans;
00167   } else {
00168      tmpp = p;
00169   }
00170   return std::sqrt(fR02 + tmpp.z() * tmpp.z() * fTan2Stereo); 
00171 }

G4double G4TwistTubsHypeSide::GetSurfaceArea (  )  [inline, virtual]

Implements G4VTwistSurface.

Definition at line 204 of file G4TwistTubsHypeSide.hh.

References G4VTwistSurface::fAxisMax, and G4VTwistSurface::fAxisMin.

00205 {
00206   // approximation with tube surface
00207 
00208   return ( fAxisMax[1] - fAxisMin[1] ) * fR0 * fDPhi ;
00209 }

EInside G4TwistTubsHypeSide::Inside ( const G4ThreeVector gp  )  [virtual]

Definition at line 188 of file G4TwistTubsHypeSide.cc.

References G4VTwistSurface::ComputeLocalPoint(), DBL_MIN, G4VTwistSurface::fHandedness, G4cout, G4endl, G4GeometryTolerance::GetInstance(), G4VTwistSurface::GetName(), G4GeometryTolerance::GetRadialTolerance(), GetRhoAtPZ(), G4VTwistSurface::IsBoundary(), G4VTwistSurface::IsInside(), G4VTwistSurface::IsOutside(), kInside, kOutside, and kSurface.

00189 {
00190    // Inside returns 
00191    static const G4double halftol
00192      = 0.5 * G4GeometryTolerance::GetInstance()->GetRadialTolerance();
00193 
00194    if (fInside.gp == gp) {
00195       return fInside.inside;
00196    }
00197    fInside.gp = gp;
00198    
00199    G4ThreeVector p = ComputeLocalPoint(gp);
00200   
00201 
00202    if (p.mag() < DBL_MIN) {
00203       fInside.inside = kOutside;
00204       return fInside.inside;
00205    }
00206    
00207    G4double rhohype = GetRhoAtPZ(p);
00208    G4double distanceToOut = fHandedness * (rhohype - p.getRho());
00209                             // +ve : inside
00210 
00211    if (distanceToOut < -halftol) {
00212 
00213      fInside.inside = kOutside;
00214 
00215    } else {
00216 
00217       G4int areacode = GetAreaCode(p);
00218       if (IsOutside(areacode)) {
00219          fInside.inside = kOutside;
00220       } else if (IsBoundary(areacode)) {
00221          fInside.inside = kSurface;
00222       } else if (IsInside(areacode)) {
00223          if (distanceToOut <= halftol) {
00224             fInside.inside = kSurface;
00225          } else {
00226             fInside.inside = kInside;
00227          }
00228       } else {
00229          G4cout << "WARNING - G4TwistTubsHypeSide::Inside()" << G4endl
00230                 << "          Invalid option !" << G4endl
00231                 << "          name, areacode, distanceToOut = "
00232                 << GetName() << ", " << std::hex << areacode << std::dec << ", "
00233                 << distanceToOut << G4endl;
00234       }
00235    }
00236    
00237    return fInside.inside; 
00238 }

G4ThreeVector G4TwistTubsHypeSide::SurfacePoint ( G4double  ,
G4double  ,
G4bool  isGlobal = false 
) [inline, virtual]

Implements G4VTwistSurface.

Definition at line 175 of file G4TwistTubsHypeSide.hh.

References G4VTwistSurface::fRot, and G4VTwistSurface::fTrans.

Referenced by GetFacets().

00176 {
00177   G4double rho = std::sqrt(fR02 + z * z * fTan2Stereo) ;
00178 
00179   G4ThreeVector SurfPoint (rho*std::cos(phi), rho*std::sin(phi), z) ;
00180 
00181   if (isGlobal) { return (fRot * SurfPoint + fTrans); }
00182   return SurfPoint;
00183 }


The documentation for this class was generated from the following files:
Generated on Mon May 27 17:53:35 2013 for Geant4 by  doxygen 1.4.7