Geant4  9.6.p02
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
G4Ray.cc
Go to the documentation of this file.
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. *
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 //
27 // $Id$
28 //
29 // ----------------------------------------------------------------------
30 // GEANT 4 class source file
31 //
32 // G4Ray.cc
33 //
34 // ----------------------------------------------------------------------
35 
36 #include "G4Ray.hh"
37 #include "G4PointRat.hh"
38 
40  : r_min(0.), r_max(0.)
41 {
42 }
43 
44 G4Ray::G4Ray(const G4Point3D& start0, const G4Vector3D& dir0)
45 {
46  Init(start0, dir0);
47 }
48 
50 {
51 }
52 
53 
54 const G4Plane& G4Ray::GetPlane(G4int number_of_plane) const
55 {
56  if(number_of_plane==1)
57  { return plane2; }
58  else
59  { return plane1; }
60 }
61 
62 
64 {
65  // Creates two orthogonal planes(plane1,plane2) the ray (rray)
66  // situated in the intersection of the planes. The planes are
67  // used to project the surface (nurb) in two dimensions.
68 
69  G4Vector3D RayDir = dir;
70  G4Point3D RayOrigin = start;
71 
72  G4Point3D p1, p2, p3, p4;
73  G4Vector3D dir1, dir2;
74  G4Vector3D invdir = G4Vector3D( PINFINITY );
75 
76  if(!NearZero(RayDir.x(), SQRT_SMALL_FASTF))
77  { invdir.setX(1.0 / RayDir.x()); }
78 
79  if(!NearZero(RayDir.y(), SQRT_SMALL_FASTF))
80  { invdir.setY(1.0 / RayDir.y()); }
81 
82  if(!NearZero(RayDir.z(), SQRT_SMALL_FASTF))
83  { invdir.setZ(1.0 / RayDir.z()); }
84 
85  MatVecOrtho(dir1, RayDir);
86 
87  Vcross( dir2, RayDir, dir1);
88  Vmove(p1, RayOrigin);
89  Vadd2(p2, RayOrigin, RayDir);
90  Vadd2(p3, RayOrigin, dir1);
91  Vadd2(p4, RayOrigin, dir2);
92 
93  CalcPlane3Pts( plane1, p1, p3, p2);
94  CalcPlane3Pts( plane2, p1, p2, p4);
95 }
96 
97 
98 void G4Ray::MatVecOrtho(register G4Vector3D &out,
99  register const G4Vector3D &in )
100 {
101  register G4double f;
102  G4int i_Which;
103 
104  if( NearZero(in.x(), 0.0001)
105  && NearZero(in.y(), 0.0001)
106  && NearZero(in.z(), 0.0001) )
107  {
108  Vsetall( out, 0 );
109  return;
110  }
111 
112  // Find component closest to zero
113  f = std::fabs(in.x());
114  i_Which=0;
115 
116  if( std::fabs(in.y()) < f )
117  {
118  f = std::fabs(in.y());
119  i_Which=1;
120  }
121 
122  if( std::fabs(in.z()) < f )
123  {
124  i_Which=2;
125  }
126 
127  if(!i_Which)
128  {
129  f = std::sqrt((in.y())*(in.y())+(in.z())*(in.z())); // hypot(in.y(),in.z())
130  }
131  else
132  {
133  if(i_Which==1)
134  {
135  f = std::sqrt((in.z())*(in.z())+(in.x())*(in.x())); // hypot(in.z(),in.x())
136  }
137  else
138  {
139  f = std::sqrt((in.x())*(in.x())+(in.y())*(in.y())); // hypot(in.x(),in.y())
140  }
141  }
142  if( NearZero( f, SMALL ) )
143  {
144  Vsetall( out, 0 );
145  return;
146  }
147 
148  f = 1.0/f;
149 
150  if(!i_Which)
151  {
152  out.setX(0.0);
153  out.setY(-in.z()*f);
154  out.setZ( in.y()*f);
155  }
156  else
157  {
158  if(i_Which==1)
159  {
160  out.setY(0.0);
161  out.setZ(-in.x()*f);
162  out.setX( in.y()*f);
163  }
164  else
165  {
166  out.setZ(0.0);
167  out.setX(-in.z()*f);
168  out.setY( in.y()*f);
169  }
170  }
171 }
172 
173 
174 // CALC_PLANE_3PTS
175 //
176 // Find the equation of a G4Plane that contains three points.
177 // Note that Normal vector created is expected to point out (see vmath.h),
178 // so the vector from A to C had better be counter-clockwise
179 // (about the point A) from the vector from A to B.
180 // This follows the outward-pointing Normal convention, and the
181 // right-hand rule for cross products.
182 //
183 /*
184  C
185  *
186  |\
187  | \
188  ^ N | \
189  | \ | \
190  | \ | \
191  |C-A \ | \
192  | \ | \
193  | \ | \
194  \| \
195  *---------*
196  A B
197  ----->
198  B-A
199 */
200 // If the points are given in the order A B C (eg, *counter*-clockwise),
201 // then the outward pointing surface Normal N = (B-A) x (C-A).
202 //
203 // Explicit Return -
204 // 0 OK
205 // -1 Failure. At least two of the points were not distinct,
206 // or all three were colinear.
207 //
208 // Implicit Return -
209 // G4Plane The G4Plane equation is stored here.
210 
211 
213  const G4Point3D& a,
214  const G4Point3D& b,
215  const G4Point3D& c )
216 {
217  // Creates the two orthogonal planes which are needed in projecting the
218  // surface into 2D.
219 
220  G4Vector3D B_A;
221  G4Vector3D C_A;
222  G4Vector3D C_B;
223 
224  register G4double mag;
225 
226  Vsub2( B_A, b, a );
227  Vsub2( C_A, c, a );
228  Vsub2( C_B, c, b );
229 
230  Vcross( plane1, B_A, C_A );
231 
232  // Ensure unit length Normal
233  mag = Magnitude(plane1);
234  if( mag <= SQRT_SMALL_FASTF )
235  {
236  return(-1);// FAIL
237  }
238 
239  mag = 1/mag;
240 
241  G4Plane pl2(plane1);
242  Vscale( plane1, pl2, mag );
243 
244  // Find distance from the origin to the G4Plane
245  plane1.d = Vdot( plane1, a );
246 
247  return(0); //ok
248 }
249 
250 
252 {
253  // Check that the ray has a G4Vector3D...
254  if (dir==G4Vector3D(0, 0, 0))
255  {
256  G4Exception("G4Ray::RayCheck()", "GeomSolids0002", FatalException,
257  "Invalid zero direction given !");
258  }
259 
260  // Make sure that the vector is unit length
261  dir= dir.unit();
262  r_min = 0;
263  r_max = 0;
264 }
265 
266 
267 void G4Ray::Vcross(G4Plane &a, const G4Vector3D &b, const G4Vector3D &c)
268 {
269  a.a = b.y() * c.z() - b.z() * c.y() ;
270  a.b = b.z() * c.x() - b.x() * c.z() ;
271  a.c = b.x() * c.y() - b.y() * c.x() ;
272 }
273 
274 
276 {
277  a.setX(b.y() * c.z() - b.z() * c.y()) ;
278  a.setY(b.z() * c.x() - b.x() * c.z()) ;
279  a.setZ(b.x() * c.y() - b.y() * c.x()) ;
280 }
281 
282 
284 {
285  a.setX(b.x());
286  a.setY(b.y());
287  a.setZ(b.z());
288 }
289 
290 
291 void G4Ray::Vadd2(G4Point3D &a, const G4Point3D &b, const G4Vector3D &c)
292 {
293  a.setX(b.x() + c.x()) ;
294  a.setY(b.y() + c.y()) ;
295  a.setZ(b.z() + c.z()) ;
296 }
297 
298 
299 void G4Ray::Vsub2(G4Vector3D &a, const G4Point3D &b, const G4Point3D &c)
300 {
301  a.setX(b.x() - c.x());
302  a.setY(b.y() - c.y());
303  a.setZ(b.z() - c.z());
304 }
305 
306 
308 {
309  a.a = b.a * c;
310  a.b = b.b * c;
311  a.c = b.c * c;
312 }
313 
314 
316 {
317  return (a.a * b.x() +
318  a.b * b.y() +
319  a.c * b.z());
320 }
321 
322 
324 {
325  return ( a.a * a.a + a.b * a.b + a.c *a.c );
326 }
327 
328 
330 {
331  return (std::sqrt( Magsq( a )) );
332 }