Geant4  10.01.p03
UEnclosingCylinder.cc
Go to the documentation of this file.
1 //
2 // ********************************************************************
3 // * This Software is part of the AIDA Unified Solids Library package *
4 // * See: https://aidasoft.web.cern.ch/USolids *
5 // ********************************************************************
6 //
7 // $Id:$
8 //
9 // --------------------------------------------------------------------
10 //
11 // UEnclosingCylinder
12 //
13 // 19.10.12 Marek Gayer
14 // Created from original implementation in Geant4
15 // --------------------------------------------------------------------
16 
17 #include "UUtils.hh"
18 #include <string>
19 #include <cmath>
20 #include <sstream>
21 #include "UEnclosingCylinder.hh"
22 #include "UReduciblePolygon.hh"
23 
24 #include "VUSolid.hh"
25 #include "UBox.hh"
26 #include "UTubs.hh"
27 
28 //
29 // Constructor
30 //
31 UEnclosingCylinder::UEnclosingCylinder(/*const UReduciblePolygon *rz*/double r, double hi, double lo,
32  bool thePhiIsOpen,
33  double theStartPhi,
34  double theTotalPhi)
35  : startPhi(theStartPhi), totalPhi(theTotalPhi),
36  rx1(0.), ry1(0.), dx1(0.), dy1(0.),
37  rx2(0.), ry2(0.), dx2(0.), dy2(0.),
38  concave(theTotalPhi > UUtils::kPi)
39 {
40  //
41  // Obtain largest r and smallest and largest z
42  //
43 
44  /*
45  radius = rz->Amax();
46  zHi = rz->Bmax();
47  zLo = rz->Bmin();
48  */
49 
50  radius = r;
51  zHi = hi;
52  zLo = lo;
53 
54  double fTolerance = VUSolid::Tolerance();
55 
56  tube = new UTubs("", 0, radius + fTolerance, zHi - zLo, theStartPhi, theTotalPhi);
57 
58  //
59  // Save phi info
60  //
61  phiIsOpen = thePhiIsOpen;
62  if (phiIsOpen)
63  {
64  rx1 = std::cos(startPhi);
65  ry1 = std::sin(startPhi);
66  dx1 = +ry1 * 10 * fTolerance;
67  dy1 = -rx1 * 10 * fTolerance;
68 
69  rx2 = std::cos(startPhi + totalPhi);
70  ry2 = std::sin(startPhi + totalPhi);
71  dx2 = -ry2 * 10 * fTolerance;
72  dy2 = +rx2 * 10 * fTolerance;
73  }
74 
75  //
76  // Add safety
77  //
78  radius += 10 * fTolerance;
79  zLo -= 10 * fTolerance;
80  zHi += 10 * fTolerance;
81 }
82 
83 
84 //
85 // Destructor
86 //
88 {
89 }
90 
91 
92 //
93 // Outside
94 //
95 // Decide very rapidly if the point is outside the cylinder
96 //
97 // If one is not certain, return false
98 //
100 {
101 // if (p.Perp() > radius ) return true;
102  if (p.Perp2() > radius * radius) return true;
103  if (p.z() < zLo) return true;
104  if (p.z() > zHi) return true;
105 
106  if (phiIsOpen)
107  {
108  if (concave)
109  {
110  if (((p.x() - dx1)*ry1 - (p.y() - dy1)*rx1) < 0) return false;
111  if (((p.x() - dx2)*ry2 - (p.y() - dy2)*rx2) > 0) return false;
112  }
113  else
114  {
115  if (((p.x() - dx1)*ry1 - (p.y() - dy1)*rx1) > 0) return true;
116  if (((p.x() - dx2)*ry2 - (p.y() - dy2)*rx2) < 0) return true;
117  }
118  }
119 
120  return false;
121 }
122 
123 
124 //
125 // Misses
126 //
127 // Decide very rapidly if the trajectory is going to miss the cylinder
128 //
129 // If one is not sure, return false
130 //
132  const UVector3& v) const
133 {
134  if (!MustBeOutside(p)) return false;
135 
136 // if (p.z() < zLo - VUSolid::Tolerance() && v.z() <= 0) return true;
137 // if (p.z() > zHi + VUSolid::Tolerance() && v.z() >= 0) return true;
138 
139  double cross = p.x() * v.y() - p.y() * v.x();
140  if (cross > radius) return true;
141 
142  double r2 = p.Perp2();
143  if (r2 > radius * radius)
144  {
145  double dot = p.x() * v.x() + p.y() * v.y();
146  if (dot > 0) return true;
147 
148 // double n = v.Perp2();
149 // if (Dot < std::sqrt(r2 - radius * radius) * n) return true;
150  }
151 
152 
153  /*
154  if (phiIsOpen)
155  {
156  if (concave)
157  {
158  if ( ((p.x()-dx1)*ry1 - (p.y()-dy1)*rx1) < 0) return false;
159  if ( ((p.x()-dx2)*ry2 - (p.y()-dy2)*rx2) > 0) return false;
160  }
161  else
162  {
163  if ( ((p.x()-dx1)*ry1 - (p.y()-dy1)*rx1) > 0) return true;
164  if ( ((p.x()-dx2)*ry2 - (p.y()-dy2)*rx2) < 0) return true;
165  }
166  return false;
167  }
168  */
169 
170  return false;
171 }
172 
174 {
175  aMin = UVector3(-radius, -radius, zLo);
176  aMax = UVector3(radius, radius, zHi);
177 }
178 
179 double UEnclosingCylinder::DistanceTo(const UVector3& p, const UVector3& v) const
180 {
181  return tube->DistanceToIn(p, v);
182 }
183 
185 {
186  return tube->SafetyFromOutside(p);
187 }
Definition: UTubs.hh:48
double SafetyFromOutside(const UVector3 &p) const
double & z()
Definition: UVector3.hh:352
double & y()
Definition: UVector3.hh:348
double SafetyFromOutside(const UVector3 &p, bool precise=false) const
Definition: UTubs.cc:1032
bool MustBeOutside(const UVector3 &p) const
static double Tolerance()
Definition: VUSolid.hh:127
double & x()
Definition: UVector3.hh:344
UEnclosingCylinder(double r, double lo, double hi, bool phiIsOpen, double startPhi, double totalPhi)
bool ShouldMiss(const UVector3 &p, const UVector3 &v) const
double Perp2() const
Definition: UVector3.hh:292
static const double kPi
Definition: UUtils.hh:49
void Extent(UVector3 &aMin, UVector3 &aMax) const
double DistanceToIn(const UVector3 &p, const UVector3 &v, double aPstep=UUtils::kInfinity) const
Definition: UTubs.cc:616
Definition: UUtils.hh:38
double DistanceTo(const UVector3 &p, const UVector3 &v) const