Geant4 9.6.0
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
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//
28// $Id$
29//
30// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
31//
32// CHANGE HISTORY
33// --------------
34//
35// 07 August 2007, P R Truscott, QinetiQ Ltd, UK - Created, with member
36// functions based on the work of Rickard Holmberg.
37//
38// 26 September 2007
39// P R Truscott, qinetiQ Ltd, UK
40// Updated to assign values of location array, not update
41// just the pointer.
42//
43// 12 October 2012, M Gayer, CERN, - Reviewed optimized implementation.
44//
45///////////////////////////////////////////////////////////////////////////////
46
48
49#include <cfloat>
50
51///////////////////////////////////////////////////////////////////////////////
52//
53// IntersectLineAndTriangle2D
54//
55// Determines whether there is an intersection between a line defined
56// by r = p + s.v and a triangle defined by verticies p0, p0+e0 and p0+e1.
57//
58// Here:
59// p = 2D vector
60// s = scaler on [0,infinity)
61// v = 2D vector
62// p0, e0 and e1 are 2D vectors
63// Information about where the intersection occurs is returned in the
64// variable location.
65//
66// This is based on the work of Rickard Holmberg.
67//
69 const G4TwoVector &p, const G4TwoVector &v,
70 const G4TwoVector &p0, const G4TwoVector &e0, const G4TwoVector &e1,
71 G4TwoVector location[2])
72{
73 G4TwoVector loc0[2];
74 G4int e0i = IntersectLineAndLineSegment2D (p,v,p0,e0,loc0);
75 if (e0i == 2)
76 {
77 location[0] = loc0[0];
78 location[1] = loc0[1];
79 return true;
80 }
81
82 G4TwoVector loc1[2];
83 G4int e1i = IntersectLineAndLineSegment2D (p,v,p0,e1,loc1);
84 if (e1i == 2)
85 {
86 location[0] = loc1[0];
87 location[1] = loc1[1];
88 return true;
89 }
90
91 if ((e0i == 1) && (e1i == 1))
92 {
93 if ((loc0[0]-p).mag2() < (loc1[0]-p).mag2())
94 {
95 location[0] = loc0[0];
96 location[1] = loc1[0];
97 }
98 else
99 {
100 location[0] = loc1[0];
101 location[1] = loc0[0];
102 }
103 return true;
104 }
105
106 G4TwoVector p1 = p0 + e0;
107 G4TwoVector DE = e1 - e0;
108 G4TwoVector loc2[2];
109 G4int e2i = IntersectLineAndLineSegment2D (p,v,p1,DE,loc2);
110 if (e2i == 2)
111 {
112 location[0] = loc2[0];
113 location[1] = loc2[1];
114 return true;
115 }
116
117 if ((e0i == 0) && (e1i == 0) && (e2i == 0)) return false;
118
119 if ((e0i == 1) && (e2i == 1))
120 {
121 if ((loc0[0]-p).mag2() < (loc2[0]-p).mag2())
122 {
123 location[0] = loc0[0];
124 location[1] = loc2[0];
125 }
126 else
127 {
128 location[0] = loc2[0];
129 location[1] = loc0[0];
130 }
131 return true;
132 }
133
134 if ((e1i == 1) && (e2i == 1))
135 {
136 if ((loc1[0]-p).mag2() < (loc2[0]-p).mag2())
137 {
138 location[0] = loc1[0];
139 location[1] = loc2[0];
140 }
141 else
142 {
143 location[0] = loc2[0];
144 location[1] = loc1[0];
145 }
146 return true;
147 }
148
149 return false;
150}
151
152///////////////////////////////////////////////////////////////////////////////
153//
154// IntersectLineAndLineSegment2D
155//
156// Determines whether there is an intersection between a line defined
157// by r = p0 + s.d0 and a line-segment with endpoints p1 and p1+d1.
158// Here:
159// p0 = 2D vector
160// s = scaler on [0,infinity)
161// d0 = 2D vector
162// p1 and d1 are 2D vectors
163//
164// This function returns:
165// 0 - if there is no intersection;
166// 1 - if there is a unique intersection;
167// 2 - if the line and line-segments overlap, and the intersection is a
168// segment itself.
169// Information about where the intersection occurs is returned in the
170// as ??.
171//
172// This is based on the work of Rickard Holmberg as well as material published
173// by Philip J Schneider and David H Eberly, "Geometric Tools for Computer
174// Graphics," ISBN 1-55860-694-0, pp 244-245, 2003.
175//
177 const G4TwoVector &p0, const G4TwoVector &d0,
178 const G4TwoVector &p1, const G4TwoVector &d1,
179 G4TwoVector location[2])
180{
181 G4TwoVector e = p1 - p0;
182 G4double kross = cross(d0,d1);
183 G4double sqrKross = kross * kross;
184 G4double sqrLen0 = d0.mag2();
185 G4double sqrLen1 = d1.mag2();
186 location[0] = G4TwoVector(0.0,0.0);
187 location[1] = G4TwoVector(0.0,0.0);
188
189 if (sqrKross > DBL_EPSILON * DBL_EPSILON * sqrLen0 * sqrLen1)
190 {
191 //
192 // The line and line segment are not parallel. Determine if the intersection
193 // is in positive s where r=p0 + s*d0, and for 0<=t<=1 where r=p1 + t*d1.
194 //
195 G4double ss = cross(e,d1)/kross;
196 if (ss < 0) return 0; // Intersection does not occur for positive ss
197 G4double t = cross(e,d0)/kross;
198 if (t < 0 || t > 1) return 0; // Intersection does not occur on line-segment
199 //
200 // Intersection of lines is a single point on the forward-propagating line
201 // defined by r=p0 + ss*d0, and the line segment defined by r=p1 + t*d1.
202 //
203 location[0] = p0 + ss*d0;
204 return 1;
205 }
206 //
207 // Line and line segment are parallel. Determine whether they overlap or not.
208 //
209 G4double sqrLenE = e.mag2();
210 kross = cross(e,d0);
211 sqrKross = kross * kross;
212 if (sqrKross > DBL_EPSILON * DBL_EPSILON * sqrLen0 * sqrLenE)
213 {
214 return 0; //Lines are different.
215 }
216 //
217 // Lines are the same. Test for overlap.
218 //
219 G4double s0 = d0.dot(e)/sqrLen0;
220 G4double s1 = s0 + d0.dot(d1)/sqrLen0;
221 G4double smin = 0.0;
222 G4double smax = 0.0;
223
224 if (s0 < s1) {smin = s0; smax = s1;}
225 else {smin = s1; smax = s0;}
226
227 if (smax < 0.0) return 0;
228 else if (smin < 0.0)
229 {
230 location[0] = p0;
231 location[1] = p0 + smax*d0;
232 return 2;
233 }
234 else
235 {
236 location[0] = p0 + smin*d0;
237 location[1] = p0 + smax*d0;
238 return 2;
239 }
240}
241
242///////////////////////////////////////////////////////////////////////////////
243//
244// CrossProduct
245//
246// This is just a ficticious "cross-product" function for two 2D vectors...
247// "ficticious" because such an operation is not relevant to 2D space compared
248// with 3D space.
249//
251 const G4TwoVector &v2)
252{
253 return v1.x()*v2.y() - v1.y()*v2.x();
254}
CLHEP::Hep2Vector G4TwoVector
Definition: G4TwoVector.hh:42
double G4double
Definition: G4Types.hh:64
int G4int
Definition: G4Types.hh:66
bool G4bool
Definition: G4Types.hh:67
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:87