source: trunk/source/geometry/solids/specific/src/G4TessellatedGeometryAlgorithms.cc@ 1347

Last change on this file since 1347 was 1337, checked in by garnier, 15 years ago

tag geant4.9.4 beta 1 + modifs locales

File size: 8.5 KB
Line 
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: G4TessellatedGeometryAlgorithms.cc,v 1.6 2008/12/18 12:57:36 gunter Exp $
29// GEANT4 tag $Name: geant4-09-04-beta-01 $
30//
31// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
32//
33// MODULE: G4TessellatedGeometryAlgorithms.cc
34//
35// Date: 07/08/2005
36// Author: Rickard Holmberg & Pete Truscott
37// Organisation: QinetiQ Ltd, UK (PT)
38// Customer: ESA-ESTEC / TEC-EES
39// Contract:
40//
41// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
42//
43// CHANGE HISTORY
44// --------------
45//
46// 07 August 2007, P R Truscott, QinetiQ Ltd, UK - Created, with member
47// functions based on the work of Rickard Holmberg.
48//
49// 26 September 2007
50// P R Truscott, qinetiQ Ltd, UK
51// Updated to assign values of location array, not update
52// just the pointer.
53//
54///////////////////////////////////////////////////////////////////////////////
55
56#include "G4TessellatedGeometryAlgorithms.hh"
57///////////////////////////////////////////////////////////////////////////////
58//
59// Pointer to single instance of class.
60//
61G4TessellatedGeometryAlgorithms* G4TessellatedGeometryAlgorithms::fInstance = 0;
62
63///////////////////////////////////////////////////////////////////////////////
64//
65// G4TessellatedGeometryAlgorithms
66//
67// Constructor doesn't need to do anything since this class just allows access
68// to the geometric algorithms contained in member functions.
69//
70G4TessellatedGeometryAlgorithms::G4TessellatedGeometryAlgorithms ()
71{
72}
73
74///////////////////////////////////////////////////////////////////////////////
75//
76// GetInstance
77//
78// This is the access point for this singleton.
79//
80G4TessellatedGeometryAlgorithms* G4TessellatedGeometryAlgorithms::GetInstance()
81{
82 static G4TessellatedGeometryAlgorithms worldStdGeom;
83 if (!fInstance)
84 {
85 fInstance = &worldStdGeom;
86 }
87 return fInstance;
88}
89
90///////////////////////////////////////////////////////////////////////////////
91//
92// IntersectLineAndTriangle2D
93//
94// Determines whether there is an intersection between a line defined
95// by r = p + s.v and a triangle defined by verticies P0, P0+E0 and P0+E1.
96//
97// Here:
98// p = 2D vector
99// s = scaler on [0,infinity)
100// v = 2D vector
101// P0, E0 and E1 are 2D vectors
102// Information about where the intersection occurs is returned in the
103// variable location.
104//
105// This is based on the work of Rickard Holmberg.
106//
107G4bool G4TessellatedGeometryAlgorithms::IntersectLineAndTriangle2D (
108 const G4TwoVector p, const G4TwoVector v,
109 const G4TwoVector P0, const G4TwoVector E0, const G4TwoVector E1,
110 G4TwoVector location[2])
111{
112 G4TwoVector loc0[2];
113 G4int e0i = IntersectLineAndLineSegment2D (p,v,P0,E0,loc0);
114 if (e0i == 2)
115 {
116 location[0] = loc0[0];
117 location[1] = loc0[1];
118 return true;
119 }
120
121 G4TwoVector loc1[2];
122 G4int e1i = IntersectLineAndLineSegment2D (p,v,P0,E1,loc1);
123 if (e1i == 2)
124 {
125 location[0] = loc1[0];
126 location[1] = loc1[1];
127 return true;
128 }
129
130 if ((e0i == 1) && (e1i == 1))
131 {
132 if ((loc0[0]-p).mag2() < (loc1[0]-p).mag2())
133 {
134 location[0] = loc0[0];
135 location[1] = loc1[0];
136 }
137 else
138 {
139 location[0] = loc1[0];
140 location[1] = loc0[0];
141 }
142 return true;
143 }
144
145 G4TwoVector P1 = P0 + E0;
146 G4TwoVector DE = E1 - E0;
147 G4TwoVector loc2[2];
148 G4int e2i = IntersectLineAndLineSegment2D (p,v,P1,DE,loc2);
149 if (e2i == 2)
150 {
151 location[0] = loc2[0];
152 location[1] = loc2[1];
153 return true;
154 }
155
156 if ((e0i == 0) && (e1i == 0) && (e2i == 0)) { return false; }
157
158 if ((e0i == 1) && (e2i == 1))
159 {
160 if ((loc0[0]-p).mag2() < (loc2[0]-p).mag2())
161 {
162 location[0] = loc0[0];
163 location[1] = loc2[0];
164 }
165 else
166 {
167 location[0] = loc2[0];
168 location[1] = loc0[0];
169 }
170 return true;
171 }
172
173 if ((e1i == 1) && (e2i == 1))
174 {
175 if ((loc1[0]-p).mag2() < (loc2[0]-p).mag2())
176 {
177 location[0] = loc1[0];
178 location[1] = loc2[0];
179 }
180 else
181 {
182 location[0] = loc2[0];
183 location[1] = loc1[0];
184 }
185 return true;
186 }
187
188 return false;
189}
190
191///////////////////////////////////////////////////////////////////////////////
192//
193// IntersectLineAndLineSegment2D
194//
195// Determines whether there is an intersection between a line defined
196// by r = P0 + s.D0 and a line-segment with endpoints P1 and P1+D1.
197// Here:
198// P0 = 2D vector
199// s = scaler on [0,infinity)
200// D0 = 2D vector
201// P1 and D1 are 2D vectors
202//
203// This function returns:
204// 0 - if there is no intersection;
205// 1 - if there is a unique intersection;
206// 2 - if the line and line-segments overlap, and the intersection is a
207// segment itself.
208// Information about where the intersection occurs is returned in the
209// as ??.
210//
211// This is based on the work of Rickard Holmberg as well as material published
212// by Philip J Schneider and David H Eberly, "Geometric Tools for Computer
213// Graphics," ISBN 1-55860-694-0, pp 244-245, 2003.
214//
215G4int G4TessellatedGeometryAlgorithms::IntersectLineAndLineSegment2D (
216 const G4TwoVector P0, const G4TwoVector D0,
217 const G4TwoVector P1, const G4TwoVector D1,
218 G4TwoVector location[2])
219{
220 G4TwoVector E = P1 - P0;
221 G4double kross = cross(D0,D1);
222 G4double sqrKross = kross * kross;
223 G4double sqrLen0 = D0.mag2();
224 G4double sqrLen1 = D1.mag2();
225 location[0] = G4TwoVector(0.0,0.0);
226 location[1] = G4TwoVector(0.0,0.0);
227
228 if (sqrKross > DBL_EPSILON * DBL_EPSILON * sqrLen0 * sqrLen1)
229 {
230//
231//
232// The line and line segment are not parallel. Determine if the intersection
233// is in positive s where r = P0 + s*D0, and for 0<=t<=1 where r = p1 + t*D1.
234//
235 G4double s = cross(E,D1)/kross;
236 if (s < 0) return 0; // Intersection does not occur for positive s.
237 G4double t = cross(E,D0)/kross;
238 if (t < 0 || t > 1) return 0; // Intersection does not occur on line-segment.
239//
240//
241// Intersection of lines is a single point on the forward-propagating line
242// defined by r = P0 + s*D0, and the line segment defined by r = p1 + t*D1.
243//
244 location[0] = P0 + s*D0;
245 return 1;
246 }
247//
248//
249// Line and line segment are parallel. Determine whether they overlap or not.
250//
251 G4double sqrLenE = E.mag2();
252 kross = cross(E,D0);
253 sqrKross = kross * kross;
254 if (sqrKross > DBL_EPSILON * DBL_EPSILON * sqrLen0 * sqrLenE)
255 {
256 return 0; //Lines are different.
257 }
258//
259//
260// Lines are the same. Test for overlap.
261//
262 G4double s0 = D0.dot(E)/sqrLen0;
263 G4double s1 = s0 + D0.dot(D1)/sqrLen0;
264 G4double smin = 0.0;
265 G4double smax = 0.0;
266
267 if (s0 < s1) {smin = s0; smax = s1;}
268 else {smin = s1; smax = s0;}
269
270 if (smax < 0.0) return 0;
271 else if (smin < 0.0)
272 {
273 location[0] = P0;
274 location[1] = P0 + smax*D0;
275 return 2;
276 }
277 else
278 {
279 location[0] = P0 + smin*D0;
280 location[1] = P0 + smax*D0;
281 return 2;
282 }
283}
Note: See TracBrowser for help on using the repository browser.