1 | #include "ShapeOfLens.h" |
---|
2 | #include "FresnelSurface.h" |
---|
3 | #include "LensUtils.h" |
---|
4 | #include "FresnelOutput_def.h" |
---|
5 | |
---|
6 | #include <globals.hh> |
---|
7 | #include <G4VoxelLimits.hh> |
---|
8 | #include <G4AffineTransform.hh> |
---|
9 | #include <G4GeometryTolerance.hh> |
---|
10 | #include <G4OpBoundaryProcess.hh> |
---|
11 | #include <G4Tubs.hh> |
---|
12 | #include <G4EventManager.hh> |
---|
13 | #include <G4Track.hh> |
---|
14 | #include <Randomize.hh> |
---|
15 | |
---|
16 | using namespace G4FresnelLens; |
---|
17 | using namespace CLHEP; |
---|
18 | using std::min; |
---|
19 | using std::max; |
---|
20 | using std::swap; |
---|
21 | |
---|
22 | //#define DEBUG_WNF |
---|
23 | //#define DEBUG |
---|
24 | //#define DEBUG_SLANTWALLS |
---|
25 | |
---|
26 | /////////////////////////////////////////////////////////////////////////////// |
---|
27 | // |
---|
28 | // constructor - check parameters |
---|
29 | //__________________________________________________________________________________ |
---|
30 | ShapeOfLens::ShapeOfLens(const G4String& pName, |
---|
31 | G4double pDz, |
---|
32 | G4double pR, |
---|
33 | SSurface* upsurf, SSurface* downsurf) |
---|
34 | : G4VSolid(pName), |
---|
35 | __INHERITCONSTRUCTOR("ShapeOfLens") |
---|
36 | fCubicVolume(0.), //fpPolyhedron(0), |
---|
37 | fUpSurface(upsurf), fDownSurface(downsurf) |
---|
38 | #ifdef SLANTWALLS |
---|
39 | ,isSlant(false), theSlantSigma(0.) |
---|
40 | #endif |
---|
41 | { |
---|
42 | top_volume = new G4Tubs("top_volume",0.,pR,pDz,0.,360.); |
---|
43 | kTolerance=G4GeometryTolerance::GetInstance()->GetSurfaceTolerance(); |
---|
44 | kHalfTolerance=kTolerance*.5; |
---|
45 | fR=min(fUpSurface->GetR(), fDownSurface->GetR()); |
---|
46 | fZ1=fDownSurface->GetMinZ(); |
---|
47 | fZ2=fUpSurface->GetMaxZ(); |
---|
48 | fCylinder.SetR(fR); |
---|
49 | fCylinder.SetZ(fDownSurface->GetEdgeZ(), fUpSurface->GetEdgeZ()); |
---|
50 | |
---|
51 | theLastPosition.set(DBL_MAX, DBL_MAX, DBL_MAX); |
---|
52 | theLastInside=kOutside; |
---|
53 | |
---|
54 | fSurfaceArea = 0.; |
---|
55 | |
---|
56 | __REG_ACTION("ShapeOfLens"); |
---|
57 | } |
---|
58 | |
---|
59 | //__________________________________________________________________________________ |
---|
60 | ShapeOfLens::ShapeOfLens( __void__& a ) : G4VSolid(a), fCubicVolume(0) { |
---|
61 | fSurfaceArea = 0.; |
---|
62 | } |
---|
63 | |
---|
64 | //__________________________________________________________________________________ |
---|
65 | ShapeOfLens::~ShapeOfLens() { |
---|
66 | // top_volume is deleted by Geant4 |
---|
67 | //delete top_volume; |
---|
68 | if ( fUpSurface ) delete fUpSurface; |
---|
69 | if ( fDownSurface ) delete fDownSurface; |
---|
70 | } |
---|
71 | |
---|
72 | //__________________________________________________________________________________ |
---|
73 | EInside ShapeOfLens::Inside(const G4ThreeVector& p, int* surface, FSIntersectedSegment* intSeg) const { |
---|
74 | #ifdef DEBUG |
---|
75 | printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n"); |
---|
76 | printf("Inside called (%s)\n", GetName().data()); |
---|
77 | printf("din pos(%f, %f, %f)\n",p.x(),p.y(),p.z()); |
---|
78 | printf("rho=%f z=%f\n",p.perp(),p.z()); |
---|
79 | #endif |
---|
80 | //if ( VectorIsZero(p) ) printf("zero\n"); |
---|
81 | |
---|
82 | if ( CompareVectors(p, theLastPosition, kHalfTolerance) ) { |
---|
83 | if ( intSeg ) *intSeg=theLastInsideSegment; |
---|
84 | #ifdef DEBUG |
---|
85 | printf("vector is cached.\n"); |
---|
86 | printf("return %s\n", theLastInside==kInside?"inside":(theLastInside==kOutside?"out":"surf")); |
---|
87 | #endif |
---|
88 | return theLastInside; |
---|
89 | } |
---|
90 | theLastInsideSegment.Reset(); |
---|
91 | theLastPosition=p; |
---|
92 | |
---|
93 | double z = p.z(); |
---|
94 | if ( z<fZ1-kHalfTolerance || z>fZ2+kHalfTolerance ) { |
---|
95 | #ifdef DEBUG |
---|
96 | printf("return out, for sure\n"); |
---|
97 | #endif |
---|
98 | return theLastInside=kOutside; |
---|
99 | } |
---|
100 | |
---|
101 | double rho = p.perp(); |
---|
102 | if ( rho > fR+kHalfTolerance ) { |
---|
103 | #ifdef DEBUG |
---|
104 | printf("return out, on side\n"); |
---|
105 | #endif |
---|
106 | return theLastInside=kOutside; |
---|
107 | } |
---|
108 | |
---|
109 | |
---|
110 | EInside ins=fCylinder.Inside(rho, z, &theLastInsideSegment); |
---|
111 | if (ins==kSurface) { |
---|
112 | if (surface) *surface = 0; |
---|
113 | #ifdef DEBUG |
---|
114 | printf("return surf, cyl\n"); |
---|
115 | #endif |
---|
116 | return theLastInside=kSurface; |
---|
117 | } |
---|
118 | |
---|
119 | EInside in = fDownSurface->Inside(rho, z, &theLastInsideSegment); |
---|
120 | if ( in==kInside ) { |
---|
121 | #ifdef DEBUG |
---|
122 | printf("return out, down\n"); |
---|
123 | #endif |
---|
124 | return theLastInside=kOutside; |
---|
125 | } |
---|
126 | if ( in==kSurface) { |
---|
127 | if ( intSeg ) { |
---|
128 | *intSeg=theLastInsideSegment; |
---|
129 | if (intSeg->surf) printf("cyl err\n"); |
---|
130 | } |
---|
131 | if (surface) *surface = 1; |
---|
132 | #ifdef DEBUG |
---|
133 | printf("return surface, down\n"); |
---|
134 | #endif |
---|
135 | return theLastInside=kSurface; |
---|
136 | } |
---|
137 | |
---|
138 | in = fUpSurface->Inside(rho, z, &theLastInsideSegment); |
---|
139 | if ( intSeg && in==kSurface ) *intSeg=theLastInsideSegment; |
---|
140 | if (surface) *surface = 2; |
---|
141 | #ifdef DEBUG |
---|
142 | printf("return %s, up\n", in==kInside?"inside":(in==kOutside?"out":"in")); |
---|
143 | #endif |
---|
144 | return theLastInside=in; |
---|
145 | } |
---|
146 | |
---|
147 | //__________________________________________________________________________________ |
---|
148 | G4double ShapeOfLens::DistanceToIn(const G4ThreeVector& p, const G4ThreeVector& v) const { |
---|
149 | #ifdef DEBUG |
---|
150 | printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n"); |
---|
151 | printf("DistanceToIn(vec) called (%s)\n", GetName().data()); |
---|
152 | printf("din pos(%.10g, %.10g, %.10g) dir(%.10g, %.10g, %.10g)\n",p.x(),p.y(),p.z(),v.x(),v.y(),v.z()); |
---|
153 | printf("rho=%g z=%g, theta=%g phi=%g\n",p.perp(),p.z(), v.theta()/deg, v.phi()/deg); |
---|
154 | #endif |
---|
155 | |
---|
156 | double zp=p.z(); |
---|
157 | double vz=v.z(); |
---|
158 | |
---|
159 | theLastPositionOnSurface.set(kInfinity, kInfinity, kInfinity); |
---|
160 | theLastSurface=0; |
---|
161 | if ( (zp>=fZ2 && vz>=0.) || (zp<=fZ1 && vz<=0.) ) return kInfinity; |
---|
162 | |
---|
163 | double perp=p.perp(); |
---|
164 | double smallSubst=0; |
---|
165 | FSIntersectedSegment intUp, intDown; |
---|
166 | theLastPositionOnSurface.set(kInfinity, kInfinity, kInfinity); |
---|
167 | if ( perp<(fR-kHalfTolerance) ) { |
---|
168 | if ( zp>=(fUpSurface->GetBottomZ(perp)-kHalfTolerance) ) { |
---|
169 | EInside in = fUpSurface->Inside(perp, zp); |
---|
170 | #ifdef DEBUG |
---|
171 | printf("in_up: %s\n", in==kSurface?"sur":( in==kOutside?"out":"in")); |
---|
172 | #endif |
---|
173 | if ( in!=kInside) { |
---|
174 | G4ThreeVector p1=p; |
---|
175 | if ( in==kSurface ) p1-=v*kHalfTolerance; |
---|
176 | double dd=fUpSurface->FindNearestIntersection(p1, v, &intUp); |
---|
177 | if ( in==kSurface ) dd-=kHalfTolerance; |
---|
178 | if( dd<=kHalfTolerance ) dd=smallSubst;; |
---|
179 | theLastPositionOnSurface=p+v*dd; |
---|
180 | theLastSurfaceSegment=intUp; |
---|
181 | theLastSurface=2; |
---|
182 | #ifdef DEBUG |
---|
183 | printf("dist up=%f\n",dd); |
---|
184 | if ( dd<kInfinity ) { |
---|
185 | printf("next point (%f, %f, %f)\n",theLastPositionOnSurface.x(), theLastPositionOnSurface.y(), theLastPositionOnSurface.z()); |
---|
186 | } |
---|
187 | #endif |
---|
188 | return dd; |
---|
189 | } |
---|
190 | } |
---|
191 | if ( zp<=(fDownSurface->GetUpperZ(perp)+kHalfTolerance) ) { |
---|
192 | EInside in = fDownSurface->Inside(perp, zp); |
---|
193 | #ifdef DEBUG |
---|
194 | printf("in_down: %s\n", in==kSurface?"sur":( in==kOutside?"out":"in")); |
---|
195 | #endif |
---|
196 | if ( in!=kOutside) { |
---|
197 | G4ThreeVector p1=p; |
---|
198 | if ( in==kSurface ) p1-=v*kHalfTolerance; |
---|
199 | double dd=fDownSurface->FindNearestIntersection(p, v, &intDown); |
---|
200 | if ( in==kSurface ) dd-=kHalfTolerance; |
---|
201 | if( dd<=kHalfTolerance ) dd=smallSubst; |
---|
202 | theLastPositionOnSurface=p+v*dd; |
---|
203 | theLastSurfaceSegment=intDown; |
---|
204 | theLastSurface=1; |
---|
205 | #ifdef DEBUG |
---|
206 | printf("dist down=%f\n",dd); |
---|
207 | if ( dd<kInfinity ) { |
---|
208 | printf("next point (%f, %f, %f)\n",theLastPositionOnSurface.x(), theLastPositionOnSurface.y(), theLastPositionOnSurface.z()); |
---|
209 | } |
---|
210 | #endif |
---|
211 | return dd; |
---|
212 | } |
---|
213 | } |
---|
214 | |
---|
215 | Warning_("Point is inside, but calling DistanceToIn."); |
---|
216 | int id=G4EventManager::GetEventManager()-> |
---|
217 | GetTrackingManager()-> |
---|
218 | GetTrack()->GetTrackID(); |
---|
219 | printf("Event %i, %s\n", id, GetName().data()); |
---|
220 | printf("pos(%.10g,%.10g,%.10g)\n", p.x(), p.y(), p.z()); |
---|
221 | printf("dif(%.10g,%.10g,%.10g)\n", v.x(), v.y(), v.z()); |
---|
222 | |
---|
223 | return kInfinity; |
---|
224 | } |
---|
225 | |
---|
226 | double cosalpha = p.x()*v.x()+p.y()*v.y(); |
---|
227 | if ( cosalpha>=.0 ) return kInfinity; |
---|
228 | // calculate distance to cylinder |
---|
229 | FSIntersectedSegment intCyl; |
---|
230 | double dist_cyl = fCylinder.FindNearestIntersection(p, v, &intCyl); |
---|
231 | double dist_up = fUpSurface->FindNearestIntersection(p, v, &intUp); |
---|
232 | double dist_down = fDownSurface->FindNearestIntersection(p, v, &intDown); |
---|
233 | |
---|
234 | #ifdef DEBUG |
---|
235 | printf("dc: %e \tdu: %e \t dd:%e\n",dist_cyl,dist_up,dist_down); |
---|
236 | #endif |
---|
237 | |
---|
238 | double mindist; |
---|
239 | if ( dist_up<dist_down ) { |
---|
240 | if ( dist_up<dist_cyl ){ |
---|
241 | mindist=dist_up; |
---|
242 | theLastSurfaceSegment=intUp; |
---|
243 | theLastSurface=2; |
---|
244 | } |
---|
245 | else { |
---|
246 | mindist=dist_cyl; |
---|
247 | theLastSurfaceSegment=intCyl; |
---|
248 | theLastSurface=0; |
---|
249 | } |
---|
250 | } |
---|
251 | else { |
---|
252 | if ( dist_down<dist_cyl ){ |
---|
253 | mindist=dist_down; |
---|
254 | theLastSurfaceSegment=intDown; |
---|
255 | theLastSurface=1; |
---|
256 | } |
---|
257 | else { |
---|
258 | mindist=dist_cyl; |
---|
259 | theLastSurfaceSegment=intCyl; |
---|
260 | theLastSurface=0; |
---|
261 | } |
---|
262 | } |
---|
263 | mindist=mindist>kTolerance?dist_cyl:smallSubst; |
---|
264 | theLastPositionOnSurface=p+v*mindist; |
---|
265 | return mindist; |
---|
266 | } |
---|
267 | |
---|
268 | //__________________________________________________________________________________ |
---|
269 | G4double ShapeOfLens::DistanceToIn(const G4ThreeVector& p) const{ |
---|
270 | #ifdef DEBUG |
---|
271 | printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n"); |
---|
272 | printf("DistanceToIn(pos) called (%s)\n", GetName().data()); |
---|
273 | printf("din pos(%f, %f, %f)\n",p.x(),p.y(),p.z()); |
---|
274 | printf("rho=%f z=%f\n",p.perp(),p.z()); |
---|
275 | #endif |
---|
276 | double zp=p.z(); |
---|
277 | if ( zp<=fCylinder.GetMinZ() ) return fDownSurface->DistanceToSurfSafeDown(p); |
---|
278 | if ( zp>=fCylinder.GetMaxZ() ) return fUpSurface->DistanceToSurfSafeUp(p); |
---|
279 | return fabs(p.perp()-fR); |
---|
280 | } |
---|
281 | |
---|
282 | //__________________________________________________________________________________ |
---|
283 | G4double ShapeOfLens::DistanceToOut(const G4ThreeVector& p, |
---|
284 | const G4ThreeVector& v, |
---|
285 | const G4bool calcNorm, |
---|
286 | G4bool *validNorm, |
---|
287 | G4ThreeVector *n) const { |
---|
288 | #ifdef DEBUG |
---|
289 | printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n"); |
---|
290 | printf("DistanceToOut(vec) called (%s)\n", GetName().data()); |
---|
291 | printf("dout (%f, %f, %f) (%f, %f, %f)\n",p.x(),p.y(),p.z(),v.x(),v.y(),v.z()); printf("rho=%f z=%f\n",p.perp(),p.z()); |
---|
292 | #endif |
---|
293 | if ( calcNorm ) *validNorm = true; |
---|
294 | |
---|
295 | G4ThreeVector p1=p; |
---|
296 | double dist_shift(0.); |
---|
297 | double perp=p.perp(); |
---|
298 | EInside in_up = fUpSurface->Inside(perp,p.z()); |
---|
299 | EInside in_down = fDownSurface->Inside(perp,p.z()); |
---|
300 | #ifdef DEBUG |
---|
301 | printf("in_up: %s\n",in_up==kSurface?"sur":(in_up==kOutside?"out":"in")); |
---|
302 | printf("in_down: %s\n",in_down==kSurface?"sur":(in_down==kOutside?"out":"in")); |
---|
303 | #endif |
---|
304 | if ( in_up==kSurface || in_down==kSurface ) { |
---|
305 | #ifdef DEBUG |
---|
306 | printf("point is on surface, shift it by kHalfTolerance\n"); |
---|
307 | #endif |
---|
308 | p1+=kHalfTolerance*v; |
---|
309 | dist_shift+=kHalfTolerance; |
---|
310 | } |
---|
311 | |
---|
312 | #ifdef DEBUG |
---|
313 | printf("asking up\n"); |
---|
314 | #endif |
---|
315 | FSIntersectedSegment intsegUp, intsegDown; |
---|
316 | double dist_up = fUpSurface->FindNearestIntersection(p1, v, &intsegUp); |
---|
317 | #ifdef DEBUG |
---|
318 | printf("asking down\n"); |
---|
319 | #endif |
---|
320 | double dist_down = fDownSurface->FindNearestIntersection(p1, v, &intsegDown); |
---|
321 | |
---|
322 | #ifdef DEBUG |
---|
323 | printf("du=%e dd=%e\n",dist_up,dist_down); |
---|
324 | double du=dist_up+dist_shift; |
---|
325 | double dd=dist_down+dist_shift; |
---|
326 | printf("du(s)=%e dd=%e\n",du,dd); |
---|
327 | if ( du<kInfinity ) { |
---|
328 | G4ThreeVector newp=p+v*du; |
---|
329 | printf("next point (up) (%f, %f, %f)\n",newp.x(), newp.y(), newp.z()); |
---|
330 | } |
---|
331 | if ( dd<kInfinity ) { |
---|
332 | G4ThreeVector newp=p+v*dd; |
---|
333 | printf("next point (down) (%f, %f, %f)\n",newp.x(), newp.y(), newp.z()); |
---|
334 | } |
---|
335 | #endif |
---|
336 | |
---|
337 | if ( dist_up<kInfinity || dist_down<kInfinity ) { |
---|
338 | if ( dist_up<dist_down ) { |
---|
339 | if ( calcNorm ) { |
---|
340 | intsegUp.Normal(p1+v*dist_up, +1., n); |
---|
341 | #ifdef SLANTWALLS |
---|
342 | if ( isSlant && n->z()==0. ) CorrectCylinderNormal(n); |
---|
343 | #endif |
---|
344 | #ifdef DEBUG |
---|
345 | printf("normal is (%f, %f, %f)\n",n->x(), n->y(), n->z()); |
---|
346 | #endif |
---|
347 | } |
---|
348 | dist_shift+=dist_up; |
---|
349 | return dist_shift<kHalfTolerance?kHalfTolerance:dist_shift+kHalfTolerance*0.5; |
---|
350 | } |
---|
351 | |
---|
352 | if ( dist_down<kInfinity ) { |
---|
353 | if ( calcNorm ) { |
---|
354 | intsegDown.Normal(p1+v*dist_down, -1., n); |
---|
355 | #ifdef SLANTWALLS |
---|
356 | if ( isSlant && n->z()==0.) CorrectCylinderNormal(n); |
---|
357 | #endif |
---|
358 | #ifdef DEBUG |
---|
359 | printf("normal is (%f, %f, %f)\n",n->x(), n->y(), n->z()); |
---|
360 | #endif |
---|
361 | } |
---|
362 | dist_shift+=dist_down; |
---|
363 | return dist_shift<kHalfTolerance?kHalfTolerance:dist_shift+kHalfTolerance*0.5; |
---|
364 | } |
---|
365 | } |
---|
366 | |
---|
367 | double dist; |
---|
368 | G4ThreeVector pp; |
---|
369 | if ( calcNorm ) { |
---|
370 | FSIntersectedSegment intCyl; |
---|
371 | dist=fCylinder.FindNearestIntersection(p1, v, &intCyl); |
---|
372 | pp=p1+v*dist; |
---|
373 | intCyl.Normal(pp, -1., n); |
---|
374 | #ifdef SLANTWALLS |
---|
375 | if ( isSlant ) CorrectCylinderNormal(n); |
---|
376 | #endif |
---|
377 | } |
---|
378 | else { |
---|
379 | dist=fCylinder.FindNearestIntersection(p1, v); |
---|
380 | pp=p1+v*dist; |
---|
381 | } |
---|
382 | |
---|
383 | if ( dist==kInfinity ) { |
---|
384 | if ( dist_shift ) return dist_shift<kHalfTolerance?kHalfTolerance:dist_shift; |
---|
385 | else { |
---|
386 | #ifdef DEBUG_WNF |
---|
387 | printf("shift is %g\n", dist_shift); |
---|
388 | if ( fUpSurface->getDebug() ) exit(1); |
---|
389 | fUpSurface->setDebug(); |
---|
390 | fDownSurface->setDebug(); |
---|
391 | DistanceToOut(p, v, calcNorm, validNorm, n); |
---|
392 | #endif |
---|
393 | Warning_("Way out not found."); |
---|
394 | int id=G4EventManager::GetEventManager()-> |
---|
395 | GetTrackingManager()-> |
---|
396 | GetTrack()->GetTrackID(); |
---|
397 | printf("Event %i, %s\n", id, GetName().data()); |
---|
398 | printf("pos(%.10g,%.10g,%.10g)\n", p.x(), p.y(), p.z()); |
---|
399 | printf("dif(%.10g,%.10g,%.10g)\n", v.x(), v.y(), v.z()); |
---|
400 | } |
---|
401 | } |
---|
402 | dist+=dist_shift; |
---|
403 | return dist<kHalfTolerance?kHalfTolerance:dist+kHalfTolerance*0.5; |
---|
404 | } |
---|
405 | |
---|
406 | //__________________________________________________________________________________ |
---|
407 | G4double ShapeOfLens::DistanceToOut(const G4ThreeVector& p) const{ |
---|
408 | #ifdef DEBUG |
---|
409 | printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n"); |
---|
410 | printf("DistanceToOut(pos) called (%s)\n", GetName().data()); |
---|
411 | printf("din pos(%f, %f, %f)\n",p.x(),p.y(),p.z()); |
---|
412 | printf("rho=%f z=%f\n",p.perp(),p.z()); |
---|
413 | #endif |
---|
414 | double d1=fDownSurface->DistanceToSurfSafeUp(p); |
---|
415 | if ( d1<kTolerance ){ |
---|
416 | #ifdef DEBUG |
---|
417 | printf("return dist to up: %g\n",d1); |
---|
418 | #endif |
---|
419 | return d1; |
---|
420 | } |
---|
421 | double d2=fUpSurface->DistanceToSurfSafeDown(p); |
---|
422 | if ( d2<kTolerance ){ |
---|
423 | #ifdef DEBUG |
---|
424 | printf("dist to up: %g\n", d1); |
---|
425 | printf("return dist to down: %g\n",d2); |
---|
426 | #endif |
---|
427 | return d2; |
---|
428 | } |
---|
429 | double d3=fabs(fR-p.perp()); |
---|
430 | |
---|
431 | #ifdef DEBUG |
---|
432 | printf("dist to up: %g\n", d1); |
---|
433 | printf("dist to down: %g\n", d2); |
---|
434 | printf("dist to cyl: %g\n", d3); |
---|
435 | printf("return: %g\n", min(min(d1,d2),d3)); |
---|
436 | #endif |
---|
437 | return min(min(d1,d2),d3); |
---|
438 | } |
---|
439 | |
---|
440 | //#define DEBUG_SAVENORMAL |
---|
441 | //__________________________________________________________________________________ |
---|
442 | G4ThreeVector ShapeOfLens::SurfaceNormal( const G4ThreeVector& p ) const { |
---|
443 | #ifdef DEBUG |
---|
444 | printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n"); |
---|
445 | printf("SurfaceNormal called (%s)\n", GetName().data()); |
---|
446 | printf("p (%f, %f)\n",p.perp(),p.z()); |
---|
447 | #endif |
---|
448 | int surface(theLastSurface); |
---|
449 | FSIntersectedSegment intseg; |
---|
450 | G4ThreeVector norm(1.,0.,0.); |
---|
451 | if ( CompareVectors(p, theLastPositionOnSurface, kHalfTolerance) ){ |
---|
452 | intseg=theLastSurfaceSegment; |
---|
453 | #ifdef DEBUG |
---|
454 | printf("Point is saved, using the last segment normal.\n"); |
---|
455 | #endif |
---|
456 | } |
---|
457 | else { |
---|
458 | EInside ins=this->Inside(p, &surface, &intseg); |
---|
459 | if ( ins!=kSurface ){ |
---|
460 | Warning_("Calculating SurfaceNormal not on surface."); |
---|
461 | int id=G4EventManager::GetEventManager()-> |
---|
462 | GetTrackingManager()-> |
---|
463 | GetTrack()->GetTrackID(); |
---|
464 | printf("Event %i, %s\n", id, GetName().data()); |
---|
465 | printf("pos(%.10g,%.10g,%.10g)\n", p.x(), p.y(), p.z()); |
---|
466 | double rho=p.perp(); |
---|
467 | printf("dz1 %g, dz2 %g\n", p.z()-fUpSurface->PointOnSurf(rho),p.z()-fDownSurface->PointOnSurf(rho)); |
---|
468 | return norm; |
---|
469 | } |
---|
470 | |
---|
471 | #ifdef DEBUG |
---|
472 | printf("Point is not saved. Dist is %g\n", (p-theLastPositionOnSurface).mag() ); |
---|
473 | #endif |
---|
474 | } |
---|
475 | #ifdef DEBUG |
---|
476 | printf(" Point: %g %g %g\n",p.x(), p.y(), p.z()); |
---|
477 | printf(" Saved point: %g %g %g\n",theLastPositionOnSurface.x(), theLastPositionOnSurface.y(), theLastPositionOnSurface.z()); |
---|
478 | printf(" Saved segment: type %2i, r(%g, %g), z(%g, %g)\n", intseg.type, intseg.r1, intseg.r2, intseg.z1, intseg.z2); |
---|
479 | #endif |
---|
480 | intseg.Normal(p, surface<2?-1.:1., &norm); |
---|
481 | #ifdef DEBUG |
---|
482 | double mag=norm.mag(); |
---|
483 | printf("Returned normal: (%g, %g, %g) (%g, %g) len=%g\n", norm.x(), norm.y(), norm.z(), norm.theta()/deg, norm.phi()/deg, mag); |
---|
484 | if ( fabs(mag-1.)>kHalfTolerance ) printf("ERROR: not unitary.\n"); |
---|
485 | #endif |
---|
486 | |
---|
487 | #ifdef SLANTWALLS |
---|
488 | if ( isSlant && norm.z()==0. ) CorrectCylinderNormal(&norm); |
---|
489 | #endif |
---|
490 | |
---|
491 | return norm; |
---|
492 | } |
---|
493 | |
---|
494 | //__________________________________________________________________________________ |
---|
495 | #ifdef SLANTWALLS |
---|
496 | void ShapeOfLens::CorrectCylinderNormal(G4ThreeVector* n) const { |
---|
497 | n->setTheta( CLHEP::RandGauss::shoot(90.*deg, theSlantSigma) ); |
---|
498 | #ifdef DEBUG_SLANTWALLS |
---|
499 | printf("%f\n",n->getTheta()/deg); |
---|
500 | #endif |
---|
501 | } |
---|
502 | #endif |
---|
503 | |
---|
504 | //__________________________________________________________________________________ |
---|
505 | G4double ShapeOfLens::GetCubicVolume(){ |
---|
506 | if(fCubicVolume == 0.)fCubicVolume=top_volume->GetCubicVolume(); |
---|
507 | return fCubicVolume; |
---|
508 | } |
---|
509 | |
---|
510 | //__________________________________________________________________________________ |
---|
511 | G4double ShapeOfLens::GetSurfaceArea() { |
---|
512 | if(fSurfaceArea == 0.)fSurfaceArea=top_volume->GetSurfaceArea(); |
---|
513 | return fSurfaceArea; |
---|
514 | } |
---|
515 | |
---|
516 | //__________________________________________________________________________________ |
---|
517 | void ShapeOfLens::DescribeYourselfTo(G4VGraphicsScene& scene) const{ |
---|
518 | top_volume->DescribeYourselfTo(scene); |
---|
519 | } |
---|
520 | //__________________________________________________________________________________ |
---|
521 | G4ThreeVector ShapeOfLens::GetPointOnSurface() const{ |
---|
522 | return top_volume->GetPointOnSurface(); |
---|
523 | } |
---|
524 | |
---|
525 | //__________________________________________________________________________________ |
---|
526 | G4bool ShapeOfLens::CalculateExtent(const EAxis pAxis, |
---|
527 | const G4VoxelLimits& pVoxelLimit, |
---|
528 | const G4AffineTransform& pTransform, |
---|
529 | G4double& pmin, G4double& pmax) const { |
---|
530 | return top_volume->CalculateExtent(pAxis,pVoxelLimit,pTransform,pmin,pmax); |
---|
531 | } |
---|