Geant4 11.1.1
Toolkit for the simulation of the passage of particles through matter
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
G4TessellatedGeometryAlgorithms.cc
Go to the documentation of this file.
1//
2// ********************************************************************
3// * License and Disclaimer *
4// * *
5// * The Geant4 software is copyright of the Copyright Holders of *
6// * the Geant4 Collaboration. It is provided under the terms and *
7// * conditions of the Geant4 Software License, included in the file *
8// * LICENSE and available at http://cern.ch/geant4/license . These *
9// * include a list of copyright holders. *
10// * *
11// * Neither the authors of this software system, nor their employing *
12// * institutes,nor the agencies providing financial support for this *
13// * work make any representation or warranty, express or implied, *
14// * regarding this software system or assume any liability for its *
15// * use. Please see the license in the file LICENSE and URL above *
16// * for the full disclaimer and the limitation of liability. *
17// * *
18// * This code implementation is the result of the scientific and *
19// * technical work of the GEANT4 collaboration and of QinetiQ Ltd, *
20// * subject to DEFCON 705 IPR conditions. *
21// * By using, copying, modifying or distributing the software (or *
22// * any work based on the software) you agree to acknowledge its *
23// * use in resulting scientific publications, and indicate your *
24// * acceptance of all terms of the Geant4 Software license. *
25// ********************************************************************
26//
27// G4TessellatedGeometryAlgorithms implementation
28//
29// 07 August 2007, P R Truscott, QinetiQ Ltd, UK - Created, with member
30// functions based on the work of Rickard Holmberg.
31// 12 October 2012, M Gayer, CERN, - Reviewed optimized implementation.
32// --------------------------------------------------------------------
33
35
36#include <cfloat>
37
38///////////////////////////////////////////////////////////////////////////////
39//
40// IntersectLineAndTriangle2D
41//
42// Determines whether there is an intersection between a line defined
43// by r = p + s.v and a triangle defined by verticies p0, p0+e0 and p0+e1.
44//
45// Here:
46// p = 2D vector
47// s = scaler on [0,infinity)
48// v = 2D vector
49// p0, e0 and e1 are 2D vectors
50// Information about where the intersection occurs is returned in the
51// variable location.
52//
53// This is based on the work of Rickard Holmberg.
54//
56 const G4TwoVector& p, const G4TwoVector& v,
57 const G4TwoVector& p0, const G4TwoVector& e0, const G4TwoVector& e1,
58 G4TwoVector location[2])
59{
60 G4TwoVector loc0[2];
61 G4int e0i = IntersectLineAndLineSegment2D (p,v,p0,e0,loc0);
62 if (e0i == 2)
63 {
64 location[0] = loc0[0];
65 location[1] = loc0[1];
66 return true;
67 }
68
69 G4TwoVector loc1[2];
70 G4int e1i = IntersectLineAndLineSegment2D (p,v,p0,e1,loc1);
71 if (e1i == 2)
72 {
73 location[0] = loc1[0];
74 location[1] = loc1[1];
75 return true;
76 }
77
78 if ((e0i == 1) && (e1i == 1))
79 {
80 if ((loc0[0]-p).mag2() < (loc1[0]-p).mag2())
81 {
82 location[0] = loc0[0];
83 location[1] = loc1[0];
84 }
85 else
86 {
87 location[0] = loc1[0];
88 location[1] = loc0[0];
89 }
90 return true;
91 }
92
93 G4TwoVector p1 = p0 + e0;
94 G4TwoVector DE = e1 - e0;
95 G4TwoVector loc2[2];
96 G4int e2i = IntersectLineAndLineSegment2D (p,v,p1,DE,loc2);
97 if (e2i == 2)
98 {
99 location[0] = loc2[0];
100 location[1] = loc2[1];
101 return true;
102 }
103
104 if ((e0i == 0) && (e1i == 0) && (e2i == 0)) return false;
105
106 if ((e0i == 1) && (e2i == 1))
107 {
108 if ((loc0[0]-p).mag2() < (loc2[0]-p).mag2())
109 {
110 location[0] = loc0[0];
111 location[1] = loc2[0];
112 }
113 else
114 {
115 location[0] = loc2[0];
116 location[1] = loc0[0];
117 }
118 return true;
119 }
120
121 if ((e1i == 1) && (e2i == 1))
122 {
123 if ((loc1[0]-p).mag2() < (loc2[0]-p).mag2())
124 {
125 location[0] = loc1[0];
126 location[1] = loc2[0];
127 }
128 else
129 {
130 location[0] = loc2[0];
131 location[1] = loc1[0];
132 }
133 return true;
134 }
135
136 return false;
137}
138
139///////////////////////////////////////////////////////////////////////////////
140//
141// IntersectLineAndLineSegment2D
142//
143// Determines whether there is an intersection between a line defined
144// by r = p0 + s.d0 and a line-segment with endpoints p1 and p1+d1.
145// Here:
146// p0 = 2D vector
147// s = scaler on [0,infinity)
148// d0 = 2D vector
149// p1 and d1 are 2D vectors
150//
151// This function returns:
152// 0 - if there is no intersection;
153// 1 - if there is a unique intersection;
154// 2 - if the line and line-segments overlap, and the intersection is a
155// segment itself.
156// Information about where the intersection occurs is returned in the
157// as ??.
158//
159// This is based on the work of Rickard Holmberg as well as material published
160// by Philip J Schneider and David H Eberly, "Geometric Tools for Computer
161// Graphics," ISBN 1-55860-694-0, pp 244-245, 2003.
162//
164 const G4TwoVector& p0, const G4TwoVector& d0,
165 const G4TwoVector& p1, const G4TwoVector& d1, G4TwoVector location[2])
166{
167 G4TwoVector e = p1 - p0;
168 G4double kross = cross(d0,d1);
169 G4double sqrKross = kross * kross;
170 G4double sqrLen0 = d0.mag2();
171 G4double sqrLen1 = d1.mag2();
172 location[0] = G4TwoVector(0.0,0.0);
173 location[1] = G4TwoVector(0.0,0.0);
174
175 if (sqrKross > DBL_EPSILON * DBL_EPSILON * sqrLen0 * sqrLen1)
176 {
177 //
178 // The line and line segment are not parallel. Determine if the intersection
179 // is in positive s where r=p0 + s*d0, and for 0<=t<=1 where r=p1 + t*d1.
180 //
181 G4double ss = cross(e,d1)/kross;
182 if (ss < 0) return 0; // Intersection does not occur for positive ss
183 G4double t = cross(e,d0)/kross;
184 if (t < 0 || t > 1) return 0; // Intersection does not occur on line-segment
185 //
186 // Intersection of lines is a single point on the forward-propagating line
187 // defined by r=p0 + ss*d0, and the line segment defined by r=p1 + t*d1.
188 //
189 location[0] = p0 + ss*d0;
190 return 1;
191 }
192 //
193 // Line and line segment are parallel. Determine whether they overlap or not.
194 //
195 G4double sqrLenE = e.mag2();
196 kross = cross(e,d0);
197 sqrKross = kross * kross;
198 if (sqrKross > DBL_EPSILON * DBL_EPSILON * sqrLen0 * sqrLenE)
199 {
200 return 0; //Lines are different.
201 }
202 //
203 // Lines are the same. Test for overlap.
204 //
205 G4double s0 = d0.dot(e)/sqrLen0;
206 G4double s1 = s0 + d0.dot(d1)/sqrLen0;
207 G4double smin = 0.0;
208 G4double smax = 0.0;
209
210 if (s0 < s1) {smin = s0; smax = s1;}
211 else {smin = s1; smax = s0;}
212
213 if (smax < 0.0) return 0;
214 else if (smin < 0.0)
215 {
216 location[0] = p0;
217 location[1] = p0 + smax*d0;
218 return 2;
219 }
220 else
221 {
222 location[0] = p0 + smin*d0;
223 location[1] = p0 + smax*d0;
224 return 2;
225 }
226}
227
228///////////////////////////////////////////////////////////////////////////////
229//
230// CrossProduct
231//
232// This is just a ficticious "cross-product" function for two 2D vectors...
233// "ficticious" because such an operation is not relevant to 2D space compared
234// with 3D space.
235//
237 const G4TwoVector& v2)
238{
239 return v1.x()*v2.y() - v1.y()*v2.x();
240}
CLHEP::Hep2Vector G4TwoVector
Definition: G4TwoVector.hh:36
double G4double
Definition: G4Types.hh:83
bool G4bool
Definition: G4Types.hh:86
int G4int
Definition: G4Types.hh:85
double mag2() const
double dot(const Hep2Vector &p) const
double x() const
double y() const
static G4bool IntersectLineAndTriangle2D(const G4TwoVector &p, const G4TwoVector &v, const G4TwoVector &p0, const G4TwoVector &e0, const G4TwoVector &e1, G4TwoVector location[2])
static G4double cross(const G4TwoVector &v1, const G4TwoVector &v2)
static G4int IntersectLineAndLineSegment2D(const G4TwoVector &p0, const G4TwoVector &d0, const G4TwoVector &p1, const G4TwoVector &d1, G4TwoVector location[2])
#define DBL_EPSILON
Definition: templates.hh:66