Geant4  9.6.p02
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
G4Surface.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 // G4Surface.cc
33 //
34 // ----------------------------------------------------------------------
35 
36 #include "G4Surface.hh"
37 #include "G4CompositeCurve.hh"
38 #include "G4GeometryTolerance.hh"
39 
41  : G4STEPEntity(),
42  bbox(0), next(0), Intersected(0), Type(0), AdvancedFace(0),
43  active(1), distance(kInfinity), uhit(0.), vhit(0.), sameSense(0)
44 {
47 }
48 
49 
51 {
52 }
53 
54 
56  : G4STEPEntity(),
57  bbox(c.bbox), next(c.next), Intersected(c.Intersected), Type(c.Type),
58  AdvancedFace(c.AdvancedFace), active(c.active), distance(c.distance),
59  uhit(c.uhit), vhit(c.vhit), sameSense(c.sameSense)
60 {
63 }
64 
65 
66 G4Surface&
67 G4Surface::operator=( const G4Surface& c )
68 {
69  if (&c == this) { return *this; }
70  bbox = c.bbox;
71  next = c.next;
73  Type = c.Type;
75  active = c.active;
76  distance = c.distance;
77  uhit = c.uhit;
78  vhit = c.vhit;
79 
82 
83  return *this;
84 }
85 
86 
88 {
89  return origin == surf.origin;
90 }
91 
93 {
94  return G4String("Surface");
95 }
96 
97 const char* G4Surface::Name() const
98 {
99  return "G4Surface";
100 }
101 
103 {
104  return Type;
105 }
106 
108 {
109 }
110 
112 {
113  return uhit;
114 }
115 
117 {
118  return vhit;
119 }
120 
121 //void G4Surface::read_surface(fstream& tmp){;}
122 
124 {
125  return closest_hit;
126 }
127 
129 {
130  return 0;
131 }
132 
134 {
135  Intersected = 0;
136  active = 1;
137  distance = kInfinity;
138 }
139 
141 {
142  surfaceBoundary.Init(*boundaries);
143  InitBounded();
144 }
145 
147 {
148  // Finds the bounds of the surface iow
149  // calculates the bounds for a bounding box
150  // to the surface. The bounding box is used
151  // for a preliminary check of intersection.
152 
155  // old implementation
156  // G4Point3d BoundaryMax = OuterBoundary->GetBoundsMax();
157  // G4Point3d BoundaryMin = OuterBoundary->GetBoundsMin();
158  // bbox = new G4BoundingBox( BoundaryMin, BoundaryMax);
159  // return;
160 }
161 
163 { // return the Normal unit vector to a Surface at the point p on
164  // (or nearly on) the Surface.
165  // The default is not well defined, so return ( 0, 0, 0 ).
166  return G4Vector3D( 0.0, 0.0, 0.0 );
167 }
168 
169 
171 {
172  G4int Result = 0;
173 
174  G4Exception("G4Surface::Intersect()", "GeomSolids0001",
175  FatalException, "Sorry, not yet implemented.");
176 
177 #ifdef NEW_IMPLEMENTATION
178  // get the intersection
179  // Result = Intersect(rayref);
180 
181  // Check that the point is within the polyline
182  // Get Normal at Hitpoint
183  const G4Vector3D& Vec = Normal(closest_hit);
184  G4Ray Normal(closest_hit, Vec);
185 
186  // Project points & Hit
187  // OuterBoundary->ProjectBoundaryTo2D(Normal.GetPlane(1),
188  // Normal.GetPlane(2), 0);
189 
190 
191 
192 
193  G4Point3D Hit = closest_hit.Project(Normal.GetPlane(1),
194  Normal.GetPlane(2) );
195  // Check point in polygon
196  // Result = OuterBoundary->Inside(Hit, rayref);
197 
198 #endif
199  return Result;
200 }
201 
202 
204 {
205  // in fact, a squared distance is returned
206 
207  // a bit suspicious, this function
208  // the distance is almost always an overestimate
209  G4double pointDistance= kInfinity;
210  G4double tmpDistance;
211  const G4CurveVector& bounds= surfaceBoundary.GetBounds();
212 
213  G4int entr = bounds.size();
214 
215  for (G4int i=0; i<entr; i++)
216  {
217  G4Curve* c= bounds[i];
218 
219  if (c->GetEntityType() == "G4CompositeCurve")
220  {
222  const G4CurveVector& segments= cc->GetSegments();
223  for (size_t j=0; j<segments.size(); j++)
224  {
225  G4Curve* ccc= segments[j];
226  tmpDistance= (G4Point3D(Pt.x(), Pt.y(), Pt.z())-ccc->GetEnd()).mag2();
227  if (pointDistance > tmpDistance)
228  {
229  pointDistance= tmpDistance;
230  }
231  }
232 
233  }
234  else
235  {
236  tmpDistance= (G4Point3D(Pt.x(), Pt.y(), Pt.z())-c->GetEnd()).mag2();
237  if (pointDistance > tmpDistance)
238  {
239  pointDistance= tmpDistance;
240  }
241  }
242  }
243 
244  // L. Broglia
245  // Be carreful ! pointdistance is the squared distance
246  return std::sqrt(pointDistance);
247 
248  // G4double PointDistance=kInfinity;
249  // G4double TmpDistance=0;
250  // PointDistance = OuterBoundary->ClosestDistanceToPoint(Pt);
251  // TmpDistance =0;
252  // for(G4int a=0;a<NumberOfInnerBoundaries;a++)
253  // {
254  // TmpDistance = InnerBoundary[a]->ClosestDistanceToPoint(Pt);
255  // if(PointDistance > TmpDistance) PointDistance = TmpDistance;
256  // }
257  // return PointDistance;
258 
259  //G4double G4Boundary::ClosestDistanceToPoint(const G4ThreeVec& Pt)
260  //{
261  // G4double PointDistance = kInfinity;
262  // G4double TmpDistance = 0;
263  // for(G4int a =0; a < NumberOfPoints;a++)
264  // {
265  // G4Point3d& Pt2 = GetPoint(a);
266  // TmpDistance = Pt2.Distance(Pt);
267  // if(PointDistance > TmpDistance)PointDistance = TmpDistance;
268  // }
269  // return PointDistance;
270  //}
271 }
272 
273 
274 std::ostream& operator<<( std::ostream& os, const G4Surface& )
275 {
276  // overwrite output operator << to Print out Surface objects
277  // using the PrintOn function defined below
278  // s.PrintOn( os );
279  return os;
280 }
281 
282 
284 {
285  // Distance from the point x to a Surface.
286  // The default for a Surface is the distance from the point to the origin.
287  G4Vector3D p = G4Vector3D( x - origin );
288  return p.mag();
289 }
290 
292 {
293 }
294 
296 {
297 }
298 
300 {
301  return -1;
302 }
303 
305 {
306  return 0;
307 }
308 
310 {
311  return 0;
312 }
313 
315 {
316  const G4Point3D* tmp= new G4Point3D(0,0,0);
317  return *tmp;
318 }
319 
321 {
322  return (G4Ray*)0;
323 }
324 
326  const G4Point3D& Pt2,
327  const G4Plane& Pl1)
328 {
329  Coord = Pt2.x()*Pl1.a + Pt2.y()*Pl1.b + Pt2.z()*Pl1.c - Pl1.d;
330 }
331 
332 /*
333 G4double G4Surface::distanceAlongRay( G4int which_way, const G4Ray* ry,
334  G4ThreeVec& p ) const
335 { // Distance along a Ray (straight line with G4ThreeVec) to leave or enter
336  // a Surface. The input variable which_way should be set to +1 to indicate
337  // leaving a Surface, -1 to indicate entering a Surface.
338  // p is the point of intersection of the Ray with the Surface.
339  // This is a default function which just gives the distance
340  // between the origin of the Ray and the origin of the Surface.
341  // Since a generic Surface doesn't have a well-defined Normal, no
342  // further checks are Done.
343 
344  // This should always be overwritten for derived classes so Print out
345  // a warning message if this is called.
346  G4cout << "WARNING from Surface::distanceAlongRay\n"
347  << " This function should be overwritten by a derived class.\n"
348  << " Using the Surface base class default.\n";
349  p = GetOrigin();
350  G4ThreeVec d = ry->Position() - p;
351  return d.Magnitude();
352 }
353 
354 G4double G4Surface::distanceAlongHelix( G4int which_way, const Helix* hx,
355  G4ThreeVec& p ) const
356 { // Distance along a Helix to leave or enter a Surface.
357  // The input variable which_way should be set to +1 to indicate
358  // leaving a Surface, -1 to indicate entering a Surface.
359  // p is the point of intersection of the Helix with the Surface.
360  // This is a default function which just gives the distance
361  // between the origin of the Helix and the origin of the Surface.
362  // Since a generic Surface doesn't have a well-defined Normal, no
363  // further checks are Done.
364 
365  // This should always be overwritten for derived classes so Print out
366  // a warning message if this is called.
367  G4cout << "WARNING from Surface::distanceAlongHelix\n"
368  << " This function should be overwritten by a derived class.\n"
369  << " Using the Surface base class default.\n";
370  p = GetOrigin();
371  G4ThreeVec d = hx->position() - p;
372  return d.Magnitude();
373 }
374 
375 
376 G4ThreeVec G4Surface::Normal() const
377 { // return the Normal unit vector to a Surface
378  // (This is only meaningful for Surfaces for which the Normal does
379  // not depend on location on the Surface).
380  // The default is not well defined, so return ( 0, 0, 0 ).
381  return G4ThreeVec( 0.0, 0.0, 0.0 );
382 }
383 
384 
385 G4ThreeVec G4Surface::Normal( const G4ThreeVec& ) const
386 { // return the Normal unit vector to a Surface at the point p on
387  // (or nearly on) the Surface.
388  // The default is not well defined, so return ( 0, 0, 0 ).
389  return G4ThreeVec( 0.0, 0.0, 0.0 );
390 }
391 
392 G4int G4Surface::Inside( const G4ThreeVec& ) const
393 { // return 0 if point p is outside Surface, 1 if Inside
394  // default is not well defined, so return 0
395  return 0;
396 }
397 
398 void G4Surface::move( const G4ThreeVec& p )
399 { // translate origin of Surface by vector p
400  origin += p;
401 }
402 
403 void G4Surface::rotate( G4double alpha, G4double beta,
404  G4double gamma, G4ThreeMat& m, G4int inverse )
405 { // rotate Surface first about global x-axis by angle alpha,
406  // second about global y-axis by angle beta,
407  // and third about global z-axis by angle gamma
408  // by creating and using G4ThreeMat objects
409  // angles are assumed to be given in radians
410  // returns also the overall rotation matrix for use by subclasses
411  // if inverse is non-zero, the order of rotations is reversed
412  // for a generic Surface, only the origin is rotated
413 // G4double ax[3][3] = { 0., 0., 0., 0., 0., 0., 0., 0., 0. };
414  G4double ax[3][3];
415  G4double ay[3][3];
416  G4double az[3][3];
417 // G4double ay[3][3] = { 0., 0., 0., 0., 0., 0., 0., 0., 0. };
418 // G4double az[3][3] = { 0., 0., 0., 0., 0., 0., 0., 0., 0. };
419  ax[0][0] = 1.;
420  ax[1][1] = std::cos( alpha );
421  ax[2][2] = ax[1][1];
422  ax[2][1] = std::sin( alpha );
423  ax[1][2] = -ax[2][1];
424  ay[1][1] = 1.;
425  ay[0][0] = std::cos( beta );
426  ay[2][2] = ay[0][0];
427  ay[0][2] = std::sin( beta );
428  ay[2][0] = -ay[0][2];
429  az[2][2] = 1.;
430  az[0][0] = std::cos( gamma );
431  az[1][1] = az[0][0];
432  az[1][0] = std::sin( gamma );
433  az[0][1] = -az[1][0];
434  G4ThreeMat &Rx = *new G4ThreeMat( ax ); // x-rotation matrix
435  G4ThreeMat &Ry = *new G4ThreeMat( ay ); // y-rotation matrix
436  G4ThreeMat &Rz = *new G4ThreeMat( az ); // z-rotation matrix
437  if ( inverse )
438  m = Rx * ( Ry * Rz );
439  else
440  m = Rz * ( Ry * Rx );
441  origin = m * origin;
442 }
443 
444 void G4Surface::rotate( G4double alpha, G4double beta,
445  G4double gamma, G4int inverse )
446 { // rotate Surface first about global x-axis by angle alpha,
447  // second about global y-axis by angle beta,
448  // and third about global z-axis by angle gamma
449  // by creating and using G4ThreeMat objects
450  // angles are assumed to be given in radians
451  // if inverse is non-zero, the order of rotations is reversed
452  G4ThreeMat m;
453 // Just call the above function to do this rotation
454  rotate( alpha, beta, gamma, m, inverse );
455 }
456 
457 */