Geant4.10
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Public Member Functions | Protected Member Functions | Static Protected Member Functions | Protected Attributes
UPolyconeSide Class Reference

#include <UPolyconeSide.hh>

Inheritance diagram for UPolyconeSide:
UVCSGface

Public Member Functions

 UPolyconeSide (const UPolyconeSideRZ *prevRZ, const UPolyconeSideRZ *tail, const UPolyconeSideRZ *head, const UPolyconeSideRZ *nextRZ, double phiStart, double deltaPhi, bool phiIsOpen, bool isAllBehind=false)
 
virtual ~UPolyconeSide ()
 
 UPolyconeSide (const UPolyconeSide &source)
 
UPolyconeSideoperator= (const UPolyconeSide &source)
 
bool Distance (const UVector3 &p, const UVector3 &v, bool outgoing, double surfTolerance, double &distance, double &distFromSurface, UVector3 &normal, bool &isAllBehind)
 
double Safety (const UVector3 &p, bool outgoing)
 
VUSolid::EnumInside Inside (const UVector3 &p, double tolerance, double *bestDistance)
 
UVector3 Normal (const UVector3 &p, double *bestDistance)
 
double Extent (const UVector3 axis)
 
UVCSGfaceClone ()
 
double SurfaceArea ()
 
UVector3 GetPointOnFace ()
 
 UPolyconeSide (__void__ &)
 
- Public Member Functions inherited from UVCSGface
 UVCSGface ()
 
virtual ~UVCSGface ()
 

Protected Member Functions

double DistanceAway (const UVector3 &p, bool opposite, double &distOutside2, double *rzNorm=0)
 
bool PointOnCone (const UVector3 &hit, double normSign, const UVector3 &p, const UVector3 &v, UVector3 &normal)
 
void CopyStuff (const UPolyconeSide &source)
 
double GetPhi (const UVector3 &p)
 

Static Protected Member Functions

static void FindLineIntersect (double x1, double y1, double tx1, double ty1, double x2, double y2, double tx2, double ty2, double &x, double &y)
 

Protected Attributes

double r [2]
 
double z [2]
 
double startPhi
 
double deltaPhi
 
bool phiIsOpen
 
bool allBehind
 
UIntersectingConecone
 
double rNorm
 
double zNorm
 
double rS
 
double zS
 
double length
 
double prevRS
 
double prevZS
 
double nextRS
 
double nextZS
 
double rNormEdge [2]
 
double zNormEdge [2]
 
int ncorners
 
UVector3corners
 

Detailed Description

Definition at line 56 of file UPolyconeSide.hh.

Constructor & Destructor Documentation

UPolyconeSide::UPolyconeSide ( const UPolyconeSideRZ prevRZ,
const UPolyconeSideRZ tail,
const UPolyconeSideRZ head,
const UPolyconeSideRZ nextRZ,
double  phiStart,
double  deltaPhi,
bool  phiIsOpen,
bool  isAllBehind = false 
)

Definition at line 31 of file UPolyconeSide.cc.

References allBehind, cone, corners, deltaPhi, length, ncorners, nextRS, nextZS, phiIsOpen, prevRS, prevZS, UPolyconeSideRZ::r, r, rNorm, rNormEdge, rS, startPhi, VUSolid::Tolerance(), UPolyconeSideRZ::z, z, zNorm, zNormEdge, and zS.

Referenced by Clone().

39  : ncorners(0), corners(0)
40 {
41 
42  tolerance = VUSolid::Tolerance();
43 
44  fSurfaceArea = 0.0;
45 
46  //
47  // Record values
48  //
49  r[0] = tail->r;
50  z[0] = tail->z;
51  r[1] = head->r;
52  z[1] = head->z;
53 
54  phiIsOpen = thePhiIsOpen;
55  if (phiIsOpen)
56  {
57  deltaPhi = theDeltaPhi;
58  startPhi = thePhiStart;
59 
60  //
61  // Set phi values to our conventions
62  //
63  while (deltaPhi < 0.0) deltaPhi += 2 * UUtils::kPi;
64  while (startPhi < 0.0) startPhi += 2 * UUtils::kPi;
65 
66  //
67  // Calculate corner coordinates
68  //
69  ncorners = 4;
70  corners = new UVector3[ncorners];
71 
72  corners[0] = UVector3(tail->r * std::cos(startPhi),
73  tail->r * std::sin(startPhi), tail->z);
74  corners[1] = UVector3(head->r * std::cos(startPhi),
75  head->r * std::sin(startPhi), head->z);
76  corners[2] = UVector3(tail->r * std::cos(startPhi + deltaPhi),
77  tail->r * std::sin(startPhi + deltaPhi), tail->z);
78  corners[3] = UVector3(head->r * std::cos(startPhi + deltaPhi),
79  head->r * std::sin(startPhi + deltaPhi), head->z);
80  }
81  else
82  {
83  deltaPhi = 2 * UUtils::kPi;
84  startPhi = 0.0;
85  }
86 
87  allBehind = isAllBehind;
88 
89  //
90  // Make our intersecting cone
91  //
92  cone = new UIntersectingCone(r, z);
93 
94  //
95  // Calculate vectors in r,z space
96  //
97  rS = r[1] - r[0];
98  zS = z[1] - z[0];
99  length = std::sqrt(rS * rS + zS * zS);
100  rS /= length;
101  zS /= length;
102 
103  rNorm = +zS;
104  zNorm = -rS;
105 
106  double lAdj;
107 
108  prevRS = r[0] - prevRZ->r;
109  prevZS = z[0] - prevRZ->z;
110  lAdj = std::sqrt(prevRS * prevRS + prevZS * prevZS);
111  prevRS /= lAdj;
112  prevZS /= lAdj;
113 
114  rNormEdge[0] = rNorm + prevZS;
115  zNormEdge[0] = zNorm - prevRS;
116  lAdj = std::sqrt(rNormEdge[0] * rNormEdge[0] + zNormEdge[0] * zNormEdge[0]);
117  rNormEdge[0] /= lAdj;
118  zNormEdge[0] /= lAdj;
119 
120  nextRS = nextRZ->r - r[1];
121  nextZS = nextRZ->z - z[1];
122  lAdj = std::sqrt(nextRS * nextRS + nextZS * nextZS);
123  nextRS /= lAdj;
124  nextZS /= lAdj;
125 
126  rNormEdge[1] = rNorm + nextZS;
127  zNormEdge[1] = zNorm - nextRS;
128  lAdj = std::sqrt(rNormEdge[1] * rNormEdge[1] + zNormEdge[1] * zNormEdge[1]);
129  rNormEdge[1] /= lAdj;
130  zNormEdge[1] /= lAdj;
131 }
double zNormEdge[2]
static double Tolerance()
Definition: VUSolid.hh:127
UIntersectingCone * cone
UVector3 * corners
double rNormEdge[2]
UPolyconeSide::~UPolyconeSide ( )
virtual

Definition at line 152 of file UPolyconeSide.cc.

References cone, corners, and phiIsOpen.

153 {
154  delete cone;
155  if (phiIsOpen)
156  {
157  delete [] corners;
158  }
159 }
UIntersectingCone * cone
UVector3 * corners
UPolyconeSide::UPolyconeSide ( const UPolyconeSide source)

Definition at line 165 of file UPolyconeSide.cc.

References CopyStuff().

166  : UVCSGface(), ncorners(0), corners(0)
167 {
168 
169  CopyStuff(source);
170 }
void CopyStuff(const UPolyconeSide &source)
UVector3 * corners
UPolyconeSide::UPolyconeSide ( __void__ &  )

Definition at line 137 of file UPolyconeSide.cc.

References r, rNormEdge, z, and zNormEdge.

138  : startPhi(0.), deltaPhi(0.), phiIsOpen(false), allBehind(false),
139  cone(0), rNorm(0.), zNorm(0.), rS(0.), zS(0.), length(0.),
140  prevRS(0.), prevZS(0.), nextRS(0.), nextZS(0.), ncorners(0), corners(0),
141  tolerance(0.), fSurfaceArea(0.)
142 {
143  r[0] = r[1] = 0.;
144  z[0] = z[1] = 0.;
145  rNormEdge[0] = rNormEdge[1] = 0.;
146  zNormEdge[0] = zNormEdge[1] = 0.;
147 }
double zNormEdge[2]
UIntersectingCone * cone
UVector3 * corners
double rNormEdge[2]

Member Function Documentation

UVCSGface* UPolyconeSide::Clone ( )
inlinevirtual

Implements UVCSGface.

Definition at line 92 of file UPolyconeSide.hh.

References UPolyconeSide().

93  {
94  return new UPolyconeSide(*this);
95  }
UPolyconeSide(const UPolyconeSideRZ *prevRZ, const UPolyconeSideRZ *tail, const UPolyconeSideRZ *head, const UPolyconeSideRZ *nextRZ, double phiStart, double deltaPhi, bool phiIsOpen, bool isAllBehind=false)
void UPolyconeSide::CopyStuff ( const UPolyconeSide source)
protected

Definition at line 198 of file UPolyconeSide.cc.

References allBehind, cone, corners, deltaPhi, length, ncorners, nextRS, nextZS, phiIsOpen, prevRS, prevZS, r, rNorm, rNormEdge, rS, startPhi, z, zNorm, zNormEdge, and zS.

Referenced by operator=(), and UPolyconeSide().

199 {
200  r[0] = source.r[0];
201  r[1] = source.r[1];
202  z[0] = source.z[0];
203  z[1] = source.z[1];
204 
205  startPhi = source.startPhi;
206  deltaPhi = source.deltaPhi;
207  phiIsOpen = source.phiIsOpen;
208  allBehind = source.allBehind;
209 
210  tolerance = source.tolerance;
211  fSurfaceArea = source.fSurfaceArea;
212 
213  cone = new UIntersectingCone(*source.cone);
214 
215  rNorm = source.rNorm;
216  zNorm = source.zNorm;
217  rS = source.rS;
218  zS = source.zS;
219  length = source.length;
220  prevRS = source.prevRS;
221  prevZS = source.prevZS;
222  nextRS = source.nextRS;
223  nextZS = source.nextZS;
224 
225  rNormEdge[0] = source.rNormEdge[0];
226  rNormEdge[1] = source.rNormEdge[1];
227  zNormEdge[0] = source.zNormEdge[0];
228  zNormEdge[1] = source.zNormEdge[1];
229 
230  if (phiIsOpen)
231  {
232  ncorners = 4;
233  corners = new UVector3[ncorners];
234 
235  corners[0] = source.corners[0];
236  corners[1] = source.corners[1];
237  corners[2] = source.corners[2];
238  corners[3] = source.corners[3];
239  }
240 }
double zNormEdge[2]
UIntersectingCone * cone
UVector3 * corners
double rNormEdge[2]
bool UPolyconeSide::Distance ( const UVector3 p,
const UVector3 v,
bool  outgoing,
double  surfTolerance,
double &  distance,
double &  distFromSurface,
UVector3 normal,
bool &  isAllBehind 
)
virtual

Implements UVCSGface.

Definition at line 246 of file UPolyconeSide.cc.

References allBehind, cone, DBL_MIN, DistanceAway(), UIntersectingCone::LineHitsCone(), UVector3::Perp(), PointOnCone(), gammaraytel::pr, rNorm, test::v, UVector3::x, UVector3::y, and zNorm.

254 {
255  double s1, s2;
256  double normSign = outgoing ? +1 : -1;
257 
258  isAllBehind = allBehind;
259 
260  //
261  // Check for two possible intersections
262  //
263  int nside = cone->LineHitsCone(p, v, s1, s2);
264  if (nside == 0) return false;
265 
266  //
267  // Check the first side first, since it is (supposed to be) closest
268  //
269  UVector3 hit = p + s1 * v;
270 
271  if (PointOnCone(hit, normSign, p, v, normal))
272  {
273  //
274  // Good intersection! What about the normal?
275  //
276  if (normSign * v.Dot(normal) > 0)
277  {
278  //
279  // We have a valid intersection, but it could very easily
280  // be behind the point. To decide if we tolerate this,
281  // we have to see if the point p is on the surface near
282  // the intersecting point.
283  //
284  // What does it mean exactly for the point p to be "near"
285  // the intersection? It means that if we draw a line from
286  // p to the hit, the line remains entirely within the
287  // tolerance bounds of the cone. To test this, we can
288  // ask if the normal is correct near p.
289  //
290  double pr = p.Perp();
291  if (pr < DBL_MIN) pr = DBL_MIN;
292  UVector3 pNormal(rNorm * p.x / pr, rNorm * p.y / pr, zNorm);
293  if (normSign * v.Dot(pNormal) > 0)
294  {
295  //
296  // p and intersection in same hemisphere
297  //
298  double distOutside2;
299  distFromSurface = -normSign * DistanceAway(p, false, distOutside2);
300  if (distOutside2 < surfTolerance * surfTolerance)
301  {
302  if (distFromSurface > -surfTolerance)
303  {
304  //
305  // We are just inside or away from the
306  // surface. Accept *any* value of distance.
307  //
308  distance = s1;
309  return true;
310  }
311  }
312  }
313  else
314  distFromSurface = s1;
315 
316  //
317  // Accept positive distances
318  //
319  if (s1 > 0)
320  {
321  distance = s1;
322  return true;
323  }
324  }
325  }
326 
327  if (nside == 1) return false;
328 
329  //
330  // Well, try the second hit
331  //
332  hit = p + s2 * v;
333 
334  if (PointOnCone(hit, normSign, p, v, normal))
335  {
336  //
337  // Good intersection! What about the normal?
338  //
339  if (normSign * v.Dot(normal) > 0)
340  {
341  double pr = p.Perp();
342  if (pr < DBL_MIN) pr = DBL_MIN;
343  UVector3 pNormal(rNorm * p.x / pr, rNorm * p.y / pr, zNorm);
344  if (normSign * v.Dot(pNormal) > 0)
345  {
346  double distOutside2;
347  distFromSurface = -normSign * DistanceAway(p, false, distOutside2);
348  if (distOutside2 < surfTolerance * surfTolerance)
349  {
350  if (distFromSurface > -surfTolerance)
351  {
352  distance = s2;
353  return true;
354  }
355  }
356  }
357  else
358  distFromSurface = s2;
359 
360  if (s2 > 0)
361  {
362  distance = s2;
363  return true;
364  }
365  }
366  }
367 
368  //
369  // Better luck next time
370  //
371  return false;
372 }
double DistanceAway(const UVector3 &p, bool opposite, double &distOutside2, double *rzNorm=0)
double x
Definition: UVector3.hh:136
UIntersectingCone * cone
#define DBL_MIN
Definition: templates.hh:75
double Perp() const
Definition: UVector3.cc:56
double y
Definition: UVector3.hh:137
int LineHitsCone(const UVector3 &p, const UVector3 &v, double &s1, double &s2)
bool PointOnCone(const UVector3 &hit, double normSign, const UVector3 &p, const UVector3 &v, UVector3 &normal)
double UPolyconeSide::DistanceAway ( const UVector3 p,
bool  opposite,
double &  distOutside2,
double *  rzNorm = 0 
)
protected

Definition at line 894 of file UPolyconeSide.cc.

References deltaPhi, GetPhi(), length, G4INCL::Math::max(), UVector3::Perp(), phiIsOpen, r, rNorm, rNormEdge, rS, UUtils::sqr(), startPhi, z, UVector3::z, zNorm, zNormEdge, and zS.

Referenced by Distance(), Inside(), Normal(), and Safety().

898 {
899  //
900  // Convert our point to r and z
901  //
902  double rx = p.Perp(), zx = p.z;
903 
904  //
905  // Change sign of r if opposite says we should
906  //
907  if (opposite) rx = -rx;
908 
909  //
910  // Calculate return value
911  //
912  double deltaR = rx - r[0], deltaZ = zx - z[0];
913  double answer = deltaR * rNorm + deltaZ * zNorm;
914 
915  //
916  // Are we off the surface in r,z space?
917  //
918  double q = deltaR * rS + deltaZ * zS;
919  if (q < 0)
920  {
921  distOutside2 = q * q;
922  if (edgeRZnorm) *edgeRZnorm = deltaR * rNormEdge[0] + deltaZ * zNormEdge[0];
923  }
924  else if (q > length)
925  {
926  distOutside2 = UUtils::sqr(q - length);
927  if (edgeRZnorm)
928  {
929  deltaR = rx - r[1];
930  deltaZ = zx - z[1];
931  *edgeRZnorm = deltaR * rNormEdge[1] + deltaZ * zNormEdge[1];
932  }
933  }
934  else
935  {
936  distOutside2 = 0;
937  if (edgeRZnorm) *edgeRZnorm = answer;
938  }
939 
940  if (phiIsOpen)
941  {
942  //
943  // Finally, check phi
944  //
945  double phi = GetPhi(p);
946  while (phi < startPhi) phi += 2 * UUtils::kPi;
947 
948  if (phi > startPhi + deltaPhi)
949  {
950  //
951  // Oops. Are we closer to the start phi or end phi?
952  //
953  double d1 = phi - startPhi - deltaPhi;
954  while (phi > startPhi) phi -= 2 * UUtils::kPi;
955  double d2 = startPhi - phi;
956 
957  if (d2 < d1) d1 = d2;
958 
959  //
960  // Add result to our distance
961  //
962  double dist = d1 * rx;
963 
964  distOutside2 += dist * dist;
965  if (edgeRZnorm)
966  {
967  *edgeRZnorm = std::max(std::fabs(*edgeRZnorm), std::fabs(dist));
968  }
969  }
970  }
971 
972  return answer;
973 }
double zNormEdge[2]
double GetPhi(const UVector3 &p)
T sqr(const T &x)
Definition: UUtils.hh:142
T max(const T t1, const T t2)
brief Return the largest of the two arguments
double Perp() const
Definition: UVector3.cc:56
double z
Definition: UVector3.hh:138
double rNormEdge[2]
double UPolyconeSide::Extent ( const UVector3  axis)
virtual

Implements UVCSGface.

Definition at line 480 of file UPolyconeSide.cc.

References test::a, test::b, test::c, cone, DBL_MIN, deltaPhi, UVector3::Dot(), GetPhi(), UVector3::Perp(), UVector3::Perp2(), phiIsOpen, r, startPhi, z, UVector3::z, UIntersectingCone::ZHi(), and UIntersectingCone::ZLo().

481 {
482  if (axis.Perp2() < DBL_MIN)
483  {
484  //
485  // Special case
486  //
487  return axis.z < 0 ? -cone->ZLo() : cone->ZHi();
488  }
489 
490  //
491  // Is the axis pointing inside our phi gap?
492  //
493  if (phiIsOpen)
494  {
495  double phi = GetPhi(axis);
496  while (phi < startPhi) phi += 2 * UUtils::kPi;
497 
498  if (phi > deltaPhi + startPhi)
499  {
500  //
501  // Yeah, looks so. Make four three vectors defining the phi
502  // opening
503  //
504  double cosP = std::cos(startPhi), sinP = std::sin(startPhi);
505  UVector3 a(r[0]*cosP, r[0]*sinP, z[0]);
506  UVector3 b(r[1]*cosP, r[1]*sinP, z[1]);
507  cosP = std::cos(startPhi + deltaPhi);
508  sinP = std::sin(startPhi + deltaPhi);
509  UVector3 c(r[0]*cosP, r[0]*sinP, z[0]);
510  UVector3 d(r[1]*cosP, r[1]*sinP, z[1]);
511 
512  double ad = axis.Dot(a),
513  bd = axis.Dot(b),
514  cd = axis.Dot(c),
515  dd = axis.Dot(d);
516 
517  if (bd > ad) ad = bd;
518  if (cd > ad) ad = cd;
519  if (dd > ad) ad = dd;
520 
521  return ad;
522  }
523  }
524 
525  //
526  // Check either end
527  //
528  double aPerp = axis.Perp();
529 
530  double a = aPerp * r[0] + axis.z * z[0];
531  double b = aPerp * r[1] + axis.z * z[1];
532 
533  if (b > a) a = b;
534 
535  return a;
536 }
double GetPhi(const UVector3 &p)
double Dot(const UVector3 &) const
Definition: UVector3.hh:257
double Perp2() const
Definition: UVector3.hh:272
UIntersectingCone * cone
double ZHi() const
#define DBL_MIN
Definition: templates.hh:75
double Perp() const
Definition: UVector3.cc:56
double z
Definition: UVector3.hh:138
double ZLo() const
void UPolyconeSide::FindLineIntersect ( double  x1,
double  y1,
double  tx1,
double  ty1,
double  x2,
double  y2,
double  tx2,
double  ty2,
double &  x,
double &  y 
)
staticprotected

Definition at line 1050 of file UPolyconeSide.cc.

1055 {
1056  //
1057  // The solution is a simple linear equation
1058  //
1059  double deter = tx1 * ty2 - tx2 * ty1;
1060 
1061  double s1 = ((x2 - x1) * ty2 - tx2 * (y2 - y1)) / deter;
1062  double s2 = ((x2 - x1) * ty1 - tx1 * (y2 - y1)) / deter;
1063 
1064  //
1065  // We want the answer to not depend on which order the
1066  // lines were specified. Take average.
1067  //
1068  x = 0.5 * (x1 + s1 * tx1 + x2 + s2 * tx2);
1069  y = 0.5 * (y1 + s1 * ty1 + y2 + s2 * ty2);
1070 }
double UPolyconeSide::GetPhi ( const UVector3 p)
protected

Definition at line 867 of file UPolyconeSide.cc.

References UVector3::Phi().

Referenced by DistanceAway(), Extent(), and PointOnCone().

868 {
869  double val = 0.;
870 
871  val = p.Phi();
872 
873  return val;
874 }
double Phi() const
Definition: UVector3.cc:64
UVector3 UPolyconeSide::GetPointOnFace ( )
virtual

Implements UVCSGface.

Definition at line 1088 of file UPolyconeSide.cc.

References deltaPhi, r, UUtils::Random(), startPhi, test::x, and z.

1089 {
1090  double x, y, zz;
1091  double rr, phi, dz, dr;
1092  dr = r[1] - r[0];
1093  dz = z[1] - z[0];
1094  phi = startPhi + deltaPhi * UUtils::Random();
1095  rr = r[0] + dr * UUtils::Random();
1096 
1097  x = rr * std::cos(phi);
1098  y = rr * std::sin(phi);
1099 
1100  // PolyconeSide has a Ring Form
1101  //
1102  if (dz == 0.)
1103  {
1104  zz = z[0];
1105  }
1106  else
1107  {
1108  if (dr == 0.) // PolyconeSide has a Tube Form
1109  {
1110  zz = z[0] + dz * UUtils::Random();
1111  }
1112  else
1113  {
1114  zz = z[0] + (rr - r[0]) * dz / dr;
1115  }
1116  }
1117 
1118  return UVector3(x, y, zz);
1119 }
double Random(double min=0.0, double max=1.0)
Definition: UUtils.cc:69
VUSolid::EnumInside UPolyconeSide::Inside ( const UVector3 p,
double  tolerance,
double *  bestDistance 
)
virtual

Implements UVCSGface.

Definition at line 415 of file UPolyconeSide.cc.

References DistanceAway(), VUSolid::eInside, VUSolid::eOutside, and VUSolid::eSurface.

418 {
419  //
420  // Check both sides
421  //
422  double distFrom[2], distOut2[2], dist2[2];
423  double edgeRZnorm[2];
424 
425  distFrom[0] = DistanceAway(p, false, distOut2[0], edgeRZnorm);
426  distFrom[1] = DistanceAway(p, true, distOut2[1], edgeRZnorm + 1);
427 
428  dist2[0] = distFrom[0] * distFrom[0] + distOut2[0];
429  dist2[1] = distFrom[1] * distFrom[1] + distOut2[1];
430 
431  //
432  // Who's closest?
433  //
434  int i = std::fabs(dist2[0]) < std::fabs(dist2[1]) ? 0 : 1;
435 
436  *bestDistance = std::sqrt(dist2[i]); // could sqrt be removed?
437 
438  //
439  // Okay then, inside or out?
440  //
441  if ((std::fabs(edgeRZnorm[i]) < atolerance)
442  && (distOut2[i] < atolerance * atolerance))
443  return VUSolid::eSurface;
444  else if (edgeRZnorm[i] < 0)
445  return VUSolid::eInside;
446  else
447  return VUSolid::eOutside;
448 }
double DistanceAway(const UVector3 &p, bool opposite, double &distOutside2, double *rzNorm=0)
UVector3 UPolyconeSide::Normal ( const UVector3 p,
double *  bestDistance 
)
virtual

Implements UVCSGface.

Definition at line 454 of file UPolyconeSide.cc.

References DistanceAway(), UVector3::Perp(), rNorm, UVector3::Unit(), UVector3::x, UVector3::y, and zNorm.

456 {
457  if (p == UVector3(0., 0., 0.))
458  {
459  return p;
460  }
461 
462  double dFrom, dOut2;
463 
464  dFrom = DistanceAway(p, false, dOut2);
465 
466  *bestDistance = std::sqrt(dFrom * dFrom + dOut2);
467 
468  double rds = p.Perp();
469  if (rds != 0.)
470  {
471  return UVector3(rNorm * p.x / rds, rNorm * p.y / rds, zNorm);
472  }
473  return UVector3(0., 0., zNorm).Unit();
474 }
double DistanceAway(const UVector3 &p, bool opposite, double &distOutside2, double *rzNorm=0)
const char * p
Definition: xmltok.h:285
double x
Definition: UVector3.hh:136
UVector3 Unit() const
Definition: UVector3.cc:80
double Perp() const
Definition: UVector3.cc:56
double y
Definition: UVector3.hh:137
UPolyconeSide & UPolyconeSide::operator= ( const UPolyconeSide source)

Definition at line 176 of file UPolyconeSide.cc.

References cone, CopyStuff(), corners, and phiIsOpen.

177 {
178  if (this == &source)
179  {
180  return *this;
181  }
182 
183  delete cone;
184  if (phiIsOpen)
185  {
186  delete [] corners;
187  }
188 
189  CopyStuff(source);
190 
191  return *this;
192 }
void CopyStuff(const UPolyconeSide &source)
UIntersectingCone * cone
UVector3 * corners
bool UPolyconeSide::PointOnCone ( const UVector3 hit,
double  normSign,
const UVector3 p,
const UVector3 v,
UVector3 normal 
)
protected

Definition at line 981 of file UPolyconeSide.cc.

References cone, corners, UVector3::Cross(), DBL_MIN, deltaPhi, UVector3::Dot(), GetPhi(), UIntersectingCone::HitOn(), UVector3::Perp(), phiIsOpen, rNorm, startPhi, VUSolid::Tolerance(), test::v, UVector3::x, UVector3::y, UVector3::z, and zNorm.

Referenced by Distance().

986 {
987  double rx = hit.Perp();
988  //
989  // Check radial/z extent, as appropriate
990  //
991  if (!cone->HitOn(rx, hit.z)) return false;
992 
993  if (phiIsOpen)
994  {
995  double phiTolerant = 2.0 * VUSolid::Tolerance() / (rx + VUSolid::Tolerance());
996  //
997  // Check phi segment. Here we have to be careful
998  // to use the standard method consistent with
999  // PolyPhiFace. See PolyPhiFace::InsideEdgesExact
1000  //
1001  double phi = GetPhi(hit);
1002  while (phi < startPhi - phiTolerant) phi += 2 * UUtils::kPi;
1003 
1004  if (phi > startPhi + deltaPhi + phiTolerant) return false;
1005 
1006  if (phi > startPhi + deltaPhi - phiTolerant)
1007  {
1008  //
1009  // Exact treatment
1010  //
1011  UVector3 qx = p + v;
1012  UVector3 qa = qx - corners[2],
1013  qb = qx - corners[3];
1014  UVector3 qacb = qa.Cross(qb);
1015 
1016  if (normSign * qacb.Dot(v) < 0) return false;
1017  }
1018  else if (phi < phiTolerant)
1019  {
1020  UVector3 qx = p + v;
1021  UVector3 qa = qx - corners[1],
1022  qb = qx - corners[0];
1023  UVector3 qacb = qa.Cross(qb);
1024 
1025  if (normSign * qacb.Dot(v) < 0) return false;
1026  }
1027  }
1028 
1029  //
1030  // We have a good hit! Calculate normal
1031  //
1032  if (rx < DBL_MIN)
1033  normal = UVector3(0, 0, zNorm < 0 ? -1 : 1);
1034  else
1035  normal = UVector3(rNorm * hit.x / rx, rNorm * hit.y / rx, zNorm);
1036  return true;
1037 }
UVector3 Cross(const UVector3 &) const
Definition: UVector3.hh:262
double GetPhi(const UVector3 &p)
static double Tolerance()
Definition: VUSolid.hh:127
double x
Definition: UVector3.hh:136
bool HitOn(const double r, const double z)
double Dot(const UVector3 &) const
Definition: UVector3.hh:257
UIntersectingCone * cone
#define DBL_MIN
Definition: templates.hh:75
double Perp() const
Definition: UVector3.cc:56
UVector3 * corners
double z
Definition: UVector3.hh:138
double y
Definition: UVector3.hh:137
double UPolyconeSide::Safety ( const UVector3 p,
bool  outgoing 
)
virtual

Implements UVCSGface.

Definition at line 375 of file UPolyconeSide.cc.

References DistanceAway(), and VUSolid::Tolerance().

376 {
377  double normSign = outgoing ? -1 : +1;
378  double distFrom, distOut2;
379 
380  //
381  // We have two tries for each hemisphere. Try the closest first.
382  //
383  distFrom = normSign * DistanceAway(p, false, distOut2);
384  if (distFrom > -0.5 * VUSolid::Tolerance())
385  {
386  //
387  // Good answer
388  //
389  if (distOut2 > 0)
390  return std::sqrt(distFrom * distFrom + distOut2);
391  else
392  return std::fabs(distFrom);
393  }
394 
395  //
396  // Try second side.
397  //
398  distFrom = normSign * DistanceAway(p, true, distOut2);
399  if (distFrom > -0.5 * VUSolid::Tolerance())
400  {
401 
402  if (distOut2 > 0)
403  return std::sqrt(distFrom * distFrom + distOut2);
404  else
405  return std::fabs(distFrom);
406  }
407 
408  return UUtils::kInfinity;
409 }
double DistanceAway(const UVector3 &p, bool opposite, double &distOutside2, double *rzNorm=0)
static double Tolerance()
Definition: VUSolid.hh:127
double UPolyconeSide::SurfaceArea ( )
virtual

Implements UVCSGface.

Definition at line 1075 of file UPolyconeSide.cc.

References deltaPhi, r, UUtils::sqr(), and z.

1076 {
1077  if (fSurfaceArea == 0)
1078  {
1079  fSurfaceArea = (r[0] + r[1]) * std::sqrt(UUtils::sqr(r[0] - r[1]) + UUtils::sqr(z[0] - z[1]));
1080  fSurfaceArea *= 0.5 * (deltaPhi);
1081  }
1082  return fSurfaceArea;
1083 }
T sqr(const T &x)
Definition: UUtils.hh:142

Field Documentation

bool UPolyconeSide::allBehind
protected

Definition at line 132 of file UPolyconeSide.hh.

Referenced by CopyStuff(), Distance(), and UPolyconeSide().

UIntersectingCone* UPolyconeSide::cone
protected
UVector3* UPolyconeSide::corners
protected

Definition at line 148 of file UPolyconeSide.hh.

Referenced by CopyStuff(), operator=(), PointOnCone(), UPolyconeSide(), and ~UPolyconeSide().

double UPolyconeSide::deltaPhi
protected
double UPolyconeSide::length
protected

Definition at line 138 of file UPolyconeSide.hh.

Referenced by CopyStuff(), DistanceAway(), and UPolyconeSide().

int UPolyconeSide::ncorners
protected

Definition at line 147 of file UPolyconeSide.hh.

Referenced by CopyStuff(), and UPolyconeSide().

double UPolyconeSide::nextRS
protected

Definition at line 141 of file UPolyconeSide.hh.

Referenced by CopyStuff(), and UPolyconeSide().

double UPolyconeSide::nextZS
protected

Definition at line 141 of file UPolyconeSide.hh.

Referenced by CopyStuff(), and UPolyconeSide().

bool UPolyconeSide::phiIsOpen
protected
double UPolyconeSide::prevRS
protected

Definition at line 139 of file UPolyconeSide.hh.

Referenced by CopyStuff(), and UPolyconeSide().

double UPolyconeSide::prevZS
protected

Definition at line 139 of file UPolyconeSide.hh.

Referenced by CopyStuff(), and UPolyconeSide().

double UPolyconeSide::r[2]
protected
double UPolyconeSide::rNorm
protected

Definition at line 136 of file UPolyconeSide.hh.

Referenced by CopyStuff(), Distance(), DistanceAway(), Normal(), PointOnCone(), and UPolyconeSide().

double UPolyconeSide::rNormEdge[2]
protected

Definition at line 144 of file UPolyconeSide.hh.

Referenced by CopyStuff(), DistanceAway(), and UPolyconeSide().

double UPolyconeSide::rS
protected

Definition at line 137 of file UPolyconeSide.hh.

Referenced by CopyStuff(), DistanceAway(), and UPolyconeSide().

double UPolyconeSide::startPhi
protected
double UPolyconeSide::z[2]
protected
double UPolyconeSide::zNorm
protected

Definition at line 136 of file UPolyconeSide.hh.

Referenced by CopyStuff(), Distance(), DistanceAway(), Normal(), PointOnCone(), and UPolyconeSide().

double UPolyconeSide::zNormEdge[2]
protected

Definition at line 144 of file UPolyconeSide.hh.

Referenced by CopyStuff(), DistanceAway(), and UPolyconeSide().

double UPolyconeSide::zS
protected

Definition at line 137 of file UPolyconeSide.hh.

Referenced by CopyStuff(), DistanceAway(), and UPolyconeSide().


The documentation for this class was generated from the following files: