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

Last change on this file since 954 was 850, checked in by garnier, 16 years ago

geant4.8.2 beta

File size: 8.4 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// * 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 $
27// GEANT4 tag $Name: HEAD $
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.