#include #include #include using namespace RAT; SNONCDAnchor::SNONCDAnchor(G4double rmin, G4double rmax, G4double radius, const G4ThreeVector &position):fPosition(position){ fDirection = position.unit(); fRmin = rmin; fRmax = rmax; fRadius = radius; fThreshold = G4GeometryTolerance::GetInstance()->GetSurfaceTolerance(); } EInside SNONCDAnchor::Inside(const G4ThreeVector &p)const { EInside in; double radius = Radius(p); double z=p.mag(); z=p.mag(); if (radius0){ if (z>fRmin + fThreshold)in = kOutside; else if (z>fRmin - fThreshold)in = kSurface; else in = kInside; } else if (radius>fRadius + fThreshold){ in = kOutside; } return in; } G4ThreeVector SNONCDAnchor::SurfaceNormal(const G4ThreeVector &p, G4bool &isValid)const{ G4ThreeVector skew = (p - fPosition); skew = skew - (skew*fDirection)*fDirection; //vector perpendicular to cylinder axis, through p. double radius = skew.mag(); double z = p.mag(); if(p*fDirection<0)z=-z; const G4ThreeVector *retval; if (radius < fRadius + fThreshold && z>fRmin - fThreshold && z < fRmax + fThreshold){ isValid = true; if (zunit(); } G4double SNONCDAnchor::DistanceToIn(const G4ThreeVector &p, const G4ThreeVector &n, const G4double dInner[2], const G4double*)const{ double dist=kInfinity; G4ThreeVector test = n.cross(fDirection); test = test.unit(); if (fabs(test*(p - fPosition))>fRadius)return dist; // no intersection possible // check top of NCD Anchor. The ncd ir (inner radius) must be the distance to which dInner is calculated. double dtest; if(dInner[0]>fThreshold)dtest=dInner[0]; else dtest=dInner[1]; test = p + dtest * n; double z = test*fDirection>0?p.mag():-p.mag(); G4ThreeVector skew = (test - fPosition); double radius=skew.mag(); if(fabs(fRadius-radius)= 0){ q = sqrt(q); d = (-b + q) / (2 * a); if (d>fThreshold && dfRmin&&zfThreshold && dfRmin&&z 0){ //if dr<0, just return dist double dz = z-fRmin; if (dist<0)dist = dz < dr ? dz : dr; else dist = sqrt(dr*dr + dist*dist); } return dist; } G4double SNONCDAnchor::DistanceToOut(const G4ThreeVector &p, const G4ThreeVector &n, const G4double dInner[2], const G4double dOuter[2])const{ double dist= DistanceToIn(p, n, dInner, dOuter); return dist; } G4double SNONCDAnchor::DistanceToOut(const G4ThreeVector &p)const { double z = p*fDirection; G4ThreeVector skew = (p - fPosition); skew = skew - (skew*fDirection)*fDirection; //vector perpendicular to cylinder axis, through p. double radius = skew.mag(); double dr = radius - fRadius; double dist=fRmin - z;; if (dr > 0){ //if dr<0, just return dist double dz = fRmax - z; if (dist<0)dist = dz < dr ? dz : dr; else { double d = sqrt(dr*dr + dz*dz); dist = dz < d ? dz : d; } } return dist; } G4bool SNONCDAnchor::OverlapsRegion(const G4ThreeVector corners[4])const { int i; double minang=-2; for(i=0;i<4;i++){ minang=std::max(minang,corners[i].unit()*fDirection); } if(minang>cos((acos(fRmin/fRmax)+fRadius/fRmax)*1.05)){ return true; } return false; }