Geant4  10.01.p01
UQuadrangularFacet.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 // UQuadrangularFacet
12 //
13 // 17.10.12 Marek Gayer
14 // Created from original implementation in Geant4
15 // --------------------------------------------------------------------
16 
17 #include "UUtils.hh"
18 #include "VUSolid.hh"
19 #include "UQuadrangularFacet.hh"
20 
21 using namespace std;
22 
24 //
25 // !!!THIS IS A FUDGE!!! IT'S TWO ADJACENT UTRIANGULARFACETS
26 // --- NOT EFFICIENT BUT PRACTICAL.
27 //
29  const UVector3& vt1, const UVector3& vt2,
30  const UVector3& vt3, UFacetVertexType vertexType)
31 {
32  UVector3 e1, e2, e3;
33 
34  SetVertex(0, vt0);
35  if (vertexType == UABSOLUTE)
36  {
37  SetVertex(1, vt1);
38  SetVertex(2, vt2);
39  SetVertex(3, vt3);
40 
41  e1 = vt1 - vt0;
42  e2 = vt2 - vt0;
43  e3 = vt3 - vt0;
44  }
45  else
46  {
47  SetVertex(1, vt0 + vt1);
48  SetVertex(2, vt0 + vt2);
49  SetVertex(3, vt0 + vt3);
50 
51  e1 = vt1;
52  e2 = vt2;
53  e3 = vt3;
54  }
55  double length1 = e1.Mag();
56  double length2 = (GetVertex(2) - GetVertex(1)).Mag();
57  double length3 = (GetVertex(3) - GetVertex(2)).Mag();
58  double length4 = e3.Mag();
59 
60  UVector3 normal1 = e1.Cross(e2).Unit();
61  UVector3 normal2 = e2.Cross(e3).Unit();
62 
63  bool isDefined = (length1 > VUSolid::Tolerance() && length2 > VUSolid::Tolerance() &&
64  length3 > VUSolid::Tolerance() && length4 > VUSolid::Tolerance() &&
65  normal1.Dot(normal2) >= 0.9999999999);
66 
67  if (isDefined)
68  {
69  fFacet1 = UTriangularFacet(GetVertex(0), GetVertex(1), GetVertex(2), UABSOLUTE);
70  fFacet2 = UTriangularFacet(GetVertex(0), GetVertex(2), GetVertex(3), UABSOLUTE);
71 
72  UTriangularFacet facet3(GetVertex(0), GetVertex(1), GetVertex(3), UABSOLUTE);
73  UTriangularFacet facet4(GetVertex(1), GetVertex(2), GetVertex(3), UABSOLUTE);
74 
75  UVector3 normal12 = fFacet1.GetSurfaceNormal() + fFacet2.GetSurfaceNormal();
76  UVector3 normal34 = facet3.GetSurfaceNormal() + facet4.GetSurfaceNormal();
77  UVector3 normal = 0.25 * (normal12 + normal34);
78 
79  fFacet1.SetSurfaceNormal(normal);
80  fFacet2.SetSurfaceNormal(normal);
81 
82  UVector3 vtmp = 0.5 * (e1 + e2);
83  fCircumcentre = GetVertex(0) + vtmp;
84  double radiusSqr = vtmp.Mag2();
85  fRadius = std::sqrt(radiusSqr);
86  }
87  else
88  {
89  UUtils::Exception("UQuadrangularFacet::UQuadrangularFacet()", "InvalidSetup", Warning, 1, "Length of sides of facet are too small or sides not planar.");
90  cerr << endl;
91  cerr << "P0 = " << GetVertex(0) << endl;
92  cerr << "P1 = " << GetVertex(1) << endl;
93  cerr << "P2 = " << GetVertex(2) << endl;
94  cerr << "P3 = " << GetVertex(3) << endl;
95  cerr << "Side lengths = P0->P1" << length1 << endl;
96  cerr << "Side lengths = P1->P2" << length2 << endl;
97  cerr << "Side lengths = P2->P3" << length3 << endl;
98  cerr << "Side lengths = P3->P0" << length4 << endl;
99  cerr << endl;
100  fRadius = 0;
101  }
102 }
103 
105 //
107 {
108 }
109 
111 //
113 {
114  fFacet1 = rhs.fFacet1;
115  fFacet2 = rhs.fFacet2;
116  fRadius = 0;
117 }
118 
120 //
122 {
123  if (this == &rhs)
124  return *this;
125 
126  fFacet1 = rhs.fFacet1;
127  fFacet2 = rhs.fFacet2;
128 
129  fRadius = 0;
130 
131  return *this;
132 }
133 
135 //
137 {
139  return c;
140 }
141 
143 //
145 {
146  UVector3 v1 = fFacet1.Distance(p);
147  UVector3 v2 = fFacet2.Distance(p);
148 
149  if (v1.Mag2() < v2.Mag2()) return v1;
150  else return v2;
151 }
152 
154 //
156  const double)
157 {
158  double dist = Distance(p).Mag();
159  return dist;
160 }
161 
163 //
164 double UQuadrangularFacet::Distance(const UVector3& p, const double, const bool outgoing)
165 {
166  double dist;
167 
168  UVector3 v = Distance(p);
169  double dir = v.Dot(GetSurfaceNormal());
170  if ((dir > dirTolerance && !outgoing) || (dir < -dirTolerance && outgoing))
171  dist = UUtils::kInfinity;
172  else
173  dist = v.Mag();
174  return dist;
175 }
176 
178 {
179  double ss = 0;
180 
181  for (int i = 0; i <= 3; ++i)
182  {
183  double sp = GetVertex(i).Dot(axis);
184  if (sp > ss) ss = sp;
185  }
186  return ss;
187 }
188 
189 bool UQuadrangularFacet::Intersect(const UVector3& p, const UVector3& v, bool outgoing, double& distance, double& distFromSurface, UVector3& normal)
190 {
191  bool intersect = fFacet1.Intersect(p, v, outgoing, distance, distFromSurface, normal);
192  if (!intersect) intersect = fFacet2.Intersect(p, v, outgoing, distance, distFromSurface, normal);
193  if (!intersect)
194  {
195  distance = distFromSurface = UUtils::kInfinity;
196  normal.Set(0);
197  }
198  return intersect;
199 }
200 
201 // Auxiliary method for get a random point on surface
203 {
205  return pr;
206 }
207 
208 // Auxiliary method for returning the surface area
210 {
211  double area = fFacet1.GetArea() + fFacet2.GetArea();
212  return area;
213 }
214 
216 {
217  return "UQuadrangularFacet";
218 }
219 
221 {
222  return fFacet1.GetSurfaceNormal();
223 }
double Mag2() const
Definition: UVector3.hh:267
UTriangularFacet fFacet1
virtual UGeometryType GetEntityType() const
static const double dirTolerance
Definition: VUFacet.hh:88
UVector3 GetPointOnFace() const
UVector3 Distance(const UVector3 &p)
UVector3 GetSurfaceNormal() const
UVector3 Cross(const UVector3 &) const
Definition: UVector3.hh:262
static const G4double e2
UQuadrangularFacet & operator=(const UQuadrangularFacet &right)
UFacetVertexType
Definition: VUFacet.hh:49
static double Tolerance()
Definition: VUSolid.hh:127
static double normal(HepRandomEngine *eptr)
Definition: RandPoisson.cc:77
UQuadrangularFacet(const UVector3 &Pt0, const UVector3 &vt1, const UVector3 &vt2, const UVector3 &vt3, UFacetVertexType)
static const double kInfinity
Definition: UUtils.hh:53
double Extent(const UVector3 axis)
double Dot(const UVector3 &) const
Definition: UVector3.hh:257
double Mag() const
Definition: UVector3.cc:48
static const G4double e1
void Exception(const char *originOfException, const char *exceptionCode, UExceptionSeverity severity, int level, const char *description)
Definition: UUtils.cc:122
void Set(double xx, double yy, double zz)
Definition: UVector3.hh:245
UVector3 Unit() const
Definition: UVector3.cc:80
UTriangularFacet fFacet2
UVector3 GetPointOnFace() const
UVector3 GetVertex(int i) const
bool Intersect(const UVector3 &p, const UVector3 &v, const bool outgoing, double &distance, double &distFromSurface, UVector3 &normal)
static const G4double e3
UVector3 GetSurfaceNormal() const
double Random(double min=0.0, double max=1.0)
Definition: UUtils.cc:69
bool Intersect(const UVector3 &p, const UVector3 &v, const bool outgoing, double &distance, double &distFromSurface, UVector3 &normal)
UVector3 Distance(const UVector3 &p)