Geant4  9.6.p02
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
G4FPlane.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 // G4FPlane.cc
33 //
34 // ----------------------------------------------------------------------
35 // Corrections by S.Giani:
36 // - The constructor using iVec now properly stores both the internal and
37 // external boundaries in the bounds vector.
38 // - Proper initialization of sameSense in both the constructors.
39 // - Addition of third argument (sense) in the second constructor to ensure
40 // consistent setting of the normal in all the client code.
41 // - Proper use of the tolerance in the Intersect function.
42 // ----------------------------------------------------------------------
43 
44 #include "G4FPlane.hh"
45 #include "G4SystemOfUnits.hh"
46 #include "G4CompositeCurve.hh"
47 
48 
49 G4FPlane::G4FPlane( const G4Vector3D& direction,
50  const G4Vector3D& axis ,
51  const G4Point3D& Pt0, G4int sense )
52  : pplace(direction, axis, Pt0), Convex(0), projectedBoundary(0)
53 {
54  G4Point3D Pt1 = G4Point3D( Pt0 + direction );
55 
56  // The plane include direction and axis is the normal,
57  // so axis^direction is included in the plane
58  G4Point3D Pt2 = G4Point3D( Pt0 + axis.cross(direction) );
59 
60  G4Ray::CalcPlane3Pts( Pl, Pt0, Pt1, Pt2 );
61 
62  active = 1;
63  sameSense = sense;
64  CalcNormal();
65  distance = kInfinity;
66  Type = 1;
67 }
68 
69 
71  const G4Point3DVector* iVec,
72  G4int sense)
73  : pplace( (*pVec)[0]-(*pVec)[1], // direction
74  ((*pVec)[pVec->size()-1]-(*pVec)[0])
75  .cross((*pVec)[0]-(*pVec)[1]), // axis
76  (*pVec)[0] ) // location
77 
78 {
79  G4Ray::CalcPlane3Pts( Pl, (*pVec)[0], (*pVec)[1], (*pVec)[2] );
80 
81  G4CurveVector bounds;
82  G4CompositeCurve* polygon;
83 
84  projectedBoundary = new G4SurfaceBoundary;
85 
86  sameSense = sense;
87 
88  // Outer boundary
89 
90  polygon= new G4CompositeCurve(*pVec);
91 
92  for (size_t i=0; i< polygon->GetSegments().size(); i++)
93  polygon->GetSegments()[i]->SetSameSense(sameSense);
94 
95  bounds.push_back(polygon);
96 
97  // Eventual inner boundary
98 
99  if (iVec)
100  {
101  polygon= new G4CompositeCurve(*iVec);
102 
103  for (size_t i=0; i< polygon->GetSegments().size(); i++)
104  polygon->GetSegments()[i]->SetSameSense(sameSense);
105 
106  bounds.push_back(polygon);
107  }
108 
109  // Set sense for boundaries
110 
111  for (size_t j=0; j< bounds.size(); j++)
112  bounds[j]->SetSameSense(sameSense);
113 
114 
115  SetBoundaries(&bounds);
116 
117  CalcNormal();
118  IsConvex();
119  distance = kInfinity;
120  Type=1;
121 }
122 
123 
125 {
126  delete NormalX;
127 }
128 
129 
131 {
132  // This is needed since the bounds are used for the Solid
133  // bbox calculation. The bbox test is NOT performed for
134  // planar surfaces.
135 
136  // Finds the bounds of the G4Plane surface iow
137  // calculates the bounds for a bounding box
138  // to the surface. The bounding box is used
139  // for a preliminary check of intersection.
140 
143 
144 }
145 
146 
148 {
149 /*
150  // Calc Normal for surface which is used for the projection
151  // Make planes
152  G4Vector3D norm;
153 
154  G4Vector3D RefDirection = pplace.GetRefDirection();
155  G4Vector3D Axis = pplace.GetAxis();
156 
157  // L. Broglia : before in G4Placement
158  if( RefDirection == Axis )
159  norm = RefDirection;
160  else
161  {
162  // L. Broglia : error on setY, and it`s better to use cross function
163  // norm.setX( RefDirection.y() * Axis.z() - RefDirection.z() * Axis.y() );
164  // norm.setY( RefDirection.x() * Axis.z() - RefDirection.z() * Axis.x() );
165  // norm.setZ( RefDirection.x() * Axis.y() - RefDirection.y() * Axis.x() );
166 
167  norm = RefDirection.cross(Axis);
168  }
169 
170  // const G4Point3D& tmp = pplace.GetSrfPoint();
171  const G4Point3D tmp = pplace.GetLocation();
172 */
173 
174  // L. Broglia
175  // The direction of the normal is the axis of his location
176  // Its sense depend on the orientation of the bounded curve
177  const G4Point3D tmp = pplace.GetLocation();
179  G4int sense = GetSameSense();
180 
181  if (sense)
182  norm = pplace.GetAxis();
183  else
184  norm = - pplace.GetAxis();
185 
186  NormalX = new G4Ray(tmp, norm);
187  NormalX->RayCheck();
188  NormalX->CreatePlanes();
189 }
190 
191 
193 {
194  // Project
195  // const G4Plane& Plane1 = NormalX->GetPlane(1);
196  // const G4Plane& Plane2 = NormalX->GetPlane(2);
197 
198  // probably not necessary
199  // projections of the boundary should be handled by the intersection
200  // OuterBoundary->ProjectBoundaryTo2D(Plane1, Plane2, 0);
201 }
202 
203 
205 {
206  return -1;
207 }
208 
209 
211 {
212  // This function count the number of intersections of a
213  // bounded surface by a ray.
214 
215 
216  // Find the intersection with the infinite plane
217  Intersected =1;
218 
219  // s is solution, line is p + tq, n is G4Plane Normal, r is point on G4Plane
220  // all parameters are pointers to arrays of three elements
221 
223  register G4double a, b, t;
224 
225  register const G4Vector3D& RayDir = rayref.GetDir();
226  register const G4Point3D& RayStart = rayref.GetStart();
227 
228  G4double dirx = RayDir.x();
229  G4double diry = RayDir.y();
230  G4double dirz = RayDir.z();
231 
232  G4Vector3D norm = (*NormalX).GetDir();
233  G4Point3D srf_point = pplace.GetLocation();
234 
235  b = norm.x() * dirx + norm.y() * diry + norm.z() * dirz;
236 
237  if ( std::fabs(b) < perMillion )
238  {
239  // G4cout << "\nLine is parallel to G4Plane.No Hit.";
240  }
241  else
242  {
243  G4double startx = RayStart.x();
244  G4double starty = RayStart.y();
245  G4double startz = RayStart.z();
246 
247  a = norm.x() * (srf_point.x() - startx) +
248  norm.y() * (srf_point.y() - starty) +
249  norm.z() * (srf_point.z() - startz) ;
250 
251  t = a/b;
252 
253  // substitute t into line equation
254  // to calculate final solution
255  G4double solx,soly,solz;
256  solx = startx + t * dirx;
257  soly = starty + t * diry;
258  solz = startz + t * dirz;
259 
260  // solve tolerance problem
261  if( (t*dirx >= -kCarTolerance/2) && (t*dirx <= kCarTolerance/2) )
262  solx = startx;
263 
264  if( (t*diry >= -kCarTolerance/2) && (t*diry <= kCarTolerance/2) )
265  soly = starty;
266 
267  if( (t*dirz >= -kCarTolerance/2) && (t*dirz <= kCarTolerance/2) )
268  solz = startz;
269 
270  G4bool xhit = (dirx < 0 && solx <= startx) || (dirx >= 0 && solx >= startx);
271  G4bool yhit = (diry < 0 && soly <= starty) || (diry >= 0 && soly >= starty);
272  G4bool zhit = (dirz < 0 && solz <= startz) || (dirz >= 0 && solz >= startz);
273 
274  if( xhit && yhit && zhit ) {
275  hitpoint= G4Point3D(solx, soly, solz);
276  }
277  }
278 
279  // closest_hit is a public Point3D in G4Surface
281 
282  if(closest_hit.x() == kInfinity)
283  {
284  // no hit
285  active=0;
286  SetDistance(kInfinity);
287  return 0;
288  }
289  else
290  {
291  // calculate the squared distance from the point to the intersection
292  // and set it in the distance data member (all clients know they have
293  // to take the sqrt)
294  SetDistance( RayStart.distance2(closest_hit) );
295 
296  // now, we have to verify that the hit point founded
297  // is included into the G4FPlane boundaries
298 
299  // project the hit to the xy plane,
300  // with the same projection that took the boundary
301  // into projectedBoundary
302  G4Point3D projectedHit= pplace.GetToPlacementCoordinates() * closest_hit;
303 
304  // test ray from the hit on the xy plane
305  G4Ray testRay( projectedHit, G4Vector3D(1, 0.01, 0) );
306 
307  // check if it intersects the boundary
308  G4int nbinter = projectedBoundary->IntersectRay2D(testRay);
309 
310  // If this number is par, it`s signify that the projected point
311  // is outside the projected surface, so the hit point is outside
312  // the bounded surface
313  if(nbinter&1)
314  {
315  // the intersection point is into the boundaries
316  // check if the intersection point is on the surface
317  if(distance <= kCarTolerance*0.5*kCarTolerance*0.5)
318  {
319  // the point is on the surface, set the distance to 0
320  SetDistance(0);
321  }
322  else
323  {
324  // the point is outside the surface
325  }
326 
327  return 1 ;
328  }
329  else
330  {
331  // the intersection point is out the boundaries
332  // it is not a real intersection
333  active=0;
334  SetDistance(kInfinity);
335  return 0;
336  }
337  }
338 }
339 
340 
342 {
343  // Calculates signed distance of point Pt to G4Plane Pl
344  // Be careful, the equation of the plane is :
345  // ax + by + cz = d
346  G4double dist = Pt.x()*Pl.a + Pt.y()*Pl.b + Pt.z()*Pl.c - Pl.d;
347 
348  return dist;
349 }
350 
351 
353 {
354  // L. Broglia
355 
356  projectedBoundary =
358 }
359 
361 {
362  G4double hownear = Pt.x()*Pl.a + Pt.y()*Pl.b + Pt.z()*Pl.c - Pl.d;
363 
364  return hownear;
365 }