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

Last change on this file since 1051 was 850, checked in by garnier, 17 years ago

geant4.8.2 beta

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