source: trunk/source/geometry/solids/BREPS/src/G4Surface.cc @ 1228

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

update geant4.9.3 tag

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