#include <G4TwistTubsHypeSide.hh>
Inheritance diagram for G4TwistTubsHypeSide:
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 |
Definition at line 54 of file G4TwistTubsHypeSide.hh.
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] |
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 }
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 }
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 }
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 }