Geant4-11
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
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
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
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}
static const G4double e1[44]
static const G4double d1
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