5 * Revision 1.1.1.1 1999/05/18 15:55:17 fca
8 * Revision 1.1.1.1 1995/10/24 10:20:57 cernlib
12 #include "geant321/pilot.h"
13 #if defined(CERNLIB_OLD)
14 *CMZ : 3.21/02 29/03/94 15.41.31 by S.Giani
16 SUBROUTINE GNEXT (X, SNEXT, SAFETY)
18 C. ******************************************************************
20 C. * SUBR. GNEXT (X, SNEXT, SAFETY) *
22 C. * Computes SNEXT and SAFETY *
23 C. * SNEXT (output) : distance to closest boundary *
24 C. * from point X(1-3) along X(4-6) *
25 C. * SAFETY (output) : shortest distance to any boundary *
27 C. * Called by : User *
28 C. * Authors : S.Banerjee, R.Brun, F.Bruyant *
30 C. ******************************************************************
32 #include "geant321/gcbank.inc"
33 #include "geant321/gconsp.inc"
34 #include "geant321/gcshno.inc"
35 #include "geant321/gctmed.inc"
36 #include "geant321/gcvolu.inc"
37 #if defined(CERNLIB_USRJMP)
38 #include "geant321/gcjump.inc"
40 REAL X(6), X0(3), XC(6), XT(6)
45 DATA IDTYP / 1, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 2, 3, 1,
46 + 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 4, 3, 1, 1, 1,
49 C. ------------------------------------------------------------------
51 * *** Transform current point and direction into local reference system
53 IF (GRMAT(10,NLEVEL).EQ.0.) THEN
55 XC(I) = X(I) -GTRAN(I,NLEVEL)
59 * (later, code in line)
60 CALL GTRNSF (X, GTRAN(1,NLEVEL), GRMAT(1,NLEVEL), XC)
61 CALL GROT (X(4), GRMAT(1,NLEVEL), XC(4))
64 * *** Compute distance to boundaries
68 JVO = LQ(JVOLUM-LVOLUM(NLEVEL))
70 IF (Q(JVO+3).EQ.0.) GO TO 300
72 IF (NIN.LT.0) GO TO 200
74 * *** Case with contents positioned
77 IF (ISEARC.GE.-1) GO TO 120
79 * ** Contents are ordered by (dynamic) GSORD, select neighbours
81 JSB = LQ(LQ(JVO-NIN-1))
86 INC = SIGN(1., XC(IAX+3))
88 CALL GFCOOR (XC, IAX, CX)
90 DR = XC(1)*XC(4) +XC(2)*XC(5)
91 IF (IAX.EQ.5) DR = DR +XC(3)*XC(6)
93 ELSE IF (IAX.EQ.6) THEN
94 INC = SIGN(1., XC(1)*XC(5)-XC(2)*XC(4))
96 INC = SIGN(1., XC(3)*(XC(1)*XC(4)+XC(2)*XC(5))
97 + -XC(6)*(XC(1)*XC(1)+XC(2)*XC(2)))
100 IDIV = LOCATF (Q(JSB+3), NSB, CX)
101 IF (IDIV.LT.0) IDIV = -IDIV
104 IF (INC.LT.0.AND.IAX.LE.3) THEN
105 SAFETY = Q(JSB+3) -CX
109 ELSE IF (IDIV.EQ.NSB) THEN
110 IF (INC.GT.0.AND.IAX.NE.7) THEN
111 SAFETY = CX -Q(JSB+2+NSB)
118 SAFETY = CX -Q(JSB+2+IDIV)
120 SAFETY = Q(JSB+3+IDIV) -CX
126 ELSE IF (IAX.EQ.6) THEN
127 IF (IDIV.EQ.0) IDIV = NSB
134 110 NCONT = IQ(JSC0+IDIV)
136 * ** Loop over (selected) contents
139 IF (IDIV.EQ.IDIVL) GO TO 400
141 * (following statement for IAX=6, when division NSB is empty)
142 IF (IDIV.GT.NSB) IDIV = 1
150 120 JNEAR = LQ(JVO-NIN-1)
151 IF (ISEARC.GT.0) THEN
152 #if !defined(CERNLIB_USRJMP)
153 CALL GUNEAR (ISEARC, 2, XC, JNEAR)
155 #if defined(CERNLIB_USRJMP)
156 CALL JUMPT4(JUNEAR,ISEARC, 2, XC, JNEAR)
158 IF (IQ(JNEAR+1).EQ.0) GO TO 300
162 IF (IQ(JNEAR+1).NE.0) THEN
168 130 IN = IQ(JNEAR+INEAR)
171 140 IN = IQ(JSCV+ICONT)
173 150 IF(IN.LE.0)GO TO 300
176 JVOT = LQ(JVOLUM-IVOT)
179 IF (NLEVEL.GE.NLDEV(NLEVEL)) THEN
180 * (case with JVOLUM structure locally developed)
181 JPAR = LQ(LQ(JVOLUM-LVOLUM(NLDEV(NLEVEL))))
182 DO 169 ILEV = NLDEV(NLEVEL), NLEVEL
183 IF (IQ(JPAR+1).EQ.0) THEN
184 IF (ILEV.EQ.NLEVEL) THEN
187 JPAR = LQ(JPAR-LINDEX(ILEV+1))
189 IF (JPAR.EQ.0) GO TO 170
190 ELSE IF (IQ(JPAR-3).GT.1) THEN
191 JPAR = LQ(JPAR-LINDEX(ILEV+1))
207 * * Compute distance to boundary of current content
209 180 IF (IROTT.EQ.0) THEN
211 XT(I) = XC(I) -Q(JIN+4+I)
215 * (later, code in line)
216 CALL GITRAN (XC, Q(JIN+5), IROTT, XT)
217 CALL GRMTD (XC(4), IROTT, XT(4))
224 CALL GNOBOX (XT,Q(JPAR+1),IACT,SNEXT,SNXT,SAFE)
225 ELSE IF (ISHT.EQ.2) THEN
226 CALL GNOTRA(XT,Q(JPAR+1),IACT,1,SNEXT,SNXT,SAFE)
227 ELSE IF (ISHT.EQ.3) THEN
228 CALL GNOTRA(XT,Q(JPAR+1),IACT,2,SNEXT,SNXT,SAFE)
230 CALL GNOTRP (XT,Q(JPAR+1),IACT,SNEXT,SNXT,SAFE)
232 ELSE IF (ISHT.LE.10) THEN
234 CALL GNOTUB(XT,Q(JPAR+1),IACT,1,SNEXT,SNXT,SAFE)
235 ELSE IF (ISHT.EQ.6) THEN
236 CALL GNOTUB(XT,Q(JPAR+1),IACT,2,SNEXT,SNXT,SAFE)
237 ELSE IF (ISHT.EQ.7) THEN
238 CALL GNOCON(XT,Q(JPAR+1),IACT,1,SNEXT,SNXT,SAFE)
239 ELSE IF (ISHT.EQ.8) THEN
240 CALL GNOCON(XT,Q(JPAR+1),IACT,2,SNEXT,SNXT,SAFE)
241 ELSE IF (ISHT.EQ.9) THEN
242 CALL GNOSPH (XT,Q(JPAR+1),IACT,SNEXT,SNXT,SAFE)
244 CALL GNOPAR (XT,Q(JPAR+1),IACT,SNEXT,SNXT,SAFE)
246 ELSE IF (ISHT.EQ.11) THEN
247 CALL GNOPGO (XT,Q(JPAR+1),IACT,SNEXT,SNXT,SAFE)
248 ELSE IF (ISHT.EQ.12) THEN
249 CALL GNOPCO (XT,Q(JPAR+1),IACT,SNEXT,SNXT,SAFE)
250 ELSE IF (ISHT.EQ.13) THEN
251 CALL GNOELT (XT,Q(JPAR+1),IACT,SNEXT,SNXT,SAFE)
252 ELSE IF (ISHT.EQ.14) THEN
253 CALL GNOHYP (XT,Q(JPAR+1),IACT,SNEXT,SNXT,SAFE)
254 ELSE IF (ISHT.EQ.28) THEN
255 CALL GSNGTR (XT,Q(JPAR+1),IACT,SNEXT,SNXT,SAFE,0)
256 ELSE IF (ISHT.EQ.NSCTUB) THEN
257 CALL GNOCTU (XT,Q(JPAR+1),IACT,SNEXT,SNXT,SAFE)
259 PRINT *, ' GNEXT : No code for shape ', ISHT
263 IF (SAFE.LT.SAFETY) SAFETY = SAFE
264 IF (SNXT.LT.SNEXT) THEN
266 IF (ISEARC.EQ.-2) THEN
267 IF (MOD(IQ(JSC0),2).NE.0) THEN
271 X0(I) = XC(I) + SNXT*XC(I+3)
274 IDIVB = LOCATF (Q(JSB+3), NSB, X0(IAX))
276 CALL GFCOOR (X0, IAX, CX)
277 IDIVB = LOCATF (Q(JSB+3), NSB, CX)
279 IF (IDIVB.LT.0) IDIVB = -IDIVB
286 ELSE IF (IDIVB.EQ.NSB) THEN
287 IF (IAX.NE.6) IDIVB = NSB - 1
293 IF (ISEARC.EQ.-2) THEN
294 IF (ICONT.EQ.NCONT) THEN
297 IF (IDIV.EQ.IDIVB) GO TO 300
298 IF (.NOT.BTEST(IQ(JVO),2)) THEN
304 * * Compute distance to boundary of current volume
306 JPAR = LQ(JGPAR-NLEVEL)
311 CALL GNBOX (XC, Q(JPAR+1), IACT, SNEXT, SNXT, SAFE)
312 ELSE IF (ISH.EQ.2) THEN
313 CALL GNTRAP (XC, Q(JPAR+1),IACT,1, SNEXT,SNXT,SAFE)
314 ELSE IF (ISH.EQ.3) THEN
315 CALL GNTRAP (XC, Q(JPAR+1),IACT,2, SNEXT,SNXT,SAFE)
317 CALL GNTRP (XC, Q(JPAR+1), IACT, SNEXT, SNXT, SAFE)
319 ELSE IF (ISH.LE.10) THEN
321 CALL GNTUBE (XC, Q(JPAR+1),IACT,1, SNEXT,SNXT,SAFE)
322 ELSE IF (ISH.EQ.6) THEN
323 CALL GNTUBE (XC, Q(JPAR+1),IACT,2, SNEXT,SNXT,SAFE)
324 ELSE IF (ISH.EQ.7) THEN
325 CALL GNCONE (XC, Q(JPAR+1),IACT,1, SNEXT,SNXT,SAFE)
326 ELSE IF (ISH.EQ.8) THEN
327 CALL GNCONE (XC, Q(JPAR+1),IACT,2, SNEXT,SNXT,SAFE)
328 ELSE IF (ISH.EQ.9) THEN
329 CALL GNSPHR (XC, Q(JPAR+1),IACT, SNEXT, SNXT, SAFE)
331 CALL GNPARA (XC, Q(JPAR+1),IACT, SNEXT, SNXT, SAFE)
333 ELSE IF (ISH.EQ.12) THEN
334 CALL GNPCON (XC, Q(JPAR+1), IACT, SNEXT, SNXT, SAFE)
335 ELSE IF (ISH.EQ.11) THEN
336 CALL GNPGON (XC, Q(JPAR+1), IACT, SNEXT, SNXT, SAFE)
337 ELSE IF (ISH.EQ.13) THEN
338 CALL GNELTU (XC, Q(JPAR+1), IACT, SNEXT, SNXT, SAFE)
339 ELSE IF (ISH.EQ.14) THEN
340 CALL GNHYPE (XC, Q(JPAR+1), IACT, SNEXT, SNXT, SAFE)
341 ELSE IF (ISH.EQ.28) THEN
342 CALL GSNGTR (XC, Q(JPAR+1), IACT, SNEXT, SNXT, SAFE,1)
343 ELSE IF (ISH.EQ.NSCTUB) THEN
344 CALL GNCTUB (XC, Q(JPAR+1), IACT, SNEXT, SNXT, SAFE)
346 PRINT *, ' GNEXT : No code for shape ', ISH
350 IF (SAFE.LT.SAFETY) SAFETY = SAFE
351 IF (SNXT.LT.SNEXT) SNEXT = SNXT
353 * * Check wether other pseudo-divisions have to be scanned
356 X0(I) = XC(I) +SNXT*XC(I+3)
359 IDIVL = LOCATF (Q(JSB+3), NSB, X0(IAX))
361 CALL GFCOOR (X0, IAX, CX)
362 IDIVL = LOCATF (Q(JSB+3), NSB, CX)
364 IF (IDIVL.LT.0) IDIVL = -IDIVL
371 ELSEIF (IDIVL.EQ.NSB)THEN
372 IF(IAX.NE.6)IDIVL=NSB-1
375 IF (IDIV.EQ.IDIVB) GO TO 400
377 193 IF ((IDIV-IDIVL)*INC.GE.0) GO TO 400
385 IF (INEAR.EQ.NNEAR) GO TO 300
390 * *** Case of volume incompletely divided
395 JVOT = LQ(JVOLUM-IVOT)
398 * ** Get the division parameters
400 IF (NLEVEL.LT.NLDEV(NLEVEL)) THEN
403 * (case with JVOLUM structure locally developed)
404 JPARM = LQ(LQ(JVOLUM-LVOLUM(NLDEV(NLEVEL))))
405 IF (NLEVEL.EQ.NLDEV(NLEVEL)) GO TO 215
406 DO 210 ILEV = NLDEV(NLEVEL), NLEVEL-1
407 IF (IQ(JPARM+1).EQ.0) THEN
408 JPARM = LQ(JPARM-LINDEX(ILEV+1))
409 IF (JPARM.EQ.0) GO TO 215
410 ELSE IF (IQ(JPARM-3).GT.1) THEN
411 JPARM = LQ(JPARM-LINDEX(ILEV+1))
415 IF (ILEV.EQ.NLEVEL-1) THEN
428 * ** Look at the first and the last divisions only
430 220 IDT = IDTYP(IAXIS, ISH)
433 IF (XC(IAXIS).LT.ORIG) THEN
438 ELSE IF (IDT.EQ.2) THEN
439 R = XC(1)**2 + XC(2)**2
440 IF (ISH.EQ.9) R = R + XC(3)**2
443 IF (ISH.EQ.5.OR.ISH.EQ.6.OR.ISH.EQ.9) THEN
450 PRINT *, ' GNEXT : Partially divided ',ISH,IAXIS
452 IF (NDIV.GT.1) IN2 = NDIV
454 ELSE IF (IDT.EQ.4) THEN
456 RXY = XC(1)**2 + XC(2)**2
458 IF (XC(3).NE.0.0) THEN
459 THET = RADDEG * ATAN (RXY/XC(3))
460 IF (THET.LT.0.0) THET = THET + 180.0
464 IF (THET.LE.ORIG) THEN
470 PRINT *, ' GNEXT : Partially divided ',ISH,IAXIS
472 IF (ISH.EQ.5.OR.ISH.EQ.7) THEN
474 IF (NDIV.GT.1) IN2 = NDIV
476 IF (XC(1).NE.0.0.OR.XC(2).NE.0.0) THEN
477 PHI = RADDEG * ATAN2 (XC(2), XC(1))
481 IF (ISH.EQ.6.OR.ISH.EQ.8) THEN
482 IF (PHI.LT.ORIG) THEN
489 IF (NDIV.GT.1) IN2 = NDIV
494 225 IF (IDT.EQ.1) THEN
498 X0(IAXIS) = ORIG + (IN - 0.5) * SDIV
499 IF (ISH.EQ.4.OR.(ISH.EQ.10.AND.IAXIS.NE.1)) THEN
500 CALL GCENT (IAXIS, X0)
503 XT(I) = XC(I) - X0(I)
506 ELSE IF (IDT.EQ.3) THEN
507 PH0 = DEGRAD * (ORIG + (IN - 0.5) * SDIV)
511 XT(I) = XC(I)*CPHR + XC(I+1)*SPHR
512 XT(I+1) = XC(I+1)*CPHR - XC(I)*SPHR
522 IF (IQ(JPARM-3).GT.1) THEN
535 CALL GNOBOX (XT, Q(JPAR+1), IACT, SNEXT, SNXT, SAFE)
536 ELSE IF (ISHT.EQ.2) THEN
537 CALL GNOTRA (XT, Q(JPAR+1), IACT, 1, SNEXT, SNXT, SAFE)
538 ELSE IF (ISHT.EQ.3) THEN
539 CALL GNOTRA (XT, Q(JPAR+1), IACT, 2, SNEXT, SNXT, SAFE)
541 CALL GNOTRP (XT, Q(JPAR+1), IACT, SNEXT, SNXT, SAFE)
543 ELSE IF (ISHT.LE.10) THEN
545 CALL GNOTUB (XT, Q(JPAR+1), IACT, 1, SNEXT, SNXT, SAFE)
546 ELSE IF (ISHT.EQ.6) THEN
547 CALL GNOTUB (XT, Q(JPAR+1), IACT, 2, SNEXT, SNXT, SAFE)
548 ELSE IF (ISHT.EQ.7) THEN
549 CALL GNOCON (XT, Q(JPAR+1), IACT, 1, SNEXT, SNXT, SAFE)
550 ELSE IF (ISHT.EQ.8) THEN
551 CALL GNOCON (XT, Q(JPAR+1), IACT, 2, SNEXT, SNXT, SAFE)
552 ELSE IF (ISHT.EQ.9) THEN
553 CALL GNOSPH (XT, Q(JPAR+1), IACT, SNEXT, SNXT, SAFE)
555 CALL GNOPAR (XT, Q(JPAR+1), IACT, SNEXT, SNXT, SAFE)
557 ELSE IF (ISHT.EQ.11) THEN
558 CALL GNOPGO (XT, Q(JPAR+1), IACT, SNEXT, SNXT, SAFE)
559 ELSE IF (ISHT.EQ.12) THEN
560 CALL GNOPCO (XT, Q(JPAR+1), IACT, SNEXT, SNXT, SAFE)
561 ELSE IF (ISHT.EQ.13) THEN
562 CALL GNOELT (XT, Q(JPAR+1), IACT, SNEXT, SNXT, SAFE)
563 ELSE IF (ISHT.EQ.14) THEN
564 CALL GNOHYP (XT, Q(JPAR+1), IACT, SNEXT, SNXT, SAFE)
565 ELSE IF (ISHT.EQ.28) THEN
566 CALL GSNGTR (XT, Q(JPAR+1), IACT, SNEXT, SNXT, SAFE,0)
567 ELSE IF (ISHT.EQ.NSCTUB) THEN
568 CALL GNOCTU (XT, Q(JPAR+1), IACT, SNEXT, SNXT, SAFE)
570 PRINT *, ' GNEXT : No code for shape ', ISHT
574 IF (SAFE.LT.SAFETY) SAFETY = SAFE
575 IF (SNXT.LT.SNEXT) SNEXT = SNXT
584 * *** Calculate SNEXT and SAFETY with respect to the Mother
585 * *** SAFETY only for concave volumes if finite SNEXT
586 * *** has been found with respect to one of its contents
589 IF (SNEXT.LT.0.9*BIG) THEN
590 IF (.NOT.BTEST(IQ(JVO),2)) IACT = 0
592 JPAR = LQ(JGPAR-NLEVEL)
595 CALL GNBOX (XC, Q(JPAR+1), IACT, SNEXT, SNXT, SAFE )
596 ELSE IF (ISH.EQ.2) THEN
597 CALL GNTRAP (XC, Q(JPAR+1), IACT, 1, SNEXT, SNXT, SAFE)
598 ELSE IF (ISH.EQ.3) THEN
599 CALL GNTRAP (XC, Q(JPAR+1), IACT, 2, SNEXT, SNXT, SAFE)
601 CALL GNTRP (XC, Q(JPAR+1), IACT, SNEXT, SNXT, SAFE)
603 ELSE IF (ISH.LE.10) THEN
605 CALL GNTUBE (XC, Q(JPAR+1), IACT, 1, SNEXT, SNXT, SAFE)
606 ELSE IF (ISH.EQ.6) THEN
607 CALL GNTUBE (XC, Q(JPAR+1), IACT, 2, SNEXT, SNXT, SAFE)
608 ELSE IF (ISH.EQ.7) THEN
609 CALL GNCONE (XC, Q(JPAR+1), IACT, 1, SNEXT, SNXT, SAFE)
610 ELSE IF (ISH.EQ.8) THEN
611 CALL GNCONE (XC, Q(JPAR+1), IACT, 2, SNEXT, SNXT, SAFE)
612 ELSE IF (ISH.EQ.9) THEN
613 CALL GNSPHR (XC, Q(JPAR+1), IACT, SNEXT, SNXT, SAFE)
615 CALL GNPARA (XC, Q(JPAR+1), IACT, SNEXT, SNXT, SAFE)
617 ELSE IF (ISH.EQ.12) THEN
618 CALL GNPCON (XC, Q(JPAR+1), IACT, SNEXT, SNXT, SAFE)
619 ELSE IF (ISH.EQ.11) THEN
620 CALL GNPGON (XC, Q(JPAR+1), IACT, SNEXT, SNXT, SAFE)
621 ELSE IF (ISH.EQ.13) THEN
622 CALL GNELTU (XC, Q(JPAR+1), IACT, SNEXT, SNXT, SAFE)
623 ELSE IF (ISH.EQ.14) THEN
624 CALL GNHYPE (XC, Q(JPAR+1), IACT, SNEXT, SNXT, SAFE)
625 ELSE IF (ISH.EQ.28) THEN
626 CALL GSNGTR (XC, Q(JPAR+1), IACT, SNEXT, SNXT, SAFE,1)
627 ELSE IF (ISH.EQ.NSCTUB) THEN
628 CALL GNCTUB (XC, Q(JPAR+1), IACT, SNEXT, SNXT, SAFE)
630 PRINT *, ' GNEXT : No code for shape ', ISH
634 IF (SAFE.LT.SAFETY) SAFETY = SAFE
635 IF (SNXT.LT.SNEXT) SNEXT = SNXT
637 400 IF (GONLY(NLEVEL).EQ.0.) THEN
639 * *** Case of a 'NOT ONLY' volume -> step search
644 IF (ST.LE.0) GO TO 999
646 IF (ST.LE.EPSI3) THEN
657 XT(I) = X(I) +SN*X(I+3)
660 CALL GINVOL (XT, ISAME)
662 IF (ST.LT.EPSI2) GO TO 490
670 IF (ST.LT.EPSI2) THEN
679 IF (NN.GT.0) GO TO 420
682 490 IF (SN.LT.SNEXT) SNEXT = SN
688 SUBROUTINE GNEX2_DUMMY