ECCE @ EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
G4TessellatedGeometryAlgorithms.cc
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file G4TessellatedGeometryAlgorithms.cc
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 }