#include <G4EllipticalTube.hh>
Inheritance diagram for G4EllipticalTube:
Definition at line 55 of file G4EllipticalTube.hh.
G4EllipticalTube::~G4EllipticalTube | ( | ) | [virtual] |
G4EllipticalTube::G4EllipticalTube | ( | __void__ & | ) |
G4EllipticalTube::G4EllipticalTube | ( | const G4EllipticalTube & | rhs | ) |
Definition at line 95 of file G4EllipticalTube.cc.
00096 : G4VSolid(rhs), dx(rhs.dx), dy(rhs.dy), dz(rhs.dz), 00097 fCubicVolume(rhs.fCubicVolume), fSurfaceArea(rhs.fSurfaceArea), 00098 fpPolyhedron(0) 00099 { 00100 }
G4bool G4EllipticalTube::CalculateExtent | ( | const EAxis | pAxis, | |
const G4VoxelLimits & | pVoxelLimit, | |||
const G4AffineTransform & | pTransform, | |||
G4double & | pmin, | |||
G4double & | pmax | |||
) | const [virtual] |
Implements G4VSolid.
Definition at line 130 of file G4EllipticalTube.cc.
References G4SolidExtentList::AddSurface(), G4ClippablePolygon::AddVertexInOrder(), G4AffineTransform::ApplyPointTransform(), G4ClippablePolygon::ClearAllVertices(), dx, dy, dz, G4SolidExtentList::GetExtent(), kMaxMeshSections, G4ClippablePolygon::PartialClip(), G4ClippablePolygon::SetNormal(), and G4AffineTransform::TransformAxis().
00134 { 00135 G4SolidExtentList extentList( axis, voxelLimit ); 00136 00137 // 00138 // We are going to divide up our elliptical face into small 00139 // pieces 00140 // 00141 00142 // 00143 // Choose phi size of our segment(s) based on constants as 00144 // defined in meshdefs.hh 00145 // 00146 G4int numPhi = kMaxMeshSections; 00147 G4double sigPhi = twopi/numPhi; 00148 00149 // 00150 // We have to be careful to keep our segments completely outside 00151 // of the elliptical surface. To do so we imagine we have 00152 // a simple (unit radius) circular cross section (as in G4Tubs) 00153 // and then "stretch" the dimensions as necessary to fit the ellipse. 00154 // 00155 G4double rFudge = 1.0/std::cos(0.5*sigPhi); 00156 G4double dxFudge = dx*rFudge, 00157 dyFudge = dy*rFudge; 00158 00159 // 00160 // As we work around the elliptical surface, we build 00161 // a "phi" segment on the way, and keep track of two 00162 // additional polygons for the two ends. 00163 // 00164 G4ClippablePolygon endPoly1, endPoly2, phiPoly; 00165 00166 G4double phi = 0, 00167 cosPhi = std::cos(phi), 00168 sinPhi = std::sin(phi); 00169 G4ThreeVector v0( dxFudge*cosPhi, dyFudge*sinPhi, +dz ), 00170 v1( dxFudge*cosPhi, dyFudge*sinPhi, -dz ), 00171 w0, w1; 00172 transform.ApplyPointTransform( v0 ); 00173 transform.ApplyPointTransform( v1 ); 00174 do 00175 { 00176 phi += sigPhi; 00177 if (numPhi == 1) phi = 0; // Try to avoid roundoff 00178 cosPhi = std::cos(phi), 00179 sinPhi = std::sin(phi); 00180 00181 w0 = G4ThreeVector( dxFudge*cosPhi, dyFudge*sinPhi, +dz ); 00182 w1 = G4ThreeVector( dxFudge*cosPhi, dyFudge*sinPhi, -dz ); 00183 transform.ApplyPointTransform( w0 ); 00184 transform.ApplyPointTransform( w1 ); 00185 00186 // 00187 // Add a point to our z ends 00188 // 00189 endPoly1.AddVertexInOrder( v0 ); 00190 endPoly2.AddVertexInOrder( v1 ); 00191 00192 // 00193 // Build phi polygon 00194 // 00195 phiPoly.ClearAllVertices(); 00196 00197 phiPoly.AddVertexInOrder( v0 ); 00198 phiPoly.AddVertexInOrder( v1 ); 00199 phiPoly.AddVertexInOrder( w1 ); 00200 phiPoly.AddVertexInOrder( w0 ); 00201 00202 if (phiPoly.PartialClip( voxelLimit, axis )) 00203 { 00204 // 00205 // Get unit normal 00206 // 00207 phiPoly.SetNormal( (v1-v0).cross(w0-v0).unit() ); 00208 00209 extentList.AddSurface( phiPoly ); 00210 } 00211 00212 // 00213 // Next vertex 00214 // 00215 v0 = w0; 00216 v1 = w1; 00217 } while( --numPhi > 0 ); 00218 00219 // 00220 // Process the end pieces 00221 // 00222 if (endPoly1.PartialClip( voxelLimit, axis )) 00223 { 00224 static const G4ThreeVector normal(0,0,+1); 00225 endPoly1.SetNormal( transform.TransformAxis(normal) ); 00226 extentList.AddSurface( endPoly1 ); 00227 } 00228 00229 if (endPoly2.PartialClip( voxelLimit, axis )) 00230 { 00231 static const G4ThreeVector normal(0,0,-1); 00232 endPoly2.SetNormal( transform.TransformAxis(normal) ); 00233 extentList.AddSurface( endPoly2 ); 00234 } 00235 00236 // 00237 // Return min/max value 00238 // 00239 return extentList.GetExtent( min, max ); 00240 }
G4double G4EllipticalTube::CheckXY | ( | const G4double | x, | |
const G4double | y, | |||
const G4double | toler | |||
) | const [inline, protected] |
Definition at line 80 of file G4EllipticalTube.icc.
Referenced by DistanceToIn(), DistanceToOut(), Inside(), and SurfaceNormal().
G4VSolid * G4EllipticalTube::Clone | ( | ) | const [virtual] |
Reimplemented from G4VSolid.
Definition at line 858 of file G4EllipticalTube.cc.
References G4EllipticalTube().
00859 { 00860 return new G4EllipticalTube(*this); 00861 }
G4Polyhedron * G4EllipticalTube::CreatePolyhedron | ( | ) | const [virtual] |
Reimplemented from G4VSolid.
Definition at line 961 of file G4EllipticalTube.cc.
Referenced by GetPolyhedron().
00962 { 00963 // create cylinder with radius=1... 00964 // 00965 G4Polyhedron* eTube = new G4PolyhedronTube(0.,1.,dz); 00966 00967 // apply non-uniform scaling... 00968 // 00969 eTube->Transform(G4Scale3D(dx,dy,1.)); 00970 return eTube; 00971 }
void G4EllipticalTube::DescribeYourselfTo | ( | G4VGraphicsScene & | scene | ) | const [virtual] |
Implements G4VSolid.
Definition at line 993 of file G4EllipticalTube.cc.
References G4VGraphicsScene::AddSolid().
00994 { 00995 scene.AddSolid (*this); 00996 }
G4double G4EllipticalTube::DistanceToIn | ( | const G4ThreeVector & | p | ) | const [virtual] |
Implements G4VSolid.
Definition at line 525 of file G4EllipticalTube.cc.
References CheckXY(), DBL_MIN, dx, dz, and G4VSolid::kCarTolerance.
00526 { 00527 static const G4double halfTol = 0.5*kCarTolerance; 00528 00529 if (CheckXY( p.x(), p.y(), +halfTol ) < 1.0) 00530 { 00531 // 00532 // We are inside or on the surface of the 00533 // elliptical cross section in x/y. Check z 00534 // 00535 if (p.z() < -dz-halfTol) 00536 return -p.z()-dz; 00537 else if (p.z() > dz+halfTol) 00538 return p.z()-dz; 00539 else 00540 return 0; // On any surface here (or inside) 00541 } 00542 00543 // 00544 // Find point on ellipse 00545 // 00546 G4double qnorm = CheckXY( p.x(), p.y() ); 00547 if (qnorm < DBL_MIN) return 0; // This should never happen 00548 00549 G4double q = 1.0/std::sqrt(qnorm); 00550 00551 G4double xe = q*p.x(), ye = q*p.y(); 00552 00553 // 00554 // Get tangent to ellipse 00555 // 00556 G4double tx = -ye*dx*dx, ty = +xe*dy*dy; 00557 G4double tnorm = std::sqrt( tx*tx + ty*ty ); 00558 00559 // 00560 // Calculate distance 00561 // 00562 G4double distR = ( (p.x()-xe)*ty - (p.y()-ye)*tx )/tnorm; 00563 00564 // 00565 // Add the result in quadrature if we are, in addition, 00566 // outside the z bounds of the shape 00567 // 00568 // We could save some time by returning the maximum rather 00569 // than the quadrature sum 00570 // 00571 if (p.z() < -dz) 00572 return std::sqrt( (p.z()+dz)*(p.z()+dz) + distR*distR ); 00573 else if (p.z() > dz) 00574 return std::sqrt( (p.z()-dz)*(p.z()-dz) + distR*distR ); 00575 00576 return distR; 00577 }
G4double G4EllipticalTube::DistanceToIn | ( | const G4ThreeVector & | p, | |
const G4ThreeVector & | v | |||
) | const [virtual] |
Implements G4VSolid.
Definition at line 367 of file G4EllipticalTube.cc.
References CheckXY(), dx, dz, IntersectXY(), G4VSolid::kCarTolerance, and CLHEP::detail::n.
00369 { 00370 static const G4double halfTol = 0.5*kCarTolerance; 00371 00372 // 00373 // Check z = -dz planer surface 00374 // 00375 G4double sigz = p.z()+dz; 00376 00377 if (sigz < halfTol) 00378 { 00379 // 00380 // We are "behind" the shape in z, and so can 00381 // potentially hit the rear face. Correct direction? 00382 // 00383 if (v.z() <= 0) 00384 { 00385 // 00386 // As long as we are far enough away, we know we 00387 // can't intersect 00388 // 00389 if (sigz < 0) return kInfinity; 00390 00391 // 00392 // Otherwise, we don't intersect unless we are 00393 // on the surface of the ellipse 00394 // 00395 if (CheckXY(p.x(),p.y(),-halfTol) <= 1.0) return kInfinity; 00396 } 00397 else 00398 { 00399 // 00400 // How far? 00401 // 00402 G4double q = -sigz/v.z(); 00403 00404 // 00405 // Where does that place us? 00406 // 00407 G4double xi = p.x() + q*v.x(), 00408 yi = p.y() + q*v.y(); 00409 00410 // 00411 // Is this on the surface (within ellipse)? 00412 // 00413 if (CheckXY(xi,yi) <= 1.0) 00414 { 00415 // 00416 // Yup. Return q, unless we are on the surface 00417 // 00418 return (sigz < -halfTol) ? q : 0; 00419 } 00420 else if (xi*dy*dy*v.x() + yi*dx*dx*v.y() >= 0) 00421 { 00422 // 00423 // Else, if we are traveling outwards, we know 00424 // we must miss 00425 // 00426 return kInfinity; 00427 } 00428 } 00429 } 00430 00431 // 00432 // Check z = +dz planer surface 00433 // 00434 sigz = p.z() - dz; 00435 00436 if (sigz > -halfTol) 00437 { 00438 if (v.z() >= 0) 00439 { 00440 if (sigz > 0) return kInfinity; 00441 if (CheckXY(p.x(),p.y(),-halfTol) <= 1.0) return kInfinity; 00442 } 00443 else { 00444 G4double q = -sigz/v.z(); 00445 00446 G4double xi = p.x() + q*v.x(), 00447 yi = p.y() + q*v.y(); 00448 00449 if (CheckXY(xi,yi) <= 1.0) 00450 { 00451 return (sigz > -halfTol) ? q : 0; 00452 } 00453 else if (xi*dy*dy*v.x() + yi*dx*dx*v.y() >= 0) 00454 { 00455 return kInfinity; 00456 } 00457 } 00458 } 00459 00460 // 00461 // Check intersection with the elliptical tube 00462 // 00463 G4double q[2]; 00464 G4int n = IntersectXY( p, v, q ); 00465 00466 if (n==0) return kInfinity; 00467 00468 // 00469 // Is the original point on the surface? 00470 // 00471 if (std::fabs(p.z()) < dz+halfTol) { 00472 if (CheckXY( p.x(), p.y(), halfTol ) < 1.0) 00473 { 00474 // 00475 // Well, yes, but are we traveling inwards at this point? 00476 // 00477 if (p.x()*dy*dy*v.x() + p.y()*dx*dx*v.y() < 0) return 0; 00478 } 00479 } 00480 00481 // 00482 // We are now certain that point p is not on the surface of 00483 // the solid (and thus std::fabs(q[0]) > halfTol). 00484 // Return kInfinity if the intersection is "behind" the point. 00485 // 00486 if (q[0] < 0) return kInfinity; 00487 00488 // 00489 // Check to see if we intersect the tube within 00490 // dz, but only when we know it might miss 00491 // 00492 G4double zi = p.z() + q[0]*v.z(); 00493 00494 if (v.z() < 0) 00495 { 00496 if (zi < -dz) return kInfinity; 00497 } 00498 else if (v.z() > 0) 00499 { 00500 if (zi > +dz) return kInfinity; 00501 } 00502 00503 return q[0]; 00504 }
G4double G4EllipticalTube::DistanceToOut | ( | const G4ThreeVector & | p | ) | const [virtual] |
Implements G4VSolid.
Definition at line 729 of file G4EllipticalTube.cc.
References DBL_MIN, dx, dz, and G4VSolid::kCarTolerance.
00730 { 00731 static const G4double halfTol = 0.5*kCarTolerance; 00732 00733 // 00734 // We need to calculate the distances to all surfaces, 00735 // and then return the smallest 00736 // 00737 // Check -dz and +dz surface 00738 // 00739 G4double sBest = dz - std::fabs(p.z()); 00740 if (sBest < halfTol) return 0; 00741 00742 // 00743 // Check elliptical surface: find intersection of 00744 // line through p and parallel to x axis 00745 // 00746 G4double radical = 1.0 - p.y()*p.y()/dy/dy; 00747 if (radical < +DBL_MIN) return 0; 00748 00749 G4double xi = dx*std::sqrt( radical ); 00750 if (p.x() < 0) xi = -xi; 00751 00752 // 00753 // Do the same with y axis 00754 // 00755 radical = 1.0 - p.x()*p.x()/dx/dx; 00756 if (radical < +DBL_MIN) return 0; 00757 00758 G4double yi = dy*std::sqrt( radical ); 00759 if (p.y() < 0) yi = -yi; 00760 00761 // 00762 // Get distance from p to the line connecting 00763 // these two points 00764 // 00765 G4double xdi = p.x() - xi, 00766 ydi = yi - p.y(); 00767 00768 G4double normi = std::sqrt( xdi*xdi + ydi*ydi ); 00769 if (normi < halfTol) return 0; 00770 xdi /= normi; 00771 ydi /= normi; 00772 00773 G4double q = 0.5*(xdi*(p.y()-yi) - ydi*(p.x()-xi)); 00774 if (xi*yi < 0) q = -q; 00775 00776 if (q < sBest) sBest = q; 00777 00778 // 00779 // Return best answer 00780 // 00781 return sBest < halfTol ? 0 : sBest; 00782 }
G4double G4EllipticalTube::DistanceToOut | ( | const G4ThreeVector & | p, | |
const G4ThreeVector & | v, | |||
const G4bool | calcNorm = false , |
|||
G4bool * | validNorm = 0 , |
|||
G4ThreeVector * | n = 0 | |||
) | const [virtual] |
Implements G4VSolid.
Definition at line 588 of file G4EllipticalTube.cc.
References CheckXY(), G4VSolid::DumpInfo(), dx, dz, G4endl, G4Exception(), IntersectXY(), JustWarning, G4VSolid::kCarTolerance, and CLHEP::detail::n.
00593 { 00594 static const G4double halfTol = 0.5*kCarTolerance; 00595 00596 // 00597 // Our normal is always valid 00598 // 00599 if (calcNorm) { *validNorm = true; } 00600 00601 G4double sBest = kInfinity; 00602 G4ThreeVector nBest(0,0,0); 00603 00604 // 00605 // Might we intersect the -dz surface? 00606 // 00607 if (v.z() < 0) 00608 { 00609 static const G4ThreeVector normHere(0.0,0.0,-1.0); 00610 // 00611 // Yup. What distance? 00612 // 00613 sBest = -(p.z()+dz)/v.z(); 00614 00615 // 00616 // Are we on the surface? If so, return zero 00617 // 00618 if (p.z() < -dz+halfTol) 00619 { 00620 if (calcNorm) { *norm = normHere; } 00621 return 0; 00622 } 00623 else 00624 { 00625 nBest = normHere; 00626 } 00627 } 00628 00629 // 00630 // How about the +dz surface? 00631 // 00632 if (v.z() > 0) 00633 { 00634 static const G4ThreeVector normHere(0.0,0.0,+1.0); 00635 // 00636 // Yup. What distance? 00637 // 00638 G4double q = (dz-p.z())/v.z(); 00639 00640 // 00641 // Are we on the surface? If so, return zero 00642 // 00643 if (p.z() > +dz-halfTol) 00644 { 00645 if (calcNorm) { *norm = normHere; } 00646 return 0; 00647 } 00648 00649 // 00650 // Best so far? 00651 // 00652 if (q < sBest) { sBest = q; nBest = normHere; } 00653 } 00654 00655 // 00656 // Check furthest intersection with ellipse 00657 // 00658 G4double q[2]; 00659 G4int n = IntersectXY( p, v, q ); 00660 00661 if (n == 0) 00662 { 00663 if (sBest == kInfinity) 00664 { 00665 DumpInfo(); 00666 std::ostringstream message; 00667 G4int oldprc = message.precision(16) ; 00668 message << "Point p is outside !?" << G4endl 00669 << "Position:" << G4endl 00670 << " p.x() = " << p.x()/mm << " mm" << G4endl 00671 << " p.y() = " << p.y()/mm << " mm" << G4endl 00672 << " p.z() = " << p.z()/mm << " mm" << G4endl 00673 << "Direction:" << G4endl << G4endl 00674 << " v.x() = " << v.x() << G4endl 00675 << " v.y() = " << v.y() << G4endl 00676 << " v.z() = " << v.z() << G4endl 00677 << "Proposed distance :" << G4endl 00678 << " snxt = " << sBest/mm << " mm"; 00679 message.precision(oldprc) ; 00680 G4Exception( "G4EllipticalTube::DistanceToOut(p,v,...)", 00681 "GeomSolids1002", JustWarning, message); 00682 } 00683 if (calcNorm) { *norm = nBest; } 00684 return sBest; 00685 } 00686 else if (q[n-1] > sBest) 00687 { 00688 if (calcNorm) { *norm = nBest; } 00689 return sBest; 00690 } 00691 sBest = q[n-1]; 00692 00693 // 00694 // Intersection with ellipse. Get normal at intersection point. 00695 // 00696 if (calcNorm) 00697 { 00698 G4ThreeVector ip = p + sBest*v; 00699 *norm = G4ThreeVector( ip.x()*dy*dy, ip.y()*dx*dx, 0.0 ).unit(); 00700 } 00701 00702 // 00703 // Do we start on the surface? 00704 // 00705 if (CheckXY( p.x(), p.y(), -halfTol ) > 1.0) 00706 { 00707 // 00708 // Well, yes, but are we traveling outwards at this point? 00709 // 00710 if (p.x()*dy*dy*v.x() + p.y()*dx*dx*v.y() > 0) return 0; 00711 } 00712 00713 return sBest; 00714 }
G4double G4EllipticalTube::GetCubicVolume | ( | ) | [virtual] |
Reimplemented from G4VSolid.
Definition at line 867 of file G4EllipticalTube.cc.
References G4VSolid::GetCubicVolume().
00868 { 00869 if(fCubicVolume != 0.) {;} 00870 else { fCubicVolume = G4VSolid::GetCubicVolume(); } 00871 return fCubicVolume; 00872 }
G4double G4EllipticalTube::GetDx | ( | ) | const [inline] |
Definition at line 38 of file G4EllipticalTube.icc.
References dx.
Referenced by G4GDMLWriteSolids::EltubeWrite(), and G4tgbGeometryDumper::GetSolidParams().
00039 { 00040 return dx; 00041 }
G4double G4EllipticalTube::GetDy | ( | ) | const [inline] |
Definition at line 44 of file G4EllipticalTube.icc.
References dy.
Referenced by G4GDMLWriteSolids::EltubeWrite(), and G4tgbGeometryDumper::GetSolidParams().
00045 { 00046 return dy; 00047 }
G4double G4EllipticalTube::GetDz | ( | ) | const [inline] |
Definition at line 50 of file G4EllipticalTube.icc.
References dz.
Referenced by G4GDMLWriteSolids::EltubeWrite(), and G4tgbGeometryDumper::GetSolidParams().
00051 { 00052 return dz; 00053 }
G4GeometryType G4EllipticalTube::GetEntityType | ( | ) | const [virtual] |
Implements G4VSolid.
Definition at line 849 of file G4EllipticalTube.cc.
00850 { 00851 return G4String("G4EllipticalTube"); 00852 }
G4VisExtent G4EllipticalTube::GetExtent | ( | ) | const [virtual] |
G4ThreeVector G4EllipticalTube::GetPointOnSurface | ( | ) | const [virtual] |
Reimplemented from G4VSolid.
Definition at line 911 of file G4EllipticalTube.cc.
References dx, dz, G4INCL::Math::pi, and sqr().
00912 { 00913 G4double xRand, yRand, zRand, phi, cosphi, sinphi, zArea, cArea,p, chose; 00914 00915 phi = RandFlat::shoot(0., 2.*pi); 00916 cosphi = std::cos(phi); 00917 sinphi = std::sin(phi); 00918 00919 // the ellipse perimeter from: "http://mathworld.wolfram.com/Ellipse.html" 00920 // m = (dx - dy)/(dx + dy); 00921 // k = 1.+1./4.*m*m+1./64.*sqr(m)*sqr(m)+1./256.*sqr(m)*sqr(m)*sqr(m); 00922 // p = pi*(a+b)*k; 00923 00924 // perimeter below from "http://www.efunda.com/math/areas/EllipseGen.cfm" 00925 00926 p = 2.*pi*std::sqrt(0.5*(dx*dx+dy*dy)); 00927 00928 cArea = 2.*dz*p; 00929 zArea = pi*dx*dy; 00930 00931 xRand = dx*cosphi; 00932 yRand = dy*sinphi; 00933 zRand = RandFlat::shoot(dz, -1.*dz); 00934 00935 chose = RandFlat::shoot(0.,2.*zArea+cArea); 00936 00937 if( (chose>=0) && (chose < cArea) ) 00938 { 00939 return G4ThreeVector (xRand,yRand,zRand); 00940 } 00941 else if( (chose >= cArea) && (chose < cArea + zArea) ) 00942 { 00943 xRand = RandFlat::shoot(-1.*dx,dx); 00944 yRand = std::sqrt(1.-sqr(xRand/dx)); 00945 yRand = RandFlat::shoot(-1.*yRand, yRand); 00946 return G4ThreeVector (xRand,yRand,dz); 00947 } 00948 else 00949 { 00950 xRand = RandFlat::shoot(-1.*dx,dx); 00951 yRand = std::sqrt(1.-sqr(xRand/dx)); 00952 yRand = RandFlat::shoot(-1.*yRand, yRand); 00953 return G4ThreeVector (xRand,yRand,-1.*dz); 00954 } 00955 }
G4Polyhedron * G4EllipticalTube::GetPolyhedron | ( | ) | const [virtual] |
Reimplemented from G4VSolid.
Definition at line 977 of file G4EllipticalTube.cc.
References CreatePolyhedron(), and G4Polyhedron::GetNumberOfRotationStepsAtTimeOfCreation().
00978 { 00979 if (!fpPolyhedron || 00980 fpPolyhedron->GetNumberOfRotationStepsAtTimeOfCreation() != 00981 fpPolyhedron->GetNumberOfRotationSteps()) 00982 { 00983 delete fpPolyhedron; 00984 fpPolyhedron = CreatePolyhedron(); 00985 } 00986 return fpPolyhedron; 00987 }
G4double G4EllipticalTube::GetSurfaceArea | ( | ) | [virtual] |
Reimplemented from G4VSolid.
Definition at line 877 of file G4EllipticalTube.cc.
References G4VSolid::GetSurfaceArea().
00878 { 00879 if(fSurfaceArea != 0.) {;} 00880 else { fSurfaceArea = G4VSolid::GetSurfaceArea(); } 00881 return fSurfaceArea; 00882 }
EInside G4EllipticalTube::Inside | ( | const G4ThreeVector & | p | ) | const [virtual] |
Implements G4VSolid.
Definition at line 250 of file G4EllipticalTube.cc.
References CheckXY(), dz, G4VSolid::kCarTolerance, kInside, kOutside, and kSurface.
00251 { 00252 static const G4double halfTol = 0.5*kCarTolerance; 00253 00254 // 00255 // Check z extents: are we outside? 00256 // 00257 G4double absZ = std::fabs(p.z()); 00258 if (absZ > dz+halfTol) return kOutside; 00259 00260 // 00261 // Check x,y: are we outside? 00262 // 00263 // G4double x = p.x(), y = p.y(); 00264 00265 if (CheckXY(p.x(), p.y(), +halfTol) > 1.0) return kOutside; 00266 00267 // 00268 // We are either inside or on the surface: recheck z extents 00269 // 00270 if (absZ > dz-halfTol) return kSurface; 00271 00272 // 00273 // Recheck x,y 00274 // 00275 if (CheckXY(p.x(), p.y(), -halfTol) > 1.0) return kSurface; 00276 00277 return kInside; 00278 }
G4int G4EllipticalTube::IntersectXY | ( | const G4ThreeVector & | p, | |
const G4ThreeVector & | v, | |||
G4double | s[2] | |||
) | const [protected] |
Definition at line 810 of file G4EllipticalTube.cc.
Referenced by DistanceToIn(), and DistanceToOut().
00813 { 00814 G4double px = p.x(), py = p.y(); 00815 G4double vx = v.x(), vy = v.y(); 00816 00817 G4double a = (vx/dx)*(vx/dx) + (vy/dy)*(vy/dy); 00818 G4double b = 2.0*( px*vx/dx/dx + py*vy/dy/dy ); 00819 G4double c = (px/dx)*(px/dx) + (py/dy)*(py/dy) - 1.0; 00820 00821 if (a < DBL_MIN) return 0; // Trajectory parallel to z axis 00822 00823 G4double radical = b*b - 4*a*c; 00824 00825 if (radical < -DBL_MIN) return 0; // No solution 00826 00827 if (radical < DBL_MIN) 00828 { 00829 // 00830 // Grazes surface 00831 // 00832 ss[0] = -b/a/2.0; 00833 return 1; 00834 } 00835 00836 radical = std::sqrt(radical); 00837 00838 G4double q = -0.5*( b + (b < 0 ? -radical : +radical) ); 00839 G4double sa = q/a; 00840 G4double sb = c/q; 00841 if (sa < sb) { ss[0] = sa; ss[1] = sb; } else { ss[0] = sb; ss[1] = sa; } 00842 return 2; 00843 }
G4EllipticalTube & G4EllipticalTube::operator= | ( | const G4EllipticalTube & | rhs | ) |
Definition at line 106 of file G4EllipticalTube.cc.
References dx, dy, dz, fCubicVolume, fSurfaceArea, and G4VSolid::operator=().
00107 { 00108 // Check assignment to self 00109 // 00110 if (this == &rhs) { return *this; } 00111 00112 // Copy base class data 00113 // 00114 G4VSolid::operator=(rhs); 00115 00116 // Copy data 00117 // 00118 dx = rhs.dx; dy = rhs.dy; dz = rhs.dz; 00119 fCubicVolume = rhs.fCubicVolume; fSurfaceArea = rhs.fSurfaceArea; 00120 fpPolyhedron = 0; 00121 00122 return *this; 00123 }
void G4EllipticalTube::SetDx | ( | const G4double | newDx | ) | [inline] |
Definition at line 56 of file G4EllipticalTube.icc.
References dx.
00057 { 00058 dx = newDx; 00059 fCubicVolume = 0.; 00060 fpPolyhedron = 0; 00061 }
void G4EllipticalTube::SetDy | ( | const G4double | newDy | ) | [inline] |
Definition at line 64 of file G4EllipticalTube.icc.
References dy.
00065 { 00066 dy = newDy; 00067 fCubicVolume = 0.; 00068 fpPolyhedron = 0; 00069 }
void G4EllipticalTube::SetDz | ( | const G4double | newDz | ) | [inline] |
Definition at line 72 of file G4EllipticalTube.icc.
References dz.
00073 { 00074 dz = newDz; 00075 fCubicVolume = 0.; 00076 fpPolyhedron = 0; 00077 }
std::ostream & G4EllipticalTube::StreamInfo | ( | std::ostream & | os | ) | const [virtual] |
Implements G4VSolid.
Definition at line 887 of file G4EllipticalTube.cc.
References dx, dz, and G4VSolid::GetName().
00888 { 00889 G4int oldprc = os.precision(16); 00890 os << "-----------------------------------------------------------\n" 00891 << " *** Dump for solid - " << GetName() << " ***\n" 00892 << " ===================================================\n" 00893 << " Solid type: G4EllipticalTube\n" 00894 << " Parameters: \n" 00895 << " length Z: " << dz/mm << " mm \n" 00896 << " surface equation in X and Y: \n" 00897 << " (X / " << dx << ")^2 + (Y / " << dy << ")^2 = 1 \n" 00898 << "-----------------------------------------------------------\n"; 00899 os.precision(oldprc); 00900 00901 return os; 00902 }
G4ThreeVector G4EllipticalTube::SurfaceNormal | ( | const G4ThreeVector & | p | ) | const [virtual] |
Implements G4VSolid.
Definition at line 284 of file G4EllipticalTube.cc.
References CheckXY(), dx, dy, dz, G4Exception(), JustWarning, and G4VSolid::kCarTolerance.
00285 { 00286 // 00287 // SurfaceNormal for the point On the Surface, sum the normals on the Corners 00288 // 00289 static const G4double halfTol = 0.5*kCarTolerance; 00290 00291 G4int noSurfaces=0; 00292 G4ThreeVector norm, sumnorm(0.,0.,0.); 00293 00294 G4double distZ = std::fabs(std::fabs(p.z()) - dz); 00295 00296 G4double distR1 = CheckXY( p.x(), p.y(),+ halfTol ); 00297 G4double distR2 = CheckXY( p.x(), p.y(),- halfTol ); 00298 00299 if ( (distZ < halfTol ) && ( distR1 <= 1 ) ) 00300 { 00301 noSurfaces++; 00302 sumnorm=G4ThreeVector( 0.0, 0.0, p.z() < 0 ? -1.0 : 1.0 ); 00303 } 00304 if( (distR1 <= 1 ) && ( distR2 >= 1 ) ) 00305 { 00306 noSurfaces++; 00307 norm= G4ThreeVector( p.x()*dy*dy, p.y()*dx*dx, 0.0 ).unit(); 00308 sumnorm+=norm; 00309 } 00310 if ( noSurfaces == 0 ) 00311 { 00312 #ifdef G4SPECSDEBUG 00313 G4Exception("G4EllipticalTube::SurfaceNormal(p)", "GeomSolids1002", 00314 JustWarning, "Point p is not on surface !?" ); 00315 #endif 00316 norm = ApproxSurfaceNormal(p); 00317 } 00318 else if ( noSurfaces == 1 ) { norm = sumnorm; } 00319 else { norm = sumnorm.unit(); } 00320 00321 return norm; 00322 }
G4double G4EllipticalTube::dx [protected] |
Definition at line 128 of file G4EllipticalTube.hh.
Referenced by CalculateExtent(), CheckXY(), CreatePolyhedron(), DistanceToIn(), DistanceToOut(), G4EllipticalTube(), GetDx(), GetExtent(), GetPointOnSurface(), IntersectXY(), operator=(), SetDx(), StreamInfo(), and SurfaceNormal().
G4double G4EllipticalTube::dy [protected] |
Definition at line 128 of file G4EllipticalTube.hh.
Referenced by CalculateExtent(), CheckXY(), G4EllipticalTube(), GetDy(), operator=(), SetDy(), and SurfaceNormal().
G4double G4EllipticalTube::dz [protected] |
Definition at line 128 of file G4EllipticalTube.hh.
Referenced by CalculateExtent(), CreatePolyhedron(), DistanceToIn(), DistanceToOut(), G4EllipticalTube(), GetDz(), GetExtent(), GetPointOnSurface(), Inside(), operator=(), SetDz(), StreamInfo(), and SurfaceNormal().