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

Last change on this file since 1315 was 1228, checked in by garnier, 14 years ago

update geant4.9.3 tag

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-03 $
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.