C
C Subroutine file 'rp3d.for' to control parameters of rays
C during 3-D shooting.
C
C Version: 5.90
C Date: 2004, July 28
C
C                                                  
C Coded by Petr Bulant
C     Department of Geophysics, Charles University Prague,
C     Ke Karlovu 3, 121 16 Praha 2, Czech Republic,
C     http://sw3d.cz/staff/bulant.htm
C
C=======================================================================
C
      SUBROUTINE RP3D(IRAY,ITYPE,G1NEW,G2NEW)
C
C----------------------------------------------------------------------
      INTEGER IRAY,ITYPE
      REAL G1NEW,G2NEW
C
C This subroutine determines the take-off parameters of the ray during
C 3-D two-point ray tracing by means of the shooting method.
C
C                                                  
C The subroutine is not fully debugged. If you will obtain the error
C message due to the bug in any of the RP* subroutine, you may try to
C change slightly the input data for the take-off parameters of rays
C (anyone of the
C AERR, PRM0,
C PAR1L, PAR2L,
C PAR1A, PAR2A, PAR1B, PAR2B,
C ANUM, BNUM)
C and run again.  The authors will appreciate any information concerning
C the bugs in the code.
C
C Most important numerical parameters for 3-D two-point ray tracing are
C the parameters listed above, together with parameter
C XERR. See also
C parameters controlling
C the computation of a single ray.
C
C To choose the best shooting parameters it may be useful to
C generate simple plots of the distribution of rays on the normalized
C ray domain or on the reference surface using, e.g., program
C RPPLOT.
C
C Do not forget to view logout file after finishing a computation.
C
C The subroutine is able to produce formatted output files, suitable
C for plotting. This may be very useful for
C debugging or when choosing the optimum shooting parameters.
C Remove the first "RETURN" command in the subroutine
C RPSTOR for getting the output files.
C See the subroutine RPSTOR for the description of the output files.
C
C For the detailed description of the shooting algorithm refer to
C Bulant,P.,1996, Two-point ray tracing in 3-D.
C  Pure and Applied Geophysics vol 148, 421-446
C Bulant,P.,1995, Two-point ray tracing in 3-D.  In: Seismic Waves
C  in Complex 3-D Structures, Report 3, pp. 37-64, Department of
C  Geophysics, Charles University, Prague.
C
C----------------------------------------------------------------------
C
C Input:
C     IRAY... Number of the already  computed rays.  IRAY=0 at the
C             beginning of  computation of a new elementary wave.
C             Otherwise, the output from the previous invocation of
C             RP3D.
C     ITYPE.. Type of the last computed ray.
C             -1000-I:..... Two-point ray to the I'th receiver.
C             other   ..... Other ray.
C
C Output:
C     IRAY... IRAY=0 when all rays have been computed and the
C             computation of the elementary wave is at termination.
C             Otherwise, input value increased by 1.
C     ITYPE.. Type of ray:
C             0: .......... Basic ray.
C             -2:.......... Auxiliary ray.
C             -1000-I:..... Auxiliary ray when searching for two-point
C                           ray to the I'th receiver.
C     G1NEW,G2NEW... If a new ray is to be traced, take-off parameters
C                    of the new ray.
C
C Subroutines and external functions required:
      EXTERNAL RPDIV,RPNEW,RPINTS,RPWHAD,RPMEM,RPTRI1,RPAUX1,RPINTP,
     *RPERAS,RPTMEA,RPLRIT,RPLRIP,RPDI2G,RPLRIL,RPCROS,RPXMEA,RPLRTC,
     *RPDPA,RPHPDI,RPLTCR,RPMEGS,RPERR,RPKBR,RPSTOR,ERROR,WARN,
     *WRITTR,WRITBR
C     LENGTH ... Called by RPMEM and RPINTP.
      LOGICAL RPLRIT,RPLRIP,RPLRIL,RPLTCR
      REAL RPDI2G
C     RPDIV,RPNEW,RPINTS,RPWHAD,RPMEM,RPTRI1,RPAUX1,RPINTP,RPERAS,
C     RPTMEA,RPLRIT,RPLRIP,RPDI2G,RPLRIL,RPCROS,RPXMEA,RPLRTC,RPDPA,
C     RPHPDI,RPLTCR,RPMEGS,RPERR,RPKBR,RPSTOR ... This file.
C     ERROR,WARN ...
C     File error.for.
C     WRITTR,WRITBR ...
C     File writ.for.
C     LENGTH ... File
C     length.for.
C
C.......................................................................
C
C Common block /RPARD/:
      INCLUDE 'rpard.inc'
C     rpard.inc
C     PRM0(2) ... Maximum allowed length of the homogeneous triangles
C                 sides (measured on the reference surface).
C None of the storage locations of the common block are altered.
C............................
C
C Common block /GLIM/:
      INCLUDE 'rp3d.inc'
C     rp3d.inc
C.......................................................................
C Auxiliary storage locations:
      INTEGER IRAY0,ITRI0,ITRI
      INTEGER ITRI0D,ITRI0S,ITRI0X,ITRI0I,ITRI1,ITRIE
      INTEGER KTRID(6),KTRIN(6),KTRIS(6)
      INTEGER ITRNAR
      INTEGER ISHEET,ISH
      REAL G1,G2,G11,G12,G22,S11,S12,S22,X1,X2
      REAL G1X1,G2X1,G1X2,G2X2
      INTEGER ITRAS(3)
      REAL G1S(3),G2S(3)
      INTEGER IGOTO
      INTEGER I1,I2
      LOGICAL LNEWAR,LTRI,LRAY,LAB20,LEND
C
      SAVE IRAY0,ITRI0,ITRI,ITRI0D,ITRI0S,ITRI0X,ITRI0I
      SAVE ITRI1,ITRIE,KTRID,KTRIS,ITRNAR
      SAVE LNEWAR,LAB20,LEND
      SAVE IGOTO,I1
C
C     IRAY0,ITRI0...Number of the already computed rays (triangles)
C                   before adding a new homogeneous triangle.
C     ITRI ...Number of the already computed triangles.
C     ITRI0_..Index of the last processed triangle when:
C          D..Dividing the triangles into homogeneous ones.
C          G..Measuring the triangles in the normalized ray domain.
C          X..Measuring the triangles on the reference surface.
C          I..Searching for two-point rays (interpolation).
C     ITRI1...Number of the already computed triangles when starting
C             the loop for the triangles.
C     ITRIE...When ITRI .gt. ITRIE, RPERAS is to be called.
C     KTRI_...One column from list of triangles.(all parameters
C             of the triangle):
C             KTRI(1),KTRI(2),KTRI(3)...Indices of vertices of the
C                                       triangle.
C             KTRI(4)... Index of the triangle.
C             KTRI(5)... Index of the basic triangle containing given
C                        triangle, zero for basic triangles.
C             KTRI(6)... Type of the triangle.
C               0: new triangle.
C               1: triangle being processed.
C               2: divided triangle.
C               3: homogeneous triangle.
C               4: triangle with all two-point rays determined.
C     KTRID...Working triangle when dividing triangles and when
C             searching for two-point rays.
C     KTRIS...Auxiliary triangle when searching for two-point rays,
C             working triangle when dividing triangle with strange ray.
C     KTRIN...A new triangle to be registrated.
C     ITRNAR..Index of the triangle containing the new auxiliary ray,
C             which have been actually traced during interpolation.
C     ISHEET..Value of integer function distinguishing between rays of
C             different histories, the so-called history function.
C             The history function assigns the rays to various
C             groups according to their history, i.e. according to the
C             structural blocks and interfaces through which the ray
C             has propagated, as well as to the position of its
C             endpoint, and the caustics encountered. Rays, which have
C             propagated through the same model blocks, have crossed
C             the same boundaries, have the same phase shift due to
C             caustics, and are incident, e.g., on the surface of
C             the model, are assigned the same value of the
C             history function.
C     G1,G2 ..Normalized parameters of rays.
C     G11,G12,G22 ... Ray-parameter metric tensor.
C     S11,S12,S22 ... Ray-tube metric tensor.
C     X1,X2 ..Coordinates of the ray on the reference surface.
C     G1X1,G2X1,G1X2,G2X2 ... Derivations of ray parameters according to
C                             the surface coordinates.
C     ITRAS,G1S,G2S ...Types and normalized ray parameters
C                      of the vertices of the triangle, in which
C                      new auxiliary ray starts.
C     IGOTO...Indicates where to go after computing a new ray.
C     I1,I2,..Implied-do variables or variables controlling the loop.
C     J1   ...Auxiliary variable  (number).
C     LNEWAR..Indicates whether the new ray is to be traced.
C     LTRI ...Indicates whether a triangle is in memory.
C     LRAY ...Indicates whether a ray is in memory.
C     LAB20 ..Indicates that inhomogeneous triangles have been created
C             running subroutine RPTMEA or RPDIV.
C     LEND ...Indicates the end of the computation (all the normalized
C             ray domain covered by basic triangles).
C-----------------------------------------------------------------------
C
C
      IF(IRAY.EQ.0) THEN
        GLIMIT(1)= 0.0
        GLIMIT(2)= 1.0
        GLIMIT(3)= 0.0
        GLIMIT(4)= 1.0
        ITRI=0
        LNEWAR=.FALSE.
        LAB20=.FALSE.
        LEND=.FALSE.
        ITRI0D=0
        ITRI0S=0
        ITRI0X=0
        ITRI0I=0
        ITRIE=100
        CALL RPTRI1(ITRI,KTRIS)
        CALL RPAUX1(ITRI,IRAY)
        CALL RPMEM(IRAY,ITYPE,ISHEET,G1,G2,G11,S11,S12,S22,G12,G22,X1,X2
     *             ,G1X1,G2X1,G1X2,G2X2)
        CALL RPDIV(KTRIS,IRAY,ITRI,G1NEW,G2NEW,LNEWAR,LAB20)
        CALL RPSTOR('R',0,KTRIS)
        CALL RPTMEA(I1,ITRI,IRAY,LNEWAR,LAB20,G1NEW,G2NEW)
        CALL RPXMEA(I1,ITRI,IRAY,LNEWAR,LAB20,G1NEW,G2NEW)
        GOTO 10
      ENDIF
C
      CALL RPSTOR('R',IRAY,KTRIS)
      GOTO (19,40,50,150,60) IGOTO
C
C
C     Covering of the ray domain with new basic triangles:
   10 CONTINUE
      IRAY0=IRAY
      ITRI0=ITRI
      LNEWAR=.FALSE.
      CALL RPNEW(IRAY,ITRI,G1NEW,G2NEW,LNEWAR)
      IF (LNEWAR) THEN
C       Trace a new ray, then go to 19.
        ITYPE=0
        IGOTO=1
        GOTO 90
      ENDIF
C
C
  19  CONTINUE
C     Storing new basic triangles:
      DO 18, I1=ITRI0+1,ITRI
        CALL RPTRI3 (I1,LTRI,KTRID)
        IF (LTRI.AND.KTRID(6).EQ.0) CALL RPSTOR ('T',1,KTRID)
  18  CONTINUE
C
C     Dividing new triangles into homogeneous triangles:
  20  CONTINUE
      I1=ITRI0D
      ITRI1=ITRI
      LAB20=.FALSE.
C
C     Loop for new triangles:
  30  CONTINUE
        I1=I1+1
        IF (I1.GT.ITRI1) GOTO 42
        CALL RPTRI3 (I1,LTRI,KTRID)
        IF (.NOT.((KTRID(6).EQ.0).AND.LTRI)) THEN
          ITRI0D=I1
          GOTO 30
        ENDIF
C
C       Dividing triangle I1 into homogeneous triangles:
  40    CONTINUE
        CALL RPDIV(KTRID,IRAY,ITRI,G1NEW,G2NEW,LNEWAR,LAB20)
        IF (LNEWAR) THEN
C         Trace a new ray, then go to 40.
          ITYPE=-2
          IGOTO=2
          GOTO 90
        ENDIF
        ITRI0D=I1
C
        IF (LAB20) THEN
C         Inhomogeneous triangles have been formed running RPDIV:
          GOTO 20
        ENDIF
      GOTO 30
C
C
C     Controlling the size of the homogeneous triangles,
C     dividing triangles too large in the ray-tube metric.
  42  CONTINUE
      I1=ITRI0S
      ITRI1=ITRI
      LNEWAR=.FALSE.
      LAB20=.FALSE.
C
C     Loop for new triangles:
  45  CONTINUE
        I1=I1+1
        IF (I1.GT.ITRI1) GOTO 51
  50    CONTINUE
        CALL RPTMEA(I1,ITRI,IRAY,LNEWAR,LAB20,G1NEW,G2NEW)
        IF (LNEWAR) THEN
C         Trace a new ray, then go to 50.
          ITYPE=-2
          IGOTO=3
          GOTO 90
        ENDIF
        ITRI0S=I1
      GOTO 45
C
  51  CONTINUE
      IF (LAB20) THEN
C       Inhomogeneous triangles have been formed running RPTMEA:
        GOTO 20
      ENDIF
      IF (I1.LT.ITRI) THEN
C       New homogeneous triangles to be measured
C       have been formed running RPTMEA:
        GOTO 42
      ENDIF
C
C
C
C     Controlling the size of the homogeneous triangles,
C     dividing triangles too large in reference surface.
  142 CONTINUE
      IF (PRM0(2).EQ.0.) THEN
C       The value of PRM0(2) is given by input data. PRM0(2)=0 indicates
C       that triangles are not to be measured on the reference surface.
        GOTO 53
      ENDIF
      I1=ITRI0X
      ITRI1=ITRI
      LNEWAR=.FALSE.
      LAB20=.FALSE.
C
C     Loop for new triangles:
  145 CONTINUE
        I1=I1+1
        IF (I1.GT.ITRI1) GOTO 151
  150   CONTINUE
        CALL RPXMEA(I1,ITRI,IRAY,LNEWAR,LAB20,G1NEW,G2NEW)
        IF (LNEWAR) THEN
C         Trace a new ray, then go to 150.
          ITYPE=-2
          IGOTO=4
          GOTO 90
        ENDIF
        ITRI0X=I1
      GOTO 145
C
  151 CONTINUE
      IF (LAB20) THEN
C       Inhomogeneous triangles have been formed running RPXMEA:
        GOTO 20
      ENDIF
      IF (I1.LT.ITRI) THEN
C       New homogeneous triangles have been formed running RPXMEA:
        GOTO 142
      ENDIF
C
C
C     Searching for two-point rays in new homogeneous triangles:
  53  CONTINUE
      I1=ITRI0I
      ITRI1=ITRI
C
C     Loop for new homogeneous triangles:
  55  CONTINUE
        I1=I1+1
        IF (I1.GT.ITRI1) THEN
          IF ((ITRI.NE.ITRI0).OR.(IRAY.NE.IRAY0)) THEN
            IF (ITRI.GE.ITRIE) THEN
C             Deleting unneeded rays and triangles:
              CALL RPERAS
              ITRIE=ITRIE+100
            ENDIF
C           New basic triangle.
            GOTO 10
          ELSE
            IF (.NOT.LEND) THEN
              LEND=.TRUE.
              GOTO 53
            ELSE
C             End of the two-point ray tracing.
              GOTO 95
            ENDIF
          ENDIF
        ENDIF
        CALL RPTRI3(I1,LTRI,KTRID)
        IF (.NOT.((KTRID(6).EQ.3).AND.LTRI)) THEN
          IF (I1.EQ.ITRI0I+1) ITRI0I=I1
          GOTO 55
        ENDIF
        CALL RPRAY(KTRID(1),LRAY,ITYPE,ISHEET,G1,G2,
     *             G11,G12,G22,X1,X2,G1X1,G2X1,G1X2,G2X2)
        IF (.NOT.LRAY) CALL RPERR(1)
        LNEWAR=.FALSE.
C
  60    CONTINUE
        IF (LNEWAR) THEN
C         Last traced ray:
          CALL RPRAY(IRAY,LRAY,ITYPE,ISHEET,G1,G2,
     *               G11,G12,G22,X1,X2,G1X1,G2X1,G1X2,G2X2)
          IF (.NOT.LRAY) CALL RPERR(1)
C         First ray of the triangle in which the last traced ray starts:
          CALL RPTRI3(ITRNAR,LTRI,KTRIS)
          IF (.NOT.LTRI) CALL RPERR(2)
          CALL RPRAY(KTRIS(1),LRAY,ITRAS(1),ISH,G1S(1),G2S(1),
     *               G11,G12,G22,X1,X2,G1X1,G2X1,G1X2,G2X2)
          IF (.NOT.LRAY) CALL RPERR(1)
C
          IF (ISH.NE.ISHEET) THEN
C           Strange ray identified inside homogeneous triangle:
            GOTO 70
          ENDIF
        ENDIF
        CALL RPINTP(KTRID,LNEWAR,IRAY,ITRI,LEND,
     *              G1NEW,G2NEW,ITRNAR,ITYPE)
        IF (LNEWAR) THEN
C         Trace a new ray, then go to 60.
          IGOTO=5
          GOTO 90
        ENDIF
        IF ((KTRID(6).EQ.4).AND.(I1.EQ.ITRI0I+1)) ITRI0I=I1
      GOTO 55
C
C
C     A strange ray identified inside the homogeneous triangle ITRNAR:
  70  CONTINUE
      CALL RPRAY(KTRIS(2),LRAY,ITRAS(2),ISH,G1S(2),G2S(2),
     *           G11,G12,G22,X1,X2,G1X1,G2X1,G1X2,G2X2)
      IF (.NOT.LRAY) CALL RPERR(1)
      CALL RPRAY(KTRIS(3),LRAY,ITRAS(3),ISH,G1S(3),G2S(3),
     *           G11,G12,G22,X1,X2,G1X1,G2X1,G1X2,G2X2)
      IF (.NOT.LRAY) CALL RPERR(1)
C     Dividing of the triangle into inhomogeneous triangles:
      KTRIS(6)=2
      CALL RPTRI2(KTRIS(4),LTRI,KTRIS)
      IF (.NOT.LTRI) CALL RPERR(2)
      IF (KTRIS(5).EQ.0) THEN
        KTRIN(5)=KTRIS(4)
      ELSE
        KTRIN(5)=KTRIS(5)
      ENDIF
      KTRIN(6)=0
      DO 72, I2=1,3
        ITRI=ITRI+1
        KTRIN(1)=KTRIS(I2)
        KTRIN(2)=KTRIS(I2+1)
        IF (I2.EQ.3) KTRIN(2)=KTRIS(1)
        KTRIN(3)=IRAY
        KTRIN(4)=ITRI
        CALL RPTRI1(ITRI,KTRIN)
        CALL RPSTOR('T',1,KTRIN)
  72  CONTINUE
      GOTO 20
C
C
C     Tracing a new ray:
  90  CONTINUE
      IRAY=IRAY+1
      RETURN
C
C
C     End of computation:
  95  CONTINUE
C
      CALL RPSTOR('R',-1,KTRIS)
      IRAY=0
      RETURN
      END
C
C=======================================================================
C
      SUBROUTINE RPDIV(KTRID,IRAY,ITRI,G1NEW,G2NEW,LNEWAR,LAB20)
C
C-----------------------------------------------------------------------
      INTEGER KTRID(6),IRAY,ITRI
      REAL G1NEW,G2NEW
      LOGICAL LNEWAR,LAB20
C Subroutine designed to divide the given triangle into homogeneous
C triangles.  The given triangle must not be altered between individual
C invocations of this subroutine until the given triangle is completely
C covered by homogeneous triangles.
C
C Input:
C     KTRID...Parameters of the triangle to be divided (one column of
C             array KTRI).
C     IRAY... Index of the last traced ray.
C     ITRI... Index of the last triangle.
C Output:
C     G1NEW,G2NEW... If a new ray is to be traced,
C                    parameters of the new ray.
C     LNEWAR   ...   Indicates whether a new ray is to be traced.
C     LAB20    ...   Indicates that inhomogeneous triangles were
C                    made running RPDIV.
C
C Subroutines and external functions required:
      EXTERNAL RPLRIP,RPLRIL,RPLRIT,RPDI2G
      REAL RPDI2G
      LOGICAL RPLRIP,RPLRIL,RPLRIT
C
C Coded by Petr Bulant
C
C.......................................................................
C
C Common blocks /GLIM/ and /BOURA/:
      INCLUDE 'rp3d.inc'
C     rp3d.inc
C............................
C
C Common block /RPARD/:
      INCLUDE 'rpard.inc'
C     rpard.inc
C     AERR...Maximum distance of the boundary rays.
C     PRM0(1) ... Maximum allowed distance of the boundary ray from the
C                 shadow zone (measured on the reference surface).
C.......................................................................
C
      REAL ZERO,ZERO1,SIDE
      PARAMETER (ZERO =.0000001)
      PARAMETER (ZERO1=.0000000001)
      PARAMETER (SIDE=1.1547)
      REAL BSTEP2
      PARAMETER (BSTEP2=0.23)
      REAL AERR2
      REAL AR0
C                                                   
      INTEGER MPOL,MPOLH
      PARAMETER (MPOL=500)
      PARAMETER (MPOLH=500)
      INTEGER NPOL,NPOLH,KPOL(MPOL,4),KPOLH(MPOLH,4)
      REAL GPOL(MPOL,2),GPOLH(MPOLH,2)
      INTEGER MLINE
      PARAMETER (MLINE=500)
      INTEGER NLINE,KLINE(MLINE,4)
      INTEGER KTRIN(6),KTRIS(6),KTRIT(6)
      INTEGER MAXR
      INTEGER ITYPE,ISH
      REAL G1,G2,G11,G12,G22,X1,X2
      REAL G1X1,G2X1,G1X2,G2X2
      INTEGER KRAYA0,KRAYB0
      INTEGER KRAYA,ITYPEA,ISHA,KRAYB,ITYPEB,ISHB,KRAYC,ITYPEC,ISHC,
     *        KRAYD,ITYPED,ISHD,KRAYE,KRAYI,KRAYJ
      INTEGER KRAYD0
      INTEGER ITYPEX,ISHX
      REAL G1X,G2X,G11X,G12X,G22X
      REAL G1A,G2A,G11A,G12A,G22A,G1X1A,G2X1A,G1X2A,G2X2A,
     *     G1B,G2B,G11B,G12B,G22B,G1X1B,G2X1B,G1X2B,G2X2B,
     *     G1C,G2C,G11C,G12C,G22C,G1X1C,G2X1C,G1X2C,G2X2C,
     *     G1D,G2D,G11D,G12D,G22D,G1X1D,G2X1D,G1X2D,G2X2D,
     *     G1E,G2E,G1I,G2I,G1J,G2J,G1K,G2K
      REAL AREA,AREA1,DIST2,MINDIS
      REAL G11POM,G12POM,G22POM
      REAL DG1,DG2,AAA,BBB,DETG,SQ
      REAL DG1N,DG2N,PAR
      INTEGER IGOTO,ISTART,INEWR,ISHP
      INTEGER I1,I2,I3,I4,I5
      INTEGER J1,J2,J3,J4,J5,J6,J30
      LOGICAL LRAY,LTRI,LSTORE,LINTS,LDGEAE
      SAVE AERR2,AR0,
     *     NPOL,KPOL,GPOL,I1,IGOTO,KRAYA,KRAYB,ISHA,ISHB,ITYPEA,ITYPEB,
     *     G1A,G2A,G1B,G2B,G11A,G11B,G12A,G12B,G22A,G22B,NLINE,KLINE,
     *     KRAYA0,KRAYB0,ISTART,J1,J2,J3,J4,INEWR,AAA,BBB,SQ,KRAYE
     *    ,KRAYC,ISHC,ITYPEC,G1C,G2C,G11C,G12C,G22C,LSTORE,ISHP,J5
     *    ,NPOLH,KPOLH,GPOLH,DG1N,DG2N,PAR,G11POM,G12POM,G22POM
     *    ,KRAYD0,LDGEAE,J30
C     ZERO ...Constant used to decide whether the real variable.EQ.zero.
C     SIDE... Length of basic triangles sides.
C     BSTEP2..The boundary is traced with minimal
C             step BSTEP(=SQRT(BSTEP2)).
C     AERR2...Second power of the maximum distance of the boundary rays.
C     AR0 ... Area of the smallest considered triangle.
C     MPOL,MPOLH...Dimension of arrays KPOL,GPOL,KPOLH,GPOLH.
C     NPOL,NPOLH...Number of rays forming the polygons KPOL,GPOL,KPOLH.
C     KPOL(I,1) ...Indices of rays forming the inhomogeneous polygon
C                  to be divided into homogeneous polygons.
C     KPOL(I,2) ...Values of integer history functions of rays forming
C                  the polygon.
C     KPOL(I,3) ...Types of rays forming the polygon.
C     KPOL(I,4) ...for boundary ray the value of history function of
C                  the other ray from the pair of the boundary rays
C                  otherwise zero.
C     GPOL(I,1),GPOL(I,2) ...Normalized parameters of rays forming
C                            the polygon.
C     KPOLH(I,1)...Indices of the rays forming the homogeneous polygon
C                  to be divided into homogeneous triangles.
C     KPOLH(I,2) ...Sheets of rays forming the polygon.
C     KPOLH(I,3) ...Types of rays forming the polygon.
C     KPOLH(I,4) ...For boundary ray the value of history function of
C              the other ray from the pair of the boundary rays or zero.
C     GPOLH(I,1),GPOLH(I,2) ...Normalized parameters of the rays forming
C                              the homogeneous polygon.
C     NLINE  ...Number of rays in KLINE.
C     KLINE ... When searching for boundary rays on the sides of divided
C               triangle by halving intervals:
C         KLINE(I,1)...Rays shot during the division of the interval.
C         KLINE(I,2)...Sheets of these rays.
C         KLINE(I,3)...Types of these rays.
C         Kline(i,4) ..The value of history function of the other
C                      ray from the pair of the boundary rays or zero.
C     KLINE .. When demarcating the boundary of the homogeneous polygon:
C         KLINE(1,1)  ...  The first ray of the homogeneous polygon.
C         KLINE(NLINE,1)...The last ray of the homogeneous polygon.
C         KLINE(I,1)...Rays shot during demarcating the boundary.
C         KLINE(I,2)...Sheets of these rays.
C         KLINE(I,3)...Types of these rays.
C         KLINE(I,4) ..The value of history function of the other
C                      ray from the pair of the boundary rays.
C         KLINE(I,1)<0 notes that side I,I+1 in KLINE is to be divided.
C     KTRIN...Parameters of the new triangle to be registrated (new
C             column to be added into array KTRI).
C     KTRIS...Working triangle when dividing incorrectly made triangle.
C     MAXR ...Maximum number of the rays in one group.
C     ITYPE.. Type of ray:
C             0: .......... Basic ray.
C             ITYPE.GT.0:.. Boundary ray, ITYPE is the index of the
C                           boundary ray at the other side of the bound.
C             -2:.......... Auxiliary ray,not used.
C             -3:.......... Auxiliary ray,used.
C             -1000-I:..... Two-point ray (to the I'th receiver).
C     ISHEET..Value of integer function distinguishing between rays of
C             different histories.
C     G1,G2 ..Normalized parameters of rays.
C     G11,G12,G22 ... Ray-parameter metric tensor.
C     X1,X2 ..Coordinates of the ray on the reference surface.
C     G1X1,G2X1,G1X2,G2X2 ... Derivations of ray parameters according to
C                             surface coordinates.
C     KRAYA0,KRAYB0.. Indices of rays forming original divided interval.
C     KRAYD0 ...Index of the ray which has indicated that previous
C               triangles have not been formed correctly.
C     KRAYA,B,C,..      ...  Signs of rays      |   auxiliary
C     ITYPEA,B,C,..     ...  Types of rays      |   variables used
C     ISHA,B,C,..  .. Value of history function |   for different rays.
C     Gi(i)A,B,C,..     ...  Parameters of rays |  (always commented)
C     AREA  ... Auxiliary variable (area of the triangle).
C     DIST2 ... Second power of the distance of two rays.
C     MINDIS... Minimum of the distances between the rays.
C     GiiPOM... Average value of the metric tensor.
C     DG1,DG2,AAA,BBB,DETG,SQ ... Auxiliary variables used to compute
C               the distance of rays or the parameters of a new ray.
C     DG1N,DG2N.. Differences of a new ray D from ray C.
C     PAR ... Parameter controlling the difference of a new ray D and C.
C     IGOTO...Indicates where to go after computing a new ray.
C     ISTART..Counts the groups of rays in NPOL, where the demarcation
C             of the boundary leads to crash.
C     INEWR...Counts how many times the new ray D was proposed.
C             INEWR=-1 indicates that D is an intersection point.
C     ISHP ...Isheet of the rays of the homogeneous polygon.
C     I1,2,3,4 ..Implied-do variables or variables controlling the loop.
C     I1 ...  Controls the main loop of checking KPOL (until label 50).
C     I4 ...  When ISTART>0 and searching for basic homogeneous polygon,
C             I4 is the reduced value of ISTART.
C     J1,2,3,4 .. Auxiliary variables (numbers).
C     J1 ...  Free until label 100, than sequence in KPOL of the
C             beginning of the KPOLH.
C     J2 ...  Free until label 100, than sequence in KPOL of the
C             end of the KPOLH.
C     J3 ...  Free until label 105, than shows actual position in KLINE.
C     J4 ...  The sequence in KPOL of the side where
C             the intersection has occurred.
C     J5 ...  When MAXR=0 and starting consequently from all the groups,
C             the sequence of the group.
C     J30...  Used when closing the homogeneous polygon:
C               J30.LE.J3 initiates the search for neighbouring rays of
C                 KLINE with different values of KLINE(I,3).
C               Then the part of boundary between these rays is
C                 demarcated and J30 stores the value of J3.
C               After this J30 is assigned the value 999999 and the
C                 demarcation of the boundary continues.
C     LRAY ...Indicates whether the ray IRAY is in memory.
C     LTRI ...Indicates whether the triangle ITRI is in memory.
C     LSTORE..LSTORE=TRUE indicates that the polygon was repaired and
C             that new boundary rays may have to be stored in KBR.
C     LINTS ..Indicates whether the intersection appeared.
C     LDGEAE..Indicates that the new ray D is being searched with
C             minimal step DG equal to AERR.
C-----------------------------------------------------------------------
C
C     Start of triangle dividing
      IF (IRAY.EQ.0) THEN
        NBR=0
        AERR2=AERR**2
        AR0=AERR2*0.4330127/9.
        ISTART=0
        PAR=0.05
        LNEWAR=.FALSE.
        LSTORE=.FALSE.
        J5=0
        RETURN
      ENDIF
C
      IF (KTRID(6).EQ.1) THEN
        GOTO (30,110,120,130,160) IGOTO
      ENDIF
C
      IF (AERR.GT.1.) THEN
C       Boundary rays are not to be searched for,
C       triangle is not to be divided:
        KTRID(6)=2
        CALL RPTRI2(KTRID(4),LTRI,KTRID)
        IF (.NOT.LTRI) CALL RPERR(2)
        LNEWAR=.FALSE.
        RETURN
      ENDIF
C
      LNEWAR=.FALSE.
      ISTART=0
      LSTORE=.FALSE.
      J5=0
      CALL RPRAY(KTRID(1),LRAY,ITYPEA,ISHA,G1A,G2A,G11A,G12A,G22A,
     *           X1,X2,G1X1A,G2X1A,G1X2A,G2X2A)
      IF (.NOT.LRAY) CALL RPERR(1)
      KRAYA=KTRID(1)
      CALL RPRAY(KTRID(2),LRAY,ITYPEB,ISHB,G1B,G2B,G11B,G12B,G22B,
     *           X1,X2,G1X1B,G2X1B,G1X2B,G2X2B)
      IF (.NOT.LRAY) CALL RPERR(1)
      KRAYB=KTRID(2)
      CALL RPRAY(KTRID(3),LRAY,ITYPEC,ISHC,G1C,G2C,G11C,G12C,G22C,
     *           X1,X2,G1X1C,G2X1C,G1X2C,G2X2C)
      IF (.NOT.LRAY) CALL RPERR(1)
      KRAYC=KTRID(3)
C     ..A,..B,..C .. Vertices of divided triangle.
C     Controlling the size of triangle surface :
      G11POM=(G11A+G11C+G11B)/3.
      G12POM=(G12A+G12C+G12B)/3.
      G22POM=(G22A+G22C+G22B)/3.
      DG1=G1B-G1A
      DG2=G2B-G2A
      DETG=G11POM*G22POM - G12POM*G12POM
      IF (DETG.LT.ZERO) CALL RPERR(4)
      AREA=SQRT(DETG)*((DG1*(G2C-G2A)-DG2*(G1C-G1A))*.5)
      IF (AREA.LT.AR0) THEN
C       0.4330127=SQRT(3)/4
C       Triangle too small or left-handed.
        KTRID(6)=2
        CALL RPTRI2(KTRID(4),LTRI,KTRID)
        IF (.NOT.LTRI) CALL RPERR(2)
        LNEWAR=.FALSE.
        RETURN
      ENDIF
C     Controlling the size of triangle sides:
      DIST2=RPDI2G(G1A,G2A,G1B,G2B,G11POM,G12POM,G22POM)
      IF (DIST2.LE.AERR2*0.25) KTRID(6)=2
      DIST2=RPDI2G(G1C,G2C,G1B,G2B,G11POM,G12POM,G22POM)
      IF (DIST2.LE.AERR2*0.25) KTRID(6)=2
      DIST2=RPDI2G(G1A,G2A,G1C,G2C,G11POM,G12POM,G22POM)
      IF (DIST2.LE.AERR2*0.25) KTRID(6)=2
      IF (KTRID(6).EQ.2) THEN
C       Triangle too small.
        CALL RPTRI2(KTRID(4),LTRI,KTRID)
        IF (.NOT.LTRI) CALL RPERR(2)
        LNEWAR=.FALSE.
        RETURN
      ENDIF
C
      KTRID(6)=1
      NPOL=3
      KPOL(1,1)=KTRID(1)
      KPOL(2,1)=KTRID(2)
      KPOL(3,1)=KTRID(3)
      KPOL(1,2)=ISHA
      KPOL(2,2)=ISHB
      KPOL(3,2)=ISHC
      KPOL(1,3)=ITYPEA
      KPOL(2,3)=ITYPEB
      KPOL(3,3)=ITYPEC
      KPOL(1,4)=0
      KPOL(2,4)=0
      KPOL(3,4)=0
      GPOL(1,1)=G1A
      GPOL(2,1)=G1B
      GPOL(3,1)=G1C
      GPOL(1,2)=G2A
      GPOL(2,2)=G2B
      GPOL(3,2)=G2C
C
C     Array KBR must be searched and the rays from KBR must be used.
C     Loop for rays in array KBR:
      KRAYB0=0
      I2=1
      IF (NBR.GT.2) THEN
  1   CONTINUE
        IF ((KRAYA.EQ.KBR(I2,1)).AND.(KRAYB.EQ.KBR(I2+1,1))) THEN
          KRAYB0=KRAYB
          KRAYA0=KRAYA
        ENDIF
        IF ((KRAYB.EQ.KBR(I2,1)).AND.(KRAYC.EQ.KBR(I2+1,1))) THEN
          KRAYB0=KRAYC
          KRAYA0=KRAYB
        ENDIF
        IF ((KRAYC.EQ.KBR(I2,1)).AND.(KRAYA.EQ.KBR(I2+1,1))) THEN
          KRAYB0=KRAYA
          KRAYA0=KRAYC
        ENDIF
        J1=KBR(I2+2,1)
        IF (KRAYB0.NE.0) THEN
C         Boundary rays found in KBR, correcting polygon:
          DO 2, I1=1,NPOL
            IF (KPOL(I1,1).EQ.KRAYB0) J3=I1
  2       CONTINUE
C
          IF (KRAYB.NE.KBR(I2+3,1)) THEN
            IF (NPOL.GE.MPOL) CALL RPERR(5)
            DO 4, I3=NPOL,J3,-1
              KPOL(I3+1,1)=KPOL(I3,1)
              KPOL(I3+1,2)=KPOL(I3,2)
              KPOL(I3+1,3)=KPOL(I3,3)
              KPOL(I3+1,4)=KPOL(I3,4)
              GPOL(I3+1,1)=GPOL(I3,1)
              GPOL(I3+1,2)=GPOL(I3,2)
  4         CONTINUE
            KPOL(J3,1)=KBR(I2+3,1)
            KPOL(J3,2)=KBR(I2+3,2)
            KPOL(J3,3)=KBR(I2+3,3)
            KPOL(J3,4)=0
            IF (KPOL(J3,3).GT.0) THEN
              CALL RPRAY(KPOL(J3,3),LRAY,ITYPE,ISH,G1,G2,
     *                   G11,G12,G22,X1,X2,G1X1,G2X1,G1X2,G2X2)
              IF (LRAY) THEN
                KPOL(J3,4)=ISH
              ENDIF
            ENDIF
            GPOL(J3,1)=GBR(I2+3,1)
            GPOL(J3,2)=GBR(I2+3,2)
            NPOL=NPOL+1
            J3=J3+1
          ENDIF
C
          IF (J1.GE.3) THEN
            IF (NPOL+J1-2.GT.MPOL) CALL RPERR(5)
            DO 6, I3=NPOL,J3,-1
              KPOL(I3+J1-2,1)=KPOL(I3,1)
              KPOL(I3+J1-2,2)=KPOL(I3,2)
              KPOL(I3+J1-2,3)=KPOL(I3,3)
              KPOL(I3+J1-2,4)=KPOL(I3,4)
              GPOL(I3+J1-2,1)=GPOL(I3,1)
              GPOL(I3+J1-2,2)=GPOL(I3,2)
  6         CONTINUE
            DO 8, I3=2,J1-1
              KPOL(J3-2+I3,1)=KBR(I2+2+I3,1)
              KPOL(J3-2+I3,2)=KBR(I2+2+I3,2)
              KPOL(J3-2+I3,3)=KBR(I2+2+I3,3)
              KPOL(J3-2+I3,4)=0
              IF (KPOL(J3-2+I3,3).GT.0) THEN
                CALL RPRAY(KPOL(J3-2+I3,3),LRAY,ITYPE,ISH,G1,G2,
     *                     G11,G12,G22,X1,X2,G1X1,G2X1,G1X2,G2X2)
                IF (LRAY) THEN
                  KPOL(J3-2+I3,4)=ISH
                ENDIF
              ENDIF
              GPOL(J3-2+I3,1)=GBR(I2+2+I3,1)
              GPOL(J3-2+I3,2)=GBR(I2+2+I3,2)
  8         CONTINUE
            NPOL=NPOL+J1-2
            J3=J3+J1-2
          ENDIF
C
          IF (J1.GE.2) THEN
            IF (KRAYA.NE.KBR(I2+2+J1,1)) THEN
              IF (NPOL+1.GT.MPOL) CALL RPERR(5)
              DO 10, I3=NPOL,J3,-1
                KPOL(I3+1,1)=KPOL(I3,1)
                KPOL(I3+1,2)=KPOL(I3,2)
                KPOL(I3+1,3)=KPOL(I3,3)
                KPOL(I3+1,4)=KPOL(I3,4)
                GPOL(I3+1,1)=GPOL(I3,1)
                GPOL(I3+1,2)=GPOL(I3,2)
  10          CONTINUE
              KPOL(J3,1)=KBR(I2+2+J1,1)
              KPOL(J3,2)=KBR(I2+2+J1,2)
              KPOL(J3,3)=KBR(I2+2+J1,3)
              KPOL(J3,4)=0
              IF (KPOL(J3,3).GT.0) THEN
                CALL RPRAY(KPOL(J3,3),LRAY,ITYPE,ISH,G1,G2,
     *                     G11,G12,G22,X1,X2,G1X1,G2X1,G1X2,G2X2)
                IF (LRAY) THEN
                  KPOL(J3,4)=ISH
                ENDIF
              ENDIF
              GPOL(J3,1)=GBR(I2+2+J1,1)
              GPOL(J3,2)=GBR(I2+2+J1,2)
              NPOL=NPOL+1
            ENDIF
          ENDIF
C
          J2=J1+3
          NBR=NBR-J2
          DO 12, I3=I2,NBR
            KBR(I3,1)=KBR(I3+J2,1)
            KBR(I3,2)=KBR(I3+J2,2)
            KBR(I3,3)=KBR(I3+J2,3)
            GBR(I3,1)=GBR(I3+J2,1)
            GBR(I3,2)=GBR(I3+J2,2)
  12      CONTINUE
          KRAYB0=0
          IF (I2.LT.NBR) GOTO 1
C
        ENDIF
        I2=I2+3+J1
      IF (I2.LT.NBR) GOTO 1
      ENDIF
C     End of the loop for KBR.
      IF ((NPOL.EQ.3).AND.(ISHA.EQ.ISHB).AND.(ISHA.EQ.ISHC)) THEN
C       Triangle is really homogeneous:
        KTRID(6)=3
        CALL RPTRI2(KTRID(4),LTRI,KTRID)
        IF (.NOT.LTRI) CALL RPERR(2)
        LNEWAR=.FALSE.
        RETURN
      ENDIF
C
C     Checking the integrity of the inhomogeneous polygon.
C     Finding boundary rays, if needed.
C
  15  CONTINUE
C     Checking the size of the sides of the polygon:
      J6=0
      CALL RPRAY(KPOL(NPOL,1),LRAY,ITYPE,ISH,G1,G2,G11A,G12A,G22A,
     *           X1,X2,G1X1,G2X1,G1X2,G2X2)
      IF (.NOT.LRAY) CALL RPERR(1)
      CALL RPRAY(KPOL(1,1),LRAY,ITYPE,ISH,G1,G2,G11B,G12B,G22B,
     *           X1,X2,G1X1,G2X1,G1X2,G2X2)
      IF (.NOT.LRAY) CALL RPERR(1)
      G11POM=(G11A+G11B)/2.
      G12POM=(G12A+G12B)/2.
      G22POM=(G22A+G22B)/2.
      DIST2=RPDI2G(GPOL(1,1),GPOL(1,2),GPOL(NPOL,1),GPOL(NPOL,2),
     *             G11POM,G12POM,G22POM)
      IF (DIST2.LE.AERR2) THEN
        J6=J6+1
      ENDIF
      DO 16, I1=1,NPOL-1
        CALL RPRAY(KPOL(I1,1),LRAY,ITYPE,ISH,G1,G2,G11A,G12A,G22A,
     *             X1,X2,G1X1,G2X1,G1X2,G2X2)
        IF (.NOT.LRAY) CALL RPERR(1)
        CALL RPRAY(KPOL(I1+1,1),LRAY,ITYPE,ISH,G1,G2,G11B,G12B,G22B,
     *             X1,X2,G1X1,G2X1,G1X2,G2X2)
        IF (.NOT.LRAY) CALL RPERR(1)
        G11POM=(G11A+G11B)/2.
        G12POM=(G12A+G12B)/2.
        G22POM=(G22A+G22B)/2.
        DIST2=RPDI2G(GPOL(I1,1),GPOL(I1,2),GPOL(I1+1,1),GPOL(I1+1,2),
     *               G11POM,G12POM,G22POM)
        IF (DIST2.LE.AERR2) THEN
          J6=J6+1
        ENDIF
  16  CONTINUE
      IF (J6.EQ.NPOL) THEN
C       All of the sides of the polygon are shorter than AERR:
        GOTO 21
      ENDIF
C     Checking the size of the polygon:
      AREA1=0.
      DO 19, I1=1,NPOL-2
        CALL RPRAY(KPOL(I1,1),LRAY,ITYPE,ISH,G1,G2,G11,G12,G22,
     *             X1,X2,G1X1,G2X1,G1X2,G2X2)
        IF (.NOT.LRAY) CALL RPERR(1)
        DG1=GPOL(I1,1)-GPOL(NPOL,1)
        DG2=GPOL(I1,2)-GPOL(NPOL,2)
        DETG=G11*G22 - G12*G12
        IF (DETG.LT.ZERO) CALL RPERR(4)
        AREA=SQRT(DETG)*((DG1*(GPOL(I1+1,2)-GPOL(I1,2))
     *       -DG2*(GPOL(I1+1,1)-GPOL(I1,1)))*.5)
        AREA1=AREA1+AREA
 19   CONTINUE
      IF (AREA1.GE.AR0) THEN
        I1=2
        GOTO 20
      ENDIF
C     The area of the polygon is quite little:
  21  CONTINUE
C       The inhomogeneous polygon will be simply divided into
C       homogeneous triangles:
        I1=1
  18    CONTINUE
          IF(I1.GT.1) THEN
            J1=I1-1
          ELSE
            J1=NPOL
          ENDIF
          IF(I1.LT.NPOL) THEN
            J2=I1+1
          ELSE
            J2=1
          ENDIF
          IF ((KPOL(J1,2).EQ.KPOL(I1,2)).AND.
     *        (KPOL(J2,2).EQ.KPOL(I1,2))) THEN
            IF (RPLRIT(.FALSE.,GPOL(J1,1),GPOL(J1,2),GPOL(I1,1),
     *          GPOL(I1,2),GPOL(J2,1),GPOL(J2,2),G1A,G2A,AREA)) THEN
              ITRI=ITRI+1
              KTRIN(1)=IABS(KPOL(J1,1))
              KTRIN(2)=IABS(KPOL(I1,1))
              KTRIN(3)=IABS(KPOL(J2,1))
              KTRIN(4)=ITRI
              IF (KTRID(5).EQ.0) THEN
                KTRIN(5)=KTRID(4)
              ELSE
                KTRIN(5)=KTRID(5)
              ENDIF
              KTRIN(6)=3
              CALL RPTRI1(ITRI,KTRIN)
              CALL RPSTOR('T',1,KTRIN)
              NPOL=NPOL-1
              DO 17, I2=I1,NPOL
                KPOL(I1,1)=KPOL(I1+1,1)
                KPOL(I1,2)=KPOL(I1+1,2)
                KPOL(I1,3)=KPOL(I1+1,3)
                KPOL(I1,4)=KPOL(I1+1,4)
                GPOL(I1,1)=GPOL(I1+1,1)
                GPOL(I1,2)=GPOL(I1+1,2)
  17          CONTINUE
              I1=1
              GOTO 18
            ENDIF
          ENDIF
        I1=I1+1
        IF (I1.LE.NPOL) GOTO 18
        KTRID(6)=2
        CALL RPTRI2(KTRID(4),LTRI,KTRID)
        IF (.NOT.LTRI) CALL RPERR(2)
        LNEWAR=.FALSE.
        RETURN
C     The inhomogeneous polygon was simply divided into
C     homogeneous triangles.
C
C     Loop for rays in the inhomogeneous polygon:
  20  CONTINUE
C       Rays with the same ISHEET:
        IF (KPOL(I1-1,2).EQ.KPOL(I1,2)) GOTO 50
C
C       Boundary rays:
        IF ((KPOL(I1-1,3).EQ.KPOL(I1,1)).OR.
     *      (KPOL(I1-1,1).EQ.KPOL(I1,3))) GOTO 50
C
        KRAYA=KPOL(I1-1,1)
        KRAYB=KPOL(I1,1)
        IF ((GPOL(I1-1,2).EQ.GLIMIT(3)).AND.(GPOL(I1,2).EQ.GLIMIT(3)))
     *    THEN
          KRAYA0=0
          KRAYB0=0
        ELSE
          KRAYA0=KRAYA
          KRAYB0=KRAYB
        ENDIF
C
C       Dividing the interval KPOL(I1-1,1),KPOL(I1,1):
        CALL RPRAY(KRAYA,LRAY,ITYPEA,ISHA,G1A,G2A,
     *            G11A,G12A,G22A,X1,X2,G1X1A,G2X1A,G1X2A,G2X2A)
        IF (.NOT.LRAY) CALL RPERR(1)
        CALL RPRAY(KRAYB,LRAY,ITYPEB,ISHB,G1B,G2B,
     *            G11B,G12B,G22B,X1,X2,G1X1B,G2X1B,G1X2B,G2X2B)
        IF (.NOT.LRAY) CALL RPERR(1)
        NLINE=0
        GOTO 40
C
C       Entry point when a new ray C was traced during the
C       division of the interval formed by rays A and B.
  30    CALL RPRAY(IRAY,LRAY,ITYPEC,ISHC,G1C,G2C,G11C,G12C,G22C,X1,X2
     *            ,G1X1C,G2X1C,G1X2C,G2X2C)
        IF (.NOT.LRAY) CALL RPERR(1)
        KRAYC=IRAY
        IF (ISHC.EQ.ISHA) THEN
           KRAYA= KRAYC
          ITYPEA=ITYPEC
             G1A=   G1C
             G2A=   G2C
            G11A=  G11C
            G12A=  G12C
            G22A=  G22C
           G1X1A= G1X1C
           G2X1A= G2X1C
           G1X2A= G1X2C
           G2X2A= G2X2C
        ELSE
          IF (NLINE.GE.MLINE) CALL RPERR(7)
          NLINE=NLINE+1
          KLINE(NLINE,1)=KRAYB
          KLINE(NLINE,2)=ISHB
          KLINE(NLINE,3)=ITYPEB
          KLINE(NLINE,4)=0
          IF (ITYPEB.GT.0) THEN
            CALL RPRAY(ITYPEB,LRAY,ITYPE,ISH,G1,G2,
     *                 G11,G12,G22,X1,X2,G1X1,G2X1,G1X2,G2X2)
            IF (LRAY) THEN
              KLINE(NLINE,4)=ISH
            ENDIF
          ENDIF
           KRAYB= KRAYC
          ITYPEB=ITYPEC
            ISHB=  ISHC
             G1B=   G1C
             G2B=   G2C
            G11B=  G11C
            G12B=  G12C
            G22B=  G22C
           G1X1B= G1X1C
           G2X1B= G2X1C
           G1X2B= G1X2C
           G2X2B= G2X2C
        ENDIF
C
  40    CONTINUE
C       Interval A,B is proposed, now deciding whether is to be divided:
        G11POM=(G11A+G11B)/2.
        G12POM=(G12A+G12B)/2.
        G22POM=(G22A+G22B)/2.
        DIST2=RPDI2G(G1A,G2A,G1B,G2B,G11POM,G12POM,G22POM)
        IF (DIST2.GT.AERR2) THEN
          G1NEW=(G1A+G1B)/2.
          G2NEW=(G2A+G2B)/2.
          IF (((G1NEW.EQ.G1A).AND.(G2NEW.EQ.G2A)).OR.
     *        ((G1NEW.EQ.G1B).AND.(G2NEW.EQ.G2B))) CALL RPERR(3)
C         Trace a new ray, then go to 30.
          IGOTO=1
          LNEWAR=.TRUE.
          RETURN
        ELSE
          IF (PRM0(1).NE.0.) THEN
            IF ((ISHA.GT.0).OR.(ISHB.GT.0)) THEN
              CALL RPMEGS(ISHA,ISHB,G1X1A,G2X1A,G1X2A,G2X2A,
     *                              G1X1B,G2X1B,G1X2B,G2X2B,G11,G12,G22)
              DIST2=RPDI2G(G1A,G2A,G1B,G2B,G11,G12,G22)
              IF (DIST2.GT.1.) THEN
                G1NEW=(G1A+G1B)/2.
                G2NEW=(G2A+G2B)/2.
                IF (((G1NEW.EQ.G1A).AND.(G2NEW.EQ.G2A)).OR.
     *              ((G1NEW.EQ.G1B).AND.(G2NEW.EQ.G2B))) CALL RPERR(3)
C               Trace a new ray, then go to 30.
                IGOTO=1
                LNEWAR=.TRUE.
                RETURN
              ENDIF
            ENDIF
          ENDIF
C         Rays A and B are boundary rays:
          CALL RPRAY(KRAYA,LRAY,ITYPEA,ISHA,G1A,G2A,G11A,G12A,G22A,X1,X2
     *               ,G1X1,G2X1,G1X2,G2X2)
          IF (.NOT.LRAY) CALL RPERR(1)
          ITYPEA=KRAYB
          CALL RPMC1(KRAYA,ITYPEA)
          CALL RPSTOR('R',KRAYA,KTRIS)
          CALL RPRAY(KRAYB,LRAY,ITYPEB,ISHB,G1B,G2B,G11B,G12B,G22B,X1,X2
     *               ,G1X1,G2X1,G1X2,G2X2)
          IF (.NOT.LRAY) CALL RPERR(1)
          ITYPEB=KRAYA
          CALL RPMC1(KRAYB,ITYPEB)
          CALL RPSTOR('R',KRAYB,KTRIS)
          IF (LSTORE) THEN
C           When the rays are on the sides of the basic triangle which
C           contains the divided triangle, storing them to the KBR:
            IF (KTRID(5).NE.0) THEN
              CALL RPTRI3(KTRID(5),LTRI,KTRIS)
              IF (.NOT.LTRI) CALL RPERR(2)
            ELSE
              KTRIS(1)=KTRID(1)
              KTRIS(2)=KTRID(2)
              KTRIS(3)=KTRID(3)
            ENDIF
            CALL RPRAY(KTRIS(1),LRAY,ITYPEC,ISHC,G1C,G2C,G11C,G12C,G22C,
     *                 X1,X2,G1X1,G2X1,G1X2,G2X2)
            IF (.NOT.LRAY) CALL RPERR(1)
            CALL RPRAY(KTRIS(2),LRAY,ITYPED,ISHD,G1D,G2D,G11D,G12D,G22D,
     *                 X1,X2,G1X1,G2X1,G1X2,G2X2)
            IF (.NOT.LRAY) CALL RPERR(1)
            CALL RPRAY(KTRIS(3),LRAY,ITYPE,ISH,G1E,G2E,G11,G12,G22,
     *                 X1,X2,G1X1,G2X1,G1X2,G2X2)
            IF (.NOT.LRAY) CALL RPERR(1)
            IF (RPLRIL(G1A,G2A,G1C,G2C,G1E,G2E).AND.
     *          RPLRIL(G1B,G2B,G1C,G2C,G1E,G2E)) THEN
C             Boundary rays are lying on the side CE (side 3,1):
              KRAYC=KTRIS(1)
              KRAYD=KTRIS(3)
            ELSEIF (RPLRIL(G1A,G2A,G1C,G2C,G1D,G2D).AND.
     *              RPLRIL(G1B,G2B,G1C,G2C,G1D,G2D)) THEN
C             Boundary rays are lying on the side CD (side 1,2):
              KRAYC=KTRIS(2)
              KRAYD=KTRIS(1)
            ELSEIF (RPLRIL(G1A,G2A,G1D,G2D,G1E,G2E).AND.
     *              RPLRIL(G1B,G2B,G1D,G2D,G1E,G2E)) THEN
C             Boundary rays are lying on the side DE (side 2,3):
              KRAYC=KTRIS(3)
              KRAYD=KTRIS(2)
            ELSE
C             Rays are not on the sides of the basic triangle:
              GOTO 42
            ENDIF
            J4=1
            IF (NBR.GT.2) THEN
  41        CONTINUE
C             Loop for the rays in KBR:
              IF ((KBR(J4,1).EQ.KRAYC).AND.(KBR(J4+1,1).EQ.KRAYD)) THEN
                IF (KBR(J4+2,1).LE.0) THEN
                  J3=J4+3
                  GOTO 413
                ENDIF
                J3=0
                IF (G1A.NE.G1B) THEN
                  IF ((G1A.LE.GBR(J4,1).AND.
     *                 G1A.GE.GBR(J4+3,1)).OR.
     *                (G1A.GE.GBR(J4,1).AND.
     *                 G1A.LE.GBR(J4+3,1))) J3=J4+3
                  DO 412, I4=J4+3,J4+1+KBR(J4+2,1)
                    IF ((G1A.GE.GBR(I4,1).AND.G1A.LE.GBR(I4+1,1)).OR.
     *              (G1A.LE.GBR(I4,1).AND.G1A.GE.GBR(I4+1,1))) J3=I4+1
  412             CONTINUE
                  I4=J4+2+KBR(J4+2,1)
                  IF ((G1A.LE.GBR(I4,1).AND.
     *                 G1A.GE.GBR(J4+1,1)).OR.
     *                (G1A.GE.GBR(I4,1).AND.
     *                 G1A.LE.GBR(J4+1,1))) J3=I4+1
                ELSE
                  IF ((G2A.LE.GBR(J4,2).AND.
     *                 G2A.GE.GBR(J4+3,2)).OR.
     *                (G2A.GE.GBR(J4,2).AND.
     *                 G2A.LE.GBR(J4+3,2))) J3=J4+3
                  DO 414, I4=J4+3,J4+1+KBR(J4+2,1)
                    IF ((G2A.GE.GBR(I4,2).AND.G2A.LE.GBR(I4+1,2)).OR.
     *              (G2A.LE.GBR(I4,2).AND.G2A.GE.GBR(I4+1,2))) J3=I4+1
  414             CONTINUE
                  I4=J4+2+KBR(J4+2,1)
                  IF ((G2A.LE.GBR(I4,2).AND.
     *                 G2A.GE.GBR(J4+1,2)).OR.
     *                (G2A.GE.GBR(I4,2).AND.
     *                 G2A.LE.GBR(J4+1,2))) J3=I4+1
                ENDIF
  413           IF (J3.NE.0) THEN
C                 Now J3 points to the position in KBR,
C                 where ray A is to be added:
                  IF (NBR+1.GT.MBR) CALL RPERR(8)
                  IF (NBR.GE.J3) NBR=NBR+1
                  DO 415, I4=NBR,J3+1,-1
                    KBR(I4,1)=KBR(I4-1,1)
                    KBR(I4,2)=KBR(I4-1,2)
                    KBR(I4,3)=KBR(I4-1,3)
                    GBR(I4,1)=GBR(I4-1,1)
                    GBR(I4,2)=GBR(I4-1,2)
  415             CONTINUE
                  NBR=MAX0(NBR,J3)
                  KBR(J3,1)=KRAYA
                  KBR(J3,2)=ISHA
                  KBR(J3,3)=ITYPEA
                  GBR(J3,1)=G1A
                  GBR(J3,2)=G2A
                  KBR(J4+2,1)=KBR(J4+2,1)+1
                ENDIF
C
                J3=0
                IF (G1A.NE.G1B) THEN
                  IF ((G1B.LE.GBR(J4,1).AND.
     *                 G1B.GE.GBR(J4+3,1)).OR.
     *                (G1B.GE.GBR(J4,1).AND.
     *                 G1B.LE.GBR(J4+3,1))) J3=J4+3
                  DO 417, I4=J4+3,J4+1+KBR(J4+2,1)
                    IF ((G1B.GE.GBR(I4,1).AND.G1B.LE.GBR(I4+1,1)).OR.
     *              (G1B.LE.GBR(I4,1).AND.G1B.GE.GBR(I4+1,1))) J3=I4+1
  417             CONTINUE
                  I4=J4+2+KBR(J4+2,1)
                  IF ((G1B.LE.GBR(I4,1).AND.
     *                 G1B.GE.GBR(J4+1,1)).OR.
     *                (G1B.GE.GBR(I4,1).AND.
     *                 G1B.LE.GBR(J4+1,1))) J3=I4+1
                ELSE
                  IF ((G2B.LE.GBR(J4,2).AND.
     *                 G2B.GE.GBR(J4+3,2)).OR.
     *                (G2B.GE.GBR(J4,2).AND.
     *                 G2B.LE.GBR(J4+3,2))) J3=J4+3
                  DO 418, I4=J4+3,J4+1+KBR(J4+2,1)
                    IF ((G2B.GE.GBR(I4,2).AND.G2B.LE.GBR(I4+1,2)).OR.
     *              (G2B.LE.GBR(I4,2).AND.G2B.GE.GBR(I4+1,2))) J3=I4+1
  418             CONTINUE
                  I4=J4+2+KBR(J4+2,1)
                  IF ((G2B.LE.GBR(I4,2).AND.
     *                 G2B.GE.GBR(J4+1,2)).OR.
     *                (G2B.GE.GBR(I4,2).AND.
     *                 G2B.LE.GBR(J4+1,2))) J3=I4+1
                ENDIF
                IF (J3.NE.0) THEN
C                 Now J3 points to the position in KBR,
C                 where ray B is to be added:
                  IF (NBR+1.GT.MBR) CALL RPERR(8)
                  IF (NBR.GE.J3) NBR=NBR+1
                  DO 410, I4=NBR,J3+1,-1
                    KBR(I4,1)=KBR(I4-1,1)
                    KBR(I4,2)=KBR(I4-1,2)
                    KBR(I4,3)=KBR(I4-1,3)
                    GBR(I4,1)=GBR(I4-1,1)
                    GBR(I4,2)=GBR(I4-1,2)
  410             CONTINUE
                  NBR=MAX0(NBR,J3)
                  KBR(J3,1)=KRAYB
                  KBR(J3,2)=ISHB
                  KBR(J3,3)=ITYPEB
                  GBR(J3,1)=G1B
                  GBR(J3,2)=G2B
                  KBR(J4+2,1)=KBR(J4+2,1)+1
                ENDIF
                GOTO 42
              ENDIF
              J4=J4+3+KBR(J4+2,1)
            IF (J4.LT.NBR) GOTO 41
            ENDIF
C           The previous triangles possibly
C           have not been formed correctly:
            CALL RPTRIP(-KTRID(4)+1,LTRI,KTRIS)
C           Loop for all the triangles in the memory:
  423       CONTINUE
              CALL RPTRIP(0,LTRI,KTRIS)
              IF (LTRI) THEN
                IF (KTRIS(5).NE.0) GOTO 423
                IF (KTRIS(4).EQ.KTRID(4)) GOTO 423
                IF (KTRIS(4).EQ.KTRID(5)) GOTO 423
                DO 422, I2=1,3
C                 There are indices of the divided side
C                 stored in KRAYC and KRAYD:
                  IF (KRAYC.EQ.KTRIS(I2)) THEN
                    DO 421, I3=1,3
                      IF (KRAYD.EQ.KTRIS(I3)) THEN
C                       Now one must divide either the basic triangle
C                       with index I4, or some of the triangles created
C                       by the division of this triangle:
                        IF (KTRIS(6).NE.2) THEN
                          KTRIS(6)=2
                          CALL RPTRI2(KTRIS(4),LTRI,KTRIS)
                          IF (.NOT.LTRI) CALL RPERR(2)
C                         KRAYD0 is the index of the ray which has
C                         indicated that this triangle is to be divided:
                          ITRI=ITRI+1
                          KTRIN(1)=KTRIS(1)
                          KTRIN(2)=KTRIS(2)
                          KTRIN(3)=KTRIS(3)
                          KTRIN(I2)=KRAYD0
                          KTRIN(4)=ITRI
                          IF (KTRIS(5).EQ.0) THEN
                            KTRIN(5)=KTRIS(4)
                          ELSE
                            KTRIN(5)=KTRIS(5)
                          ENDIF
                          KTRIN(6)=0
                          CALL RPTRI1(ITRI,KTRIN)
                          CALL RPSTOR('T',1,KTRIN)
                          ITRI=ITRI+1
                          KTRIN(1)=KTRIS(1)
                          KTRIN(2)=KTRIS(2)
                          KTRIN(3)=KTRIS(3)
                          KTRIN(I3)=KRAYD0
                          KTRIN(4)=ITRI
                          CALL RPTRI1(ITRI,KTRIN)
                          CALL RPSTOR('T',1,KTRIN)
                          LAB20=.TRUE.
                          GOTO 42
                        ENDIF
                        CALL RPRAY(KRAYD0,LRAY,ITYPE,ISH,G1J,G2J,
     *                            G11,G12,G22,X1,X2,G1X1,G2X1,G1X2,G2X2)
                        IF (.NOT.LRAY) CALL RPERR(1)
                        CALL RPTRIP(-KTRID(4)+1,LTRI,KTRIS)
C                       Loop for all the triangles in the memory:
  431                   CONTINUE
                          CALL RPTRIP(0,LTRI,KTRIT)
                          IF (LTRI) THEN
      IF (KTRIT(5).NE.KTRIS(4)) GOTO 431
      CALL RPRAY(KTRIT(1),LRAY,ITYPE,ISH,G1C,G2C,G11,G12,G22,
     *           X1,X2,G1X1,G2X1,G1X2,G2X2)
      IF (.NOT.LRAY) CALL RPERR(1)
      CALL RPRAY(KTRIT(2),LRAY,ITYPE,ISH,G1D,G2D,G11,G12,G22,
     *           X1,X2,G1X1,G2X1,G1X2,G2X2)
      IF (.NOT.LRAY) CALL RPERR(1)
      CALL RPRAY(KTRIT(3),LRAY,ITYPE,ISH,G1E,G2E,G11,G12,G22,
     *           X1,X2,G1X1,G2X1,G1X2,G2X2)
      IF (.NOT.LRAY) CALL RPERR(1)
      IF (RPLRIL(G1J,G2J,G1C,G2C,G1E,G2E)) THEN
C       Boundary rays are lying on the side CE (side 3,1):
        I4=1
        I5=3
      ELSEIF (RPLRIL(G1J,G2J,G1C,G2C,G1D,G2D)) THEN
C       Boundary rays are lying on the side CD (side 1,2):
        I4=1
        I5=2
      ELSEIF (RPLRIL(G1J,G2J,G1D,G2D,G1E,G2E)) THEN
C       Boundary rays are lying on the side DE (side 2,3):
        I4=2
        I5=3
      ELSE
C       Rays are not on the sides of this triangle:
        GOTO 431
      ENDIF
      ITRI=ITRI+1
      KTRIN(1)=KTRIT(1)
      KTRIN(2)=KTRIT(2)
      KTRIN(3)=KTRIT(3)
      KTRIN(I4)=KRAYD0
      KTRIN(4)=ITRI
      KTRIN(5)=KTRIT(5)
      KTRIN(6)=0
      CALL RPTRI1(ITRI,KTRIN)
      CALL RPSTOR('T',1,KTRIN)
      ITRI=ITRI+1
      KTRIN(1)=KTRIT(1)
      KTRIN(2)=KTRIT(2)
      KTRIN(3)=KTRIT(3)
      KTRIN(I5)=KRAYD0
      KTRIN(4)=ITRI
      CALL RPTRI1(ITRI,KTRIN)
      CALL RPSTOR('T',1,KTRIN)
      LAB20=.TRUE.
      GOTO 431
                          ENDIF
C                       End of the loop for all the triangles
C                       in the memory.
                      ENDIF
  421               CONTINUE
                  ENDIF
  422           CONTINUE
                GOTO 423
              ENDIF
C           End of the loop for all the triangles in the memory.
C
C           The side KRAYC-KRAYD is not in KBR, but there is no other
C           triangle with this side. Rays will be stored to KBR:
            IF (NBR.GE.MBR) CALL RPERR(8)
            CALL RPRAY(KRAYC,LRAY,ITYPE,ISH,G1,G2,G11,G12,G22,
     *                 X1,X2,G1X1,G2X1,G1X2,G2X2)
            IF (.NOT.LRAY) CALL RPERR(1)
            NBR=NBR+1
            KBR(NBR,1)=KRAYC
            KBR(NBR,2)=0
            KBR(NBR,3)=0
            GBR(NBR,1)=G1
            GBR(NBR,2)=G2
            IF (NBR.GE.MBR) CALL RPERR(8)
            CALL RPRAY(KRAYD,LRAY,ITYPE,ISH,G1,G2,G11,G12,G22,
     *                 X1,X2,G1X1,G2X1,G1X2,G2X2)
            IF (.NOT.LRAY) CALL RPERR(1)
            NBR=NBR+1
            KBR(NBR,1)=KRAYD
            KBR(NBR,2)=0
            KBR(NBR,3)=0
            GBR(NBR,1)=G1
            GBR(NBR,2)=G2
            IF (NBR.GE.MBR) CALL RPERR(8)
            NBR=NBR+1
            KBR(NBR,1)=0
            KBR(NBR,2)=0
            KBR(NBR,3)=0
            GBR(NBR,1)=0
            GBR(NBR,2)=0
            J1=NBR
C           The side C,D were turned.
C           Now the sequence of the rays is as follows: C,B,A,D
            IF (KRAYB.NE.KRAYC) THEN
              IF (NBR.GE.MBR) CALL RPERR(8)
              NBR=NBR+1
              KBR(NBR,1)=KRAYB
              KBR(NBR,2)=ISHB
              KBR(NBR,3)=ITYPEB
              GBR(NBR,1)=G1B
              GBR(NBR,2)=G2B
              KBR(J1,1)=KBR(J1,1)+1
            ENDIF
            IF (KRAYA.NE.KRAYD) THEN
              IF (NBR.GE.MBR) CALL RPERR(8)
              NBR=NBR+1
              KBR(NBR,1)=KRAYA
              KBR(NBR,2)=ISHA
              KBR(NBR,3)=ITYPEA
              GBR(NBR,1)=G1A
              GBR(NBR,2)=G2A
              KBR(J1,1)=KBR(J1,1)+1
            ENDIF
          ENDIF
C         End IF (LSTORE)
C         Correcting polygon:
  42      CONTINUE
          IF (KRAYA.NE.KPOL(I1-1,1)) THEN
            IF (NPOL.GE.MPOL) CALL RPERR(5)
            DO 44, I2=NPOL,I1,-1
              KPOL(I2+1,1)=KPOL(I2,1)
              KPOL(I2+1,2)=KPOL(I2,2)
              KPOL(I2+1,3)=KPOL(I2,3)
              KPOL(I2+1,4)=KPOL(I2,4)
              GPOL(I2+1,1)=GPOL(I2,1)
              GPOL(I2+1,2)=GPOL(I2,2)
  44        CONTINUE
            KPOL(I1,1)=KRAYA
            KPOL(I1,2)=ISHA
            KPOL(I1,3)=ITYPEA
            KPOL(I1,4)=ISHB
            GPOL(I1,1)=G1A
            GPOL(I1,2)=G2A
            NPOL=NPOL+1
            I1=I1+1
          ELSE
            KPOL(I1-1,3)=ITYPEA
          ENDIF
          IF (KRAYB.NE.KPOL(I1,1)) THEN
            IF (NPOL.GE.MPOL) CALL RPERR(5)
            DO 46, I2=NPOL,I1,-1
              KPOL(I2+1,1)=KPOL(I2,1)
              KPOL(I2+1,2)=KPOL(I2,2)
              KPOL(I2+1,3)=KPOL(I2,3)
              KPOL(I2+1,4)=KPOL(I2,4)
              GPOL(I2+1,1)=GPOL(I2,1)
              GPOL(I2+1,2)=GPOL(I2,2)
  46        CONTINUE
            KPOL(I1,1)=KRAYB
            KPOL(I1,2)=ISHB
            KPOL(I1,3)=ITYPEB
            KPOL(I1,4)=ISHA
            GPOL(I1,1)=G1B
            GPOL(I1,2)=G2B
            NPOL=NPOL+1
            I1=I1+1
          ELSE
            KPOL(I1,3)=ITYPEB
          ENDIF
C         Storing ray B to KLINE:
          IF (NLINE.GE.MLINE) CALL RPERR(7)
          NLINE=NLINE+1
          KLINE(NLINE,1)=KRAYB
          KLINE(NLINE,2)=ISHB
          KLINE(NLINE,3)=ITYPEB
          KLINE(NLINE,4)=ISHA
C         Searching for new rays A and B in KLINE:
          DO 48, I2=NLINE,2,-1
            IF (KLINE(I2,2).NE.KLINE(I2-1,2)) THEN
              KRAYA=KLINE(I2,1)
              KRAYB=KLINE(I2-1,1)
              NLINE=I2-2
              CALL RPRAY(KRAYA,LRAY,ITYPEA,ISHA,G1A,G2A,
     *                   G11A,G12A,G22A,X1,X2,G1X1A,G2X1A,G1X2A,G2X2A)
              IF (.NOT.LRAY) CALL RPERR(1)
              CALL RPRAY(KRAYB,LRAY,ITYPEB,ISHB,G1B,G2B,
     *                   G11B,G12B,G22B,X1,X2,G1X1B,G2X1B,G1X2B,G2X2B)
              IF (.NOT.LRAY) CALL RPERR(1)
              GOTO 40
            ENDIF
  48      CONTINUE
C         No other rays in KLINE:
          NLINE=0
          IF (KTRID(5).NE.0) THEN
            CALL RPTRI3(KTRID(5),LTRI,KTRIS)
            IF (.NOT.LTRI) GOTO 50
          ELSE
            KTRIS(1)=KTRID(1)
            KTRIS(2)=KTRID(2)
            KTRIS(3)=KTRID(3)
          ENDIF
          IF (((KRAYA0.EQ.KTRIS(1)).AND.(KRAYB0.EQ.KTRIS(2))).OR.
     *        ((KRAYA0.EQ.KTRIS(2)).AND.(KRAYB0.EQ.KTRIS(3))).OR.
     *        ((KRAYA0.EQ.KTRIS(3)).AND.(KRAYB0.EQ.KTRIS(1)))) THEN
C           Saving found boundary rays:
            IF (NBR.GE.MBR) CALL RPERR(8)
            NBR=NBR+1
            CALL RPRAY(KRAYB0,LRAY,ITYPE,ISH,G1,G2,G11,G12,G22,
     *                 X1,X2,G1X1,G2X1,G1X2,G2X2)
            IF (.NOT.LRAY) CALL RPERR(1)
            KBR(NBR,1)=KRAYB0
            KBR(NBR,2)=0
            KBR(NBR,3)=0
            GBR(NBR,1)=G1
            GBR(NBR,2)=G2
            IF (NBR.GE.MBR) CALL RPERR(8)
            NBR=NBR+1
            CALL RPRAY(KRAYA0,LRAY,ITYPE,ISH,G1,G2,G11,G12,G22,
     *                 X1,X2,G1X1,G2X1,G1X2,G2X2)
            IF (.NOT.LRAY) CALL RPERR(1)
            KBR(NBR,1)=KRAYA0
            KBR(NBR,2)=0
            KBR(NBR,3)=0
            GBR(NBR,1)=G1
            GBR(NBR,2)=G2
            IF (NBR.GE.MBR) CALL RPERR(8)
            NBR=NBR+1
            KBR(NBR,1)=0
            KBR(NBR,2)=0
            KBR(NBR,3)=0
            GBR(NBR,1)=0
            GBR(NBR,2)=0
            J1=NBR
            I2=I1-1
  49        IF (KPOL(I2,1).NE.KRAYA0) THEN
              IF (NBR.GE.MBR) CALL RPERR(8)
              NBR=NBR+1
              KBR(NBR,1)=KPOL(I2,1)
              KBR(NBR,2)=KPOL(I2,2)
              KBR(NBR,3)=KPOL(I2,3)
              GBR(NBR,1)=GPOL(I2,1)
              GBR(NBR,2)=GPOL(I2,2)
              KBR(J1,1)=KBR(J1,1)+1
              I2=I2-1
              GOTO 49
            ENDIF
          ENDIF
        ENDIF
  50  CONTINUE
      I1=I1+1
      IF (I1.LE.NPOL) GOTO 20
C
C     Shifting the polygon in such a way, that the first and the last
C     rays of the polygon are boundary rays:
      IF (KPOL(1,2).EQ.KPOL(NPOL,2)) THEN
C       Inhomogeneous polygon will be shifted now:
        I2=0
  55    CONTINUE
        I2=I2+1
        IF (NPOL.GE.MPOL) CALL RPERR(5)
        DO 52, I1=NPOL+1,2,-1
          KPOL(I1,1)=KPOL(I1-1,1)
          KPOL(I1,2)=KPOL(I1-1,2)
          KPOL(I1,3)=KPOL(I1-1,3)
          KPOL(I1,4)=KPOL(I1-1,4)
          GPOL(I1,1)=GPOL(I1-1,1)
          GPOL(I1,2)=GPOL(I1-1,2)
  52    CONTINUE
        KPOL(1,1)=KPOL(NPOL+1,1)
        KPOL(1,2)=KPOL(NPOL+1,2)
        KPOL(1,3)=KPOL(NPOL+1,3)
        KPOL(1,4)=KPOL(NPOL+1,4)
        GPOL(1,1)=GPOL(NPOL+1,1)
        GPOL(1,2)=GPOL(NPOL+1,2)
        IF ((KPOL(1,2).EQ.KPOL(NPOL,2)).AND.(I2.LT.NPOL)) GOTO 55
      ELSE
        IF ((KPOL(1,3).EQ.KPOL(NPOL,1)).OR.
     *      (KPOL(1,1).EQ.KPOL(NPOL,3))) THEN
C         Boundary rays, no action.
        ELSE
C         Inhomogeneous polygon will be shifted and then checked.
          IF (NPOL.GE.MPOL) CALL RPERR(5)
          KPOL(NPOL+1,1)=KPOL(1,1)
          KPOL(NPOL+1,2)=KPOL(1,2)
          KPOL(NPOL+1,3)=KPOL(1,3)
          KPOL(NPOL+1,4)=KPOL(1,4)
          GPOL(NPOL+1,1)=GPOL(1,1)
          GPOL(NPOL+1,2)=GPOL(1,2)
          DO 58, I1=1,NPOL
            KPOL(I1,1)=KPOL(I1+1,1)
            KPOL(I1,2)=KPOL(I1+1,2)
            KPOL(I1,3)=KPOL(I1+1,3)
            KPOL(I1,4)=KPOL(I1+1,4)
            GPOL(I1,1)=GPOL(I1+1,1)
            GPOL(I1,2)=GPOL(I1+1,2)
  58      CONTINUE
          GOTO 15
        ENDIF
      ENDIF
C
C
C     The inhomogeneous polygon is created.
C     Homogeneous polygons will be found and separated from it now.
C     Firstly preferring basic homogeneous polygons with rays of such
C     ISH, that other rays have not:
  60  CONTINUE
      I4=ISTART
      LSTORE=.FALSE.
      DO 64, I1=1,NPOL
        IF (KPOL(I1,1).GE.1) THEN
          J1=I1
          ISHP=KPOL(I1,2)
          GOTO 65
        ENDIF
  64  CONTINUE
  65  CONTINUE
      DO 66, I1=J1+1,NPOL
        IF (KPOL(I1,2).NE.ISHP) THEN
          J2=I1-1
          GOTO 67
        ENDIF
  66  CONTINUE
      J2=NPOL
  67  CONTINUE
      DO 70, I1=J2+1,NPOL
        IF (KPOL(I1,2).EQ.ISHP) THEN
          GOTO 701
        ENDIF
  70  CONTINUE
C     Rays J1 and J2 should not be marked as boundary rays:
      IF ((KPOL(J1,1).EQ.KPOL(J2,3)).OR.(KPOL(J1,3).EQ.KPOL(J2,1)))
     *  GOTO 701
C     Neighbouring rays ought to have the same ISH:
      IF (J1.EQ.1) THEN
        J3=NPOL
      ELSE
        J3=J1-1
      ENDIF
      IF (J2.EQ.NPOL) THEN
        J4=1
      ELSE
        J4=J2+1
      ENDIF
      IF (KPOL(J3,2).NE.KPOL(J4,2)) THEN
        GOTO 701
      ENDIF
      IF (I4.GT.0) THEN
C       In case ISTART .gt. 0 starting from other rays.
        I4=I4-1
        GOTO 701
      ENDIF
      GOTO 100
  701 CONTINUE
C
C     These rays are not very suitable to create
C     the homogeneous polygon:
      DO 69, I2=NPOL,1,-1
        IF ((KPOL(I2,1).GE.1).AND.(KPOL(I2,2).NE.ISHP)) THEN
C         Start from other rays:
          DO 68, I3=1,NPOL
            IF (KPOL(I3,2).EQ.ISHP) KPOL(I3,1)=-IABS(KPOL(I3,1))
  68      CONTINUE
          GOTO 60
        ENDIF
  69  CONTINUE
C     No other rays with such ISH, that other rays have not.
C     Now preferring basic homogeneous polygons with the higher
C     number of rays:
      DO 72, I2=1,NPOL
        KPOL(I2,1)=IABS(KPOL(I2,1))
  72  CONTINUE
  73  CONTINUE
      MAXR=0
      J2=0
  81  CONTINUE
      DO 82, I1=J2+1,NPOL
        IF (KPOL(I1,1).GE.1) THEN
          J1=I1
          GOTO 83
        ENDIF
  82  CONTINUE
C     All the groups were counted:
      GOTO 86
  83  CONTINUE
      DO 84, I1=J1+1,NPOL
        IF (KPOL(I1,2).NE.KPOL(J1,2)) THEN
          J2=I1-1
          GOTO 85
        ENDIF
  84  CONTINUE
      J2=NPOL
  85  CONTINUE
      I3=J2-J1+1
C     Rays J1 and J2 should not be marked as boundary rays:
      IF ((KPOL(J1,1).EQ.KPOL(J2,3)).OR.(KPOL(J1,3).EQ.KPOL(J2,1)))
     *  GOTO 81
      IF (I3.GT.MAXR) MAXR=I3
      GOTO 81
C
C     All the groups were counted:
  86  CONTINUE
      IF (MAXR.EQ.0) THEN
C       The best group is not chosen, trying groups consequently:
        J5=J5+1
        J2=0
        I4=J5
  900   CONTINUE
        I4=I4-1
        IF (J2.GE.NPOL) THEN
C         The inhomogeneous polygon will be simply divided into
C         homogeneous triangles:
          I1=1
  901     CONTINUE
            IF(I1.GT.1) THEN
              J1=I1-1
            ELSE
              J1=NPOL
            ENDIF
            IF(I1.LT.NPOL) THEN
              J2=I1+1
            ELSE
              J2=1
            ENDIF
            IF ((KPOL(J1,2).EQ.KPOL(I1,2)).AND.
     *          (KPOL(J2,2).EQ.KPOL(I1,2))) THEN
              IF (RPLRIT(.FALSE.,GPOL(J1,1),GPOL(J1,2),GPOL(I1,1),
     *            GPOL(I1,2),GPOL(J2,1),GPOL(J2,2),G1A,G2A,AREA)) THEN
                ITRI=ITRI+1
                KTRIN(1)=IABS(KPOL(J1,1))
                KTRIN(2)=IABS(KPOL(I1,1))
                KTRIN(3)=IABS(KPOL(J2,1))
                KTRIN(4)=ITRI
                IF (KTRID(5).EQ.0) THEN
                  KTRIN(5)=KTRID(4)
                ELSE
                  KTRIN(5)=KTRID(5)
                ENDIF
                KTRIN(6)=3
                CALL RPTRI1(ITRI,KTRIN)
                CALL RPSTOR('T',1,KTRIN)
                NPOL=NPOL-1
                DO 902, I2=I1,NPOL
                  KPOL(I1,1)=KPOL(I1+1,1)
                  KPOL(I1,2)=KPOL(I1+1,2)
                  KPOL(I1,3)=KPOL(I1+1,3)
                  KPOL(I1,4)=KPOL(I1+1,4)
                  GPOL(I1,1)=GPOL(I1+1,1)
                  GPOL(I1,2)=GPOL(I1+1,2)
  902           CONTINUE
                I1=1
                GOTO 901
              ENDIF
            ENDIF
          I1=I1+1
          IF (I1.LE.NPOL) GOTO 901
          KTRID(6)=2
          CALL RPTRI2(KTRID(4),LTRI,KTRID)
          IF (.NOT.LTRI) CALL RPERR(2)
          LNEWAR=.FALSE.
          RETURN
        ENDIF
        J1=J2+1
        ISHP=KPOL(J1,2)
        DO 903, I1=J1+1,NPOL
          IF (KPOL(I1,2).NE.ISHP) THEN
            J2=I1-1
            GOTO 904
          ENDIF
  903   CONTINUE
        J2=NPOL
  904   CONTINUE
        IF (I4.GT.0) GOTO 900
        GOTO 100
      ENDIF
C     MAXR .gt. 0, the first group with this number of rays will become
C     to be the basic homogeneous polygon:
      J2=0
  91  CONTINUE
      DO 92, I1=J2+1,NPOL
        IF (KPOL(I1,1).GE.1) THEN
          J1=I1
          GOTO 93
        ENDIF
  92  CONTINUE
  93  CONTINUE
      DO 94, I1=J1+1,NPOL
        IF (KPOL(I1,2).NE.KPOL(J1,2)) THEN
          J2=I1-1
          GOTO 95
        ENDIF
  94  CONTINUE
      J2=NPOL
  95  CONTINUE
      I3=J2-J1+1
      IF (I3.NE.MAXR) GOTO 91
      ISHP=KPOL(J1,2)
      IF (I4.GT.0) THEN
C       In case ISTART .gt. 0 starting from other rays.
        I4=I4-1
        DO 96, I1=J1,J2
          KPOL(I1,1)=-IABS(KPOL(I1,1))
  96    CONTINUE
        GOTO 73
      ENDIF
C
C     The group with ISH=ISHP of rays in KPOL from J1 to J2 becomes
C     to be the basic homogeneous polygon:
  100 CONTINUE
      DO 101, I1=1,NPOL
        KPOL(I1,1)=IABS(KPOL(I1,1))
  101 CONTINUE
      NPOLH=J2-J1+1
      IF (NPOLH.GT.MPOLH) CALL RPERR(6)
      DO 102, I1=J1,J2
        KPOLH(I1-J1+1,1)=KPOL(I1,1)
        KPOLH(I1-J1+1,2)=KPOL(I1,2)
        KPOLH(I1-J1+1,3)=KPOL(I1,3)
        KPOLH(I1-J1+1,4)=KPOL(I1,4)
        GPOLH(I1-J1+1,1)=GPOL(I1,1)
        GPOLH(I1-J1+1,2)=GPOL(I1,2)
  102 CONTINUE
C
C
C     The basic homogeneous polygon is formed,
C     now demarcating the boundary:
C
      IF (NPOLH.EQ.1) THEN
C       In this situation a very small part of the domain
C       will escape notice.
        NPOLH=0
        DO 104, I1=1,NPOL
          IF (KPOL(I1,1).EQ.KPOLH(1,1)) THEN
            IF ((I1.GT.1).AND.(I1.LT.NPOL)) THEN
              KPOL(I1-1,3)=KPOL(I1+1,1)
            ELSEIF (I1.EQ.1) THEN
              KPOL(NPOL,3)=KPOL(2,1)
            ELSE
              KPOL(NPOL-1,3)=KPOL(1,1)
            ENDIF
            NPOL=NPOL-1
            DO 103, I2=I1,NPOL
              KPOL(I2,1)=KPOL(I2+1,1)
              KPOL(I2,2)=KPOL(I2+1,2)
              KPOL(I2,3)=KPOL(I2+1,3)
              KPOL(I2,4)=KPOL(I2+1,4)
              GPOL(I2,1)=GPOL(I2+1,1)
              GPOL(I2,2)=GPOL(I2+1,2)
  103       CONTINUE
            GOTO 105
          ENDIF
  104   CONTINUE
  105   CONTINUE
        IF (NPOL.GE.2) THEN
          GOTO 15
        ELSE
          KTRID(6)=2
          CALL RPTRI2(KTRID(4),LTRI,KTRID)
          IF (.NOT.LTRI) CALL RPERR(2)
          LNEWAR=.FALSE.
          RETURN
        ENDIF
      ENDIF
C
      IF (NPOLH.EQ.NPOL) THEN
C       Whole polygon is homogeneous, it is prepared to be divided
C       into triangles now. (New boundary need not be traced).
        NPOL=0
        GOTO 155
      ENDIF
C
C     NPOLH is greater or equal 2:
C
      KLINE(1,1)=KPOLH(1,1)
      KLINE(1,2)=KPOLH(1,2)
      KLINE(1,3)=KPOLH(1,3)
      KLINE(1,4)=KPOLH(1,4)
      KLINE(2,1)=KPOLH(NPOLH,1)
      KLINE(2,2)=KPOLH(NPOLH,2)
      KLINE(2,3)=KPOLH(NPOLH,3)
      KLINE(2,4)=KPOLH(NPOLH,4)
      NLINE=2
      J3=1
      J30=1
C
C     Entry point when boundary rays were found and
C     added to KLINE:
  107 CONTINUE
      IF (J3.GE.J30) THEN
        DO 108, I1=J3,NLINE-1
          IF ((KLINE(I1,4).NE.0).AND.(KLINE(I1+1,4).NE.0)) THEN
            IF (KLINE(I1,4).NE.KLINE(I1+1,4)) THEN
              IF (J30.EQ.0) J30=J3
              J3=I1
              GOTO 111
            ENDIF
          ENDIF
  108   CONTINUE
        J3=J30
        J30=999999
      ENDIF
  111 KRAYA=IABS(KLINE(J3,1))
      KRAYB=IABS(KLINE(J3+1,1))
      CALL RPRAY(KRAYA,LRAY,ITYPEA,ISHA,G1A,G2A,
     *          G11A,G12A,G22A,X1,X2,G1X1A,G2X1A,G1X2A,G2X2A)
      IF (.NOT.LRAY) CALL RPERR(1)
      CALL RPRAY(KRAYB,LRAY,ITYPEB,ISHB,G1B,G2B,
     *          G11B,G12B,G22B,X1,X2,G1X1B,G2X1B,G1X2B,G2X2B)
      IF (.NOT.LRAY) CALL RPERR(1)
      G11POM=(G11A+G11B)/2.
      G12POM=(G12A+G12B)/2.
      G22POM=(G22A+G22B)/2.
      DIST2=RPDI2G(G1A,G2A,G1B,G2B,G11POM,G12POM,G22POM)
      IF (DIST2.LT.AERR2) THEN
C       Rays are too close, boundary is not to be demarcated:
        J3=J3+1
        IF (J3.NE.NLINE) THEN
          GOTO 107
        ELSE
          IF (J30.NE.999999) THEN
            J3=J30
            J30=999999
            GOTO 107
          ENDIF
          GOTO 143
        ENDIF
      ENDIF
      G1NEW=(G1A+G1B)/2.
      G2NEW=(G2A+G2B)/2.
      IF (((G1NEW.EQ.G1A).AND.(G2NEW.EQ.G2A)).OR.
     *    ((G1NEW.EQ.G1B).AND.(G2NEW.EQ.G2B))) CALL RPERR(3)
      IF (.NOT.RPLRIP(NPOL,GPOL,G1NEW,G2NEW)) THEN
C       Ray C will be replaced by intersection point of
C       the abscissa perpendicular to abscissa AB with
C       the abscissae of the polygon. The point nearest to the point C
C       is preferred:
C       Looking for the intersection point of abscissa DE
C       with the abscissae of the polygon:
C       ..J,..K ... The rays of tested polygon abscissa.
C       ..D,..E ... The rays of intersecting abscissa.
C       ..X ... The intersection point.
        G1C=G1NEW
        G2C=G2NEW
C
C       Computing the parameters of points D and E:
        AAA=(G11POM*(G1A-G1B)+G12POM*(G2A-G2B))
        BBB=(G12POM*(G1A-G1B)+G22POM*(G2A-G2B))
        DETG=G11POM*G22POM - G12POM*G12POM
        IF (DETG.LT.ZERO) CALL RPERR(4)
        DIST2=(G1A-G1B)*AAA + (G2A-G2B)*BBB
        G1D=(G1A+G1B)/2. + SIDE/SQRT(DIST2)*SQRT(3./DETG)*BBB
        G2D=(G2A+G2B)/2. - SIDE/SQRT(DIST2)*SQRT(3./DETG)*AAA
        G1E=(G1A+G1B)/2. - SIDE/SQRT(DIST2)*SQRT(3./DETG)*BBB
        G2E=(G2A+G2B)/2. + SIDE/SQRT(DIST2)*SQRT(3./DETG)*AAA
C
C       Searching for intersection point nearest to the point C:
        MINDIS=999999.
        G1J=GPOL(NPOL,1)
        G2J=GPOL(NPOL,2)
        G1K=GPOL(1,1)
        G2K=GPOL(1,2)
        I1=0
  109   CONTINUE
          CALL RPCROS(G1D,G2D,G1E,G2E,G1J,G2J,G1K,G2K,LINTS,G1X,G2X)
          IF (LINTS) THEN
            DIST2=RPDI2G(G1X,G2X,G1C,G2C,G11POM,G12POM,G22POM)
            IF (DIST2.LT.MINDIS) THEN
              MINDIS=DIST2
              G1NEW=G1X
              G2NEW=G2X
            ENDIF
          ENDIF
          I1=I1+1
          IF ((KPOL(I1,1).EQ.IABS(KLINE(J3,1))).AND.
     *        (KPOL(I1+1,1).EQ.IABS(KLINE(J3+1,1)))) I1=I1+1
          IF (I1.LT.NPOL) THEN
            G1J=GPOL(I1,1)
            G2J=GPOL(I1,2)
            G1K=GPOL(I1+1,1)
            G2K=GPOL(I1+1,2)
            GOTO 109
          ENDIF
C       End of the loop.
        IF (MINDIS.EQ.999999.) THEN
C         RP3D-009
          CALL ERROR('RP3D-009: Intersection not found in RPDIV.')
C         This error should not appear.
C         Please contact the author or try to
C         change the input data.
        ENDIF
      ENDIF
C     Trace a new ray, then go to 110:
      KRAYC=IRAY+1
      IGOTO=2
      LNEWAR=.TRUE.
      RETURN
C
C
C     Ray C=(A+B)/2. was actually traced.
  110 CONTINUE
      CALL RPRAY(KRAYC,LRAY,ITYPEC,ISHC,G1C,G2C,G11C,G12C,G22C,X1,X2,
     *           G1X1,G2X1,G1X2,G2X2)
      IF (.NOT.LRAY) CALL RPERR(1)
      IF (ISHC.NE.ISHA) THEN
        I1=NPOL
        I2=1
  112   CONTINUE
          IF (RPLRIL(G1C,G2C,GPOL(I1,1),GPOL(I1,2),
     *               GPOL(I2,1),GPOL(I2,2))) THEN
            IF ((KPOL(I1,2).NE.ISHC).AND.(KPOL(I2,2).NE.ISHC)) THEN
C             Ray C is between the rays of different history:
              IF ((KPOL(I1,3).NE.KPOL(I2,1)).AND.
     *            (KPOL(I1,1).NE.KPOL(I2,3))) THEN
C               New ray is not between the rays signed as boundary rays.
                CALL RPRAY(KPOL(I1,1),LRAY,ITYPE,ISH,G1,G2,G11,G12,G22,
     *                     X1,X2,G1X1,G2X1,G1X2,G2X2)
                IF (.NOT.LRAY) CALL RPERR(1)
                CALL RPRAY(KPOL(I2,1),LRAY,ITYPEX,ISHX,G1X,G2X,G11X,G12X
     *                    ,G22X,X1,X2,G1X1,G2X1,G1X2,G2X2)
                IF (.NOT.LRAY) CALL RPERR(1)
                G11POM=(G11X+G11)/2.
                G12POM=(G12X+G12)/2.
                G22POM=(G22X+G22)/2.
                DIST2=RPDI2G(GPOL(I1,1),GPOL(I1,2),GPOL(I2,1),GPOL(I2,2)
     *                      ,G11POM,G12POM,G22POM)
                IF (DIST2.GT.AERR2) THEN
C                 New ray is between the rays which are not
C                 as near as boundary rays.
C                 Ray C is to be added to the polygon:
                  IF (NPOL.GE.MPOL) CALL RPERR(5)
                  NPOL=NPOL+1
                  DO 114, I3=NPOL,I2+1,-1
                    KPOL(I3,1)=KPOL(I3-1,1)
                    KPOL(I3,2)=KPOL(I3-1,2)
                    KPOL(I3,3)=KPOL(I3-1,3)
                    KPOL(I3,4)=KPOL(I3-1,4)
                    GPOL(I3,1)=GPOL(I3-1,1)
                    GPOL(I3,2)=GPOL(I3-1,2)
  114             CONTINUE
                  KPOL(I2,1)=KRAYC
                  KPOL(I2,2)=ISHC
                  KPOL(I2,3)=ITYPEC
                  KPOL(I2,4)=0
                  IF (ITYPEC.GT.0) THEN
                    CALL RPRAY(ITYPEC,LRAY,ITYPE,ISH,G1,G2,
     *                         G11,G12,G22,X1,X2,G1X1,G2X1,G1X2,G2X2)
                    IF (LRAY) THEN
                      KPOL(I2,4)=ISH
                    ENDIF
                  ENDIF
                  GPOL(I2,1)=G1C
                  GPOL(I2,2)=G2C
C                 When the ray C is on the sides of the basic triangle
C                 which contains the divided triangle, storing it to
C                 the array KBR:
                  IF (KTRID(5).NE.0) THEN
                    CALL RPTRI3(KTRID(5),LTRI,KTRIS)
                    IF (.NOT.LTRI) CALL RPERR(2)
                  ELSE
                    KTRIS(1)=KTRID(1)
                    KTRIS(2)=KTRID(2)
                    KTRIS(3)=KTRID(3)
                  ENDIF
                  CALL RPRAY(KTRIS(1),LRAY,ITYPE,ISH,G1I,G2I,G11,G12,G22
     *                       ,X1,X2,G1X1,G2X1,G1X2,G2X2)
                  IF (.NOT.LRAY) CALL RPERR(1)
                  CALL RPRAY(KTRIS(2),LRAY,ITYPE,ISH,G1J,G2J,G11,G12,G22
     *                       ,X1,X2,G1X1,G2X1,G1X2,G2X2)
                  IF (.NOT.LRAY) CALL RPERR(1)
                  CALL RPRAY(KTRIS(3),LRAY,ITYPE,ISH,G1K,G2K,G11,G12,G22
     *                       ,X1,X2,G1X1,G2X1,G1X2,G2X2)
                  IF (.NOT.LRAY) CALL RPERR(1)
                  KRAYI=0
                  IF (RPLRIL(G1C,G2C,G1K,G2K,G1I,G2I)) THEN
C                   Boundary rays are lying on the side IK (side 3,1):
                    KRAYI=KTRIS(1)
                    KRAYJ=KTRIS(3)
                  ELSEIF (RPLRIL(G1C,G2C,G1I,G2I,G1J,G2J)) THEN
C                   Boundary rays are lying on the side IJ (side 1,2):
                    KRAYI=KTRIS(2)
                    KRAYJ=KTRIS(1)
                  ELSEIF (RPLRIL(G1C,G2C,G1J,G2J,G1K,G2K)) THEN
C                   Boundary rays are lying on the side JK (side 2,3):
                    KRAYI=KTRIS(3)
                    KRAYJ=KTRIS(2)
                  ENDIF
                  IF (KRAYI.NE.0) CALL RPKBR(KRAYI,KRAYJ,KRAYC)
C                 Noting that new boundary rays are to be stored:
                  KRAYD0=KRAYC
                  LSTORE=.TRUE.
                  ISTART=0
                  NPOLH=0
                  NLINE=0
                  GOTO 15
                ENDIF
              ENDIF
            ENDIF
C           Ray C is on the polygon, but it is not to be added to it.
            GOTO 116
          ENDIF
          I1=I2
          I2=I2+1
        IF (I2.LE.NPOL) GOTO 112
      ENDIF
  116 CONTINUE
C     Entry point when ray C=(A+B)/2. was chosen from the polygon
C     (or was traced and lies on the polygon).
C     Proposing of ray parameters G1NEW,G2NEW of a new ray D:
      G11POM=(G11A+G11B+G11C)/3.
      G12POM=(G12A+G12B+G12C)/3.
      G22POM=(G22A+G22B+G22C)/3.
      DETG=G11POM*G22POM - G12POM*G12POM
      IF (DETG.LT.ZERO) CALL RPERR(4)
      DIST2=RPDI2G(G1A,G2A,G1B,G2B,G11POM,G12POM,G22POM)
      IF (ISHC.EQ.ISHA) THEN
        DG1=G1A-G1B
        DG2=G2A-G2B
      ELSE
        DG1=G1B-G1A
        DG2=G2B-G2A
      ENDIF
      AAA=G11POM*DG1+G12POM*DG2
      BBB=G12POM*DG1+G22POM*DG2
C     DGIN constructed so that vector C-N is normalized to one:
      SQ=SQRT(1./(DETG*DIST2))
      DG1N= SQ*BBB
      DG2N=-SQ*AAA
C     Choosing the length of the vector C-N:
      DG1N=DG1N*(PAR*SQRT(DIST2))
      DG2N=DG2N*(PAR*SQRT(DIST2))
      IF (ABS(DG1N).LT.ZERO) THEN
        IF (DG1N.LT.0.) THEN
          DG1N=-ZERO
        ELSE
          DG1N=ZERO
        ENDIF
      ENDIF
      IF (ABS(DG2N).LT.ZERO) THEN
        IF (DG2N.LT.0.) THEN
          DG2N=-ZERO
        ELSE
          DG2N=ZERO
        ENDIF
      ENDIF
      G1NEW=G1C + DG1N
      G2NEW=G2C + DG2N
      INEWR=1
      MINDIS=0.
      IF (.NOT.(RPLRIP(NPOL,GPOL,G1NEW,G2NEW))) THEN
C       New ray D proposed out of the polygon will be replaced by
C       the intersection point.
C       Looking for the intersection point of abscissa KRAYC,KRAYD
C       with the abscissae of the polygon:
C       ..J,..K ... The rays of tested polygon abscissa.
C       ..C,..D ... The rays of intersecting abscissa.
C       ..X ... The intersection point.
        MINDIS=999999.
        G1J=GPOL(NPOL,1)
        G2J=GPOL(NPOL,2)
        G1K=GPOL(1,1)
        G2K=GPOL(1,2)
        G1D=G1NEW
        G2D=G2NEW
        I1=0
  117   CONTINUE
        CALL RPCROS(G1C,G2C,G1D,G2D,G1J,G2J,G1K,G2K,LINTS,G1X,G2X)
        IF (LINTS) THEN
          DIST2=RPDI2G(G1X,G2X,G1C,G2C,G11POM,G12POM,G22POM)
          IF ((DIST2.LT.MINDIS).AND.(DIST2.GT.ZERO1)) THEN
            J4=I1
            MINDIS=DIST2
            G1NEW=G1X
            G2NEW=G2X
          ENDIF
        ENDIF
        I1=I1+1
        IF ((KPOL(I1,1).EQ.IABS(KLINE(J3,1))).AND.
     *      (KPOL(I1+1,1).EQ.IABS(KLINE(J3+1,1)))) I1=I1+1
        IF (I1.LT.NPOL) THEN
          G1J=GPOL(I1,1)
          G2J=GPOL(I1,2)
          G1K=GPOL(I1+1,1)
          G2K=GPOL(I1+1,2)
          GOTO 117
        ENDIF
        INEWR=-1
      ENDIF
      IF (MINDIS.EQ.999999.) THEN
        ISTART=ISTART+1
        INEWR=0
        NPOLH=0
        NLINE=0
        GOTO 60
      ENDIF
C     Trace a new ray, then go to 120:
      KRAYE=KRAYC
      IGOTO=3
      LNEWAR=.TRUE.
      RETURN
C
C     New ray D was actually traced:
  120 CONTINUE
      KRAYD=IRAY
      CALL RPRAY(IRAY,LRAY,ITYPED,ISHD,G1D,G2D,G11D,G12D,G22D,X1,X2,
     *           G1X1,G2X1,G1X2,G2X2)
      IF (.NOT.LRAY) CALL RPERR(1)
      IF (ISHD.NE.ISHC) THEN
C       Ray D has another history than previous ray (C or D).
C       Halving the interval (on label 140):
        LDGEAE=.FALSE.
        IF ((ISHD.NE.ISHP).AND.(ISHC.NE.ISHP)) THEN
          ISTART=ISTART+1
          NPOLH=0
          NLINE=0
          GOTO 60
        ENDIF
        IF (ISHD.NE.ISHA) THEN
          KRAYA=KRAYE
          KRAYB=KRAYD
        ELSE
          KRAYA=KRAYD
          KRAYB=KRAYE
        ENDIF
        CALL RPRAY(KRAYA,LRAY,ITYPEA,ISHA,G1A,G2A,G11A,G12A,G22A,X1,X2,
     *             G1X1A,G2X1A,G1X2A,G2X2A)
        IF (.NOT.LRAY) CALL RPERR(1)
        CALL RPRAY(KRAYB,LRAY,ITYPEB,ISHB,G1B,G2B,G11B,G12B,G22B,X1,X2,
     *             G1X1B,G2X1B,G1X2B,G2X2B)
        IF (.NOT.LRAY) CALL RPERR(1)
        GOTO 140
      ELSEIF (INEWR.GT.0) THEN
C       Ray D has the same history than previous ray (C or D),
C       proposing the parameters of a new ray D:
        G1NEW=G1C + DG1N*(2.**(INEWR))
        G2NEW=G2C + DG2N*(2.**(INEWR))
        KRAYE=KRAYD
        INEWR=INEWR+1
        MINDIS=0.
        IF (.NOT.(RPLRIP(NPOL,GPOL,G1NEW,G2NEW))) THEN
C         New ray D proposed out of the polygon will be replaced by
C         the intersection point.
C         Looking for the intersection point of abscissa KRAYC,KRAYD
C         with the abscissae of the polygon:
C         ..J,..K ... The rays of tested polygon abscissa.
C         ..C,..D ... The rays of intersecting abscissa.
C         ..X ... The intersection point.
          MINDIS=999999.
          G1J=GPOL(NPOL,1)
          G2J=GPOL(NPOL,2)
          G1K=GPOL(1,1)
          G2K=GPOL(1,2)
          G1D=G1NEW
          G2D=G2NEW
          I1=0
  122     CONTINUE
          CALL RPCROS(G1C,G2C,G1D,G2D,G1J,G2J,G1K,G2K,LINTS,G1X,G2X)
          IF (LINTS) THEN
            DIST2=RPDI2G(G1X,G2X,G1C,G2C,G11POM,G12POM,G22POM)
            IF ((DIST2.LT.MINDIS).AND.(DIST2.GT.ZERO1)) THEN
              J4=I1
              MINDIS=DIST2
              G1NEW=G1X
              G2NEW=G2X
            ENDIF
          ENDIF
          I1=I1+1
          IF (I1.LT.NPOL) THEN
            G1J=GPOL(I1,1)
            G2J=GPOL(I1,2)
            G1K=GPOL(I1+1,1)
            G2K=GPOL(I1+1,2)
            GOTO 122
          ENDIF
          INEWR=-1
        ENDIF
        IF (MINDIS.EQ.999999.) THEN
          ISTART=ISTART+1
          INEWR=0
          NPOLH=0
          NLINE=0
          GOTO 60
        ENDIF
C       Trace a new ray, then go to 120:
        IGOTO=3
        LNEWAR=.TRUE.
        RETURN
      ELSE
C       Ray D is an intersection point and has the same history as a
C       previous ray (C or D). This ray will be placed to the polygon
C       and the polygon will be divided again.
C       The intersection appeared with J4-th abscissa of the polygon:
        IF (J4.EQ.0) THEN
          I1=NPOL
          I2=1
        ELSE
          I1=J4
          I2=J4+1
        ENDIF
        IF ((ISHD.EQ.KPOL(I1,2)).AND.(ISHD.EQ.KPOL(I2,2))) THEN
C         Ray D is between the rays of the same history:
          IF (.NOT.LDGEAE) THEN
C           Trying to find ray D once more, starting from the ray C
C           and going with the first step equal to AERR.
C           Hereinafter DETG is not the determinant:
            DETG=DG1N*G11C*DG1N + 2.*G12C*DG1N*DG2N + DG2N*G22C*DG2N
            DETG=SQRT(DETG)
            IF (DETG.LT.ZERO1) DETG=ZERO1
            DETG=SQRT(AERR2)/DETG
            DG1N=DG1N*DETG
            DG2N=DG2N*DETG
            G1NEW=G1C + DG1N
            G2NEW=G2C + DG2N
            IF (RPLRIP(NPOL,GPOL,G1NEW,G2NEW)) THEN
C             New ray must be in the inhomogeneous polygon:
              INEWR=1
C             Trace a new ray, then go to 120:
              KRAYE=KRAYC
              IGOTO=3
              LNEWAR=.TRUE.
              LDGEAE=.TRUE.
              RETURN
            ENDIF
          ENDIF
          ISTART=ISTART+1
          LDGEAE=.FALSE.
        ELSE
C         Ray D is between the rays of different history:
          IF ((KPOL(I1,3).EQ.KPOL(I2,1)).OR.(KPOL(I1,1).EQ.KPOL(I2,3)))
     *        THEN
C           New ray is between the rays signed as boundary rays,
C           this ray is not to be stored to KPOL:
            ISTART=ISTART+1
            NPOLH=0
            NLINE=0
            GOTO 60
          ENDIF
          CALL RPRAY(KPOL(I1,1),LRAY,ITYPE,ISH,G1,G2,G11,G12,G22,
     *               X1,X2,G1X1,G2X1,G1X2,G2X2)
          IF (.NOT.LRAY) CALL RPERR(1)
          CALL RPRAY(KPOL(I2,1),LRAY,ITYPEX,ISHX,G1X,G2X,G11X,G12X,
     *               G22X,X1,X2,G1X1,G2X1,G1X2,G2X2)
          IF (.NOT.LRAY) CALL RPERR(1)
          G11POM=(G11X+G11)/2.
          G12POM=(G12X+G12)/2.
          G22POM=(G22X+G22)/2.
          DIST2=RPDI2G(GPOL(I1,1),GPOL(I1,2),GPOL(I2,1),GPOL(I2,2),
     *                 G11POM,G12POM,G22POM)
          IF (DIST2.LT.AERR2) THEN
C           New ray is between the rays which are
C           as near as boundary rays,
C           this ray is not to be stored to KPOL:
            ISTART=ISTART+1
            NPOLH=0
            NLINE=0
            GOTO 60
          ENDIF
C         New ray D is to be added to the polygon:
          IF (NPOL.GE.MPOL) CALL RPERR(5)
          NPOL=NPOL+1
          DO 128, I4=NPOL,I2+1,-1
            KPOL(I4,1)=KPOL(I4-1,1)
            KPOL(I4,2)=KPOL(I4-1,2)
            KPOL(I4,3)=KPOL(I4-1,3)
            KPOL(I4,4)=KPOL(I4-1,4)
            GPOL(I4,1)=GPOL(I4-1,1)
            GPOL(I4,2)=GPOL(I4-1,2)
  128     CONTINUE
          KPOL(I2,1)=KRAYD
          KPOL(I2,2)=ISHD
          KPOL(I2,3)=ITYPED
          KPOL(I2,4)=0
          IF (ITYPED.GT.0) THEN
            CALL RPRAY(ITYPED,LRAY,ITYPE,ISH,G1,G2,
     *                 G11,G12,G22,X1,X2,G1X1,G2X1,G1X2,G2X2)
            IF (LRAY) THEN
              KPOL(I2,4)=ISH
            ENDIF
          ENDIF
          GPOL(I2,1)=G1D
          GPOL(I2,2)=G2D
C         When the ray D is on the sides of the basic triangle which
C         contains the divided triangle, storing it to the KBR:
          IF (KTRID(5).NE.0) THEN
            CALL RPTRI3(KTRID(5),LTRI,KTRIS)
            IF (.NOT.LTRI) CALL RPERR(2)
          ELSE
            KTRIS(1)=KTRID(1)
            KTRIS(2)=KTRID(2)
            KTRIS(3)=KTRID(3)
          ENDIF
          CALL RPRAY(KTRIS(1),LRAY,ITYPE,ISH,G1I,G2I,G11,G12,G22,
     *               X1,X2,G1X1,G2X1,G1X2,G2X2)
          IF (.NOT.LRAY) CALL RPERR(1)
          CALL RPRAY(KTRIS(2),LRAY,ITYPE,ISH,G1J,G2J,G11,G12,G22,
     *               X1,X2,G1X1,G2X1,G1X2,G2X2)
          IF (.NOT.LRAY) CALL RPERR(1)
          CALL RPRAY(KTRIS(3),LRAY,ITYPE,ISH,G1K,G2K,G11,G12,G22,
     *               X1,X2,G1X1,G2X1,G1X2,G2X2)
          IF (.NOT.LRAY) CALL RPERR(1)
          KRAYI=0
          IF (RPLRIL(G1D,G2D,G1K,G2K,G1I,G2I)) THEN
C           Boundary rays are lying on the side IK (side 3,1):
            KRAYI=KTRIS(1)
            KRAYJ=KTRIS(3)
          ELSEIF (RPLRIL(G1D,G2D,G1I,G2I,G1J,G2J)) THEN
C           Boundary rays are lying on the side IJ (side 1,2):
            KRAYI=KTRIS(2)
            KRAYJ=KTRIS(1)
          ELSEIF (RPLRIL(G1D,G2D,G1J,G2J,G1K,G2K)) THEN
C           Boundary rays are lying on the side JK (side 2,3):
            KRAYI=KTRIS(3)
            KRAYJ=KTRIS(2)
          ENDIF
          IF (KRAYI.NE.0) CALL RPKBR(KRAYI,KRAYJ,KRAYD)
C         Noting that new boundary rays are to be stored:
          KRAYD0=KRAYD
          LSTORE=.TRUE.
          ISTART=0
        ENDIF
        NPOLH=0
        NLINE=0
        GOTO 15
      ENDIF
C
C     Entry point when a new ray was traced during the
C     division of the interval formed by rays A and B.
C     (The interval is divided to demarcate the boundary.)
  130 CALL RPRAY(IRAY,LRAY,ITYPED,ISHD,G1D,G2D,G11D,G12D,G22D,X1,X2
     *          ,G1X1D,G2X1D,G1X2D,G2X2D)
      IF (.NOT.LRAY) CALL RPERR(1)
      KRAYD=IRAY
      IF (ISHD.EQ.ISHA) THEN
         KRAYA= KRAYD
        ITYPEA=ITYPED
           G1A=   G1D
           G2A=   G2D
          G11A=  G11D
          G12A=  G12D
          G22A=  G22D
         G1X1A= G1X1D
         G2X1A= G2X1D
         G1X2A= G1X2D
         G2X2A= G2X2D
      ELSE
         KRAYB= KRAYD
        ITYPEB=ITYPED
           G1B=   G1D
           G2B=   G2D
          G11B=  G11D
          G12B=  G12D
          G22B=  G22D
         G1X1B= G1X1D
         G2X1B= G2X1D
         G1X2B= G1X2D
         G2X2B= G2X2D
      ENDIF
C
  140 CONTINUE
C     Interval A,B is proposed, now deciding whether it must be divided:
C     (The interval is divided to demarcate the boundary.)
      G11POM=(G11A+G11B)/2.
      G12POM=(G12A+G12B)/2.
      G22POM=(G22A+G22B)/2.
      DIST2=RPDI2G(G1A,G2A,G1B,G2B,G11POM,G12POM,G22POM)
      IF (DIST2.LE.AERR2) THEN
        IF (PRM0(1).NE.0.) THEN
          IF ((ISHA.GT.0).OR.(ISHB.GT.0)) THEN
            CALL RPMEGS(ISHA,ISHB,G1X1A,G2X1A,G1X2A,G2X2A,
     *                            G1X1B,G2X1B,G1X2B,G2X2B,G11,G12,G22)
            DIST2=RPDI2G(G1A,G2A,G1B,G2B,G11,G12,G22)
            IF (DIST2.GT.1.) THEN
              DIST2=AERR2+1.
            ENDIF
          ENDIF
        ENDIF
      ENDIF
      IF ((DIST2.GT.AERR2).OR.(KRAYA.EQ.IABS(KLINE(J3,1))).OR.
     *                      (KRAYA.EQ.IABS(KLINE(J3+1,1)))) THEN
        IF ((ABS(G1B-G1A).GE.ZERO).OR.(ABS(G2B-G2A).GE.ZERO)) THEN
C         Trace a new ray, then go to 130:
          G1NEW=(G1A+G1B)/2.
          G2NEW=(G2A+G2B)/2.
          IF (((G1NEW.EQ.G1A).AND.(G2NEW.EQ.G2A)).OR.
     *        ((G1NEW.EQ.G1B).AND.(G2NEW.EQ.G2B))) CALL RPERR(3)
          IGOTO=4
          LNEWAR=.TRUE.
          RETURN
        ELSE
          J3=J3+1
          IF (J3+2.LE.NLINE) THEN
            GOTO 141
          ELSE
            GOTO 145
          ENDIF
        ENDIF
      ENDIF
C     Rays A and B are boundary rays:
      CALL RPRAY(KRAYA,LRAY,ITYPEA,ISHA,G1A,G2A,G11A,G12A,G22A,X1,X2
     *           ,G1X1,G2X1,G1X2,G2X2)
      IF (.NOT.LRAY) CALL RPERR(1)
      ITYPEA=KRAYB
      CALL RPMC1(KRAYA,ITYPEA)
      CALL RPSTOR('R',KRAYA,KTRIS)
      CALL RPRAY(KRAYB,LRAY,ITYPEB,ISHB,G1B,G2B,G11B,G12B,G22B,X1,X2
     *           ,G1X1,G2X1,G1X2,G2X2)
      IF (.NOT.LRAY) CALL RPERR(1)
      ITYPEB=KRAYA
      CALL RPMC1(KRAYB,ITYPEB)
      CALL RPSTOR('R',KRAYB,KTRIS)
C     Storing boundary rays to KLINE:
      IF (NLINE.GE.MLINE) CALL RPERR(7)
      NLINE=NLINE+1
      DO 142, I2=NLINE,J3+2,-1
        KLINE(I2,1)=KLINE(I2-1,1)
        KLINE(I2,2)=KLINE(I2-1,2)
        KLINE(I2,3)=KLINE(I2-1,3)
        KLINE(I2,4)=KLINE(I2-1,4)
  142 CONTINUE
      KLINE(J3+1,1)=KRAYA
      KLINE(J3+1,2)=ISHA
      KLINE(J3+1,3)=ITYPEA
      KLINE(J3+1,4)=ISHB
  141 CONTINUE
C     Deciding whether the side formed by rays J3,J3+1 of KLINE
C     is to be divided:
      IF (KLINE(J3,1).LT.0) THEN
        KLINE(J3,1)=IABS(KLINE(J3,1))
      ELSE
C       Criterion 1: (Distance of the ray J3+1 from the
C                     line connecting rays J3 and J3+2) .lt. (4*AERR)
        CALL RPRAY(IABS(KLINE(J3,1)),LRAY,ITYPEB,ISHB,G1B,G2B,G11B,G12B,
     *             G22B,X1,X2,G1X1B,G2X1B,G1X2B,G2X2B)
        IF (.NOT.LRAY) CALL RPERR(1)
        CALL RPRAY(IABS(KLINE(J3+1,1)),LRAY,ITYPEA,ISHA,G1A,G2A,
     *                     G11A,G12A,G22A,X1,X2,G1X1A,G2X1A,G1X2A,G2X2A)
        IF (.NOT.LRAY) CALL RPERR(1)
        CALL RPRAY(IABS(KLINE(J3+2,1)),LRAY,ITYPEC,ISHC,G1C,G2C,
     *                     G11C,G12C,G22C,X1,X2,G1X1C,G2X1C,G1X2C,G2X2C)
        IF (.NOT.LRAY) CALL RPERR(1)
        G11POM=(G11A+G11C+G11B)/3.
        G12POM=(G12A+G12C+G12B)/3.
        G22POM=(G22A+G22C+G22B)/3.
        DIST2=RPDI2G(G1C,G2C,G1B,G2B,G11POM,G12POM,G22POM)
        DETG=G11POM*G22POM - G12POM*G12POM
        IF (DETG.LT.ZERO) CALL RPERR(4)
        AREA=DETG*(((G1C-G1B)*(G2A-G2B)-(G2C-G2B)*(G1A-G1B))**2)
C       Distance:      (AREA is the area**2)
        IF (DIST2.GE.ZERO) DIST2=AREA/DIST2
        IF (DIST2.LE.16*AERR2) THEN
C         Criterion 2: (Distance of the rays J3 and J3+1)**2.lt.BSTEP2:
          DIST2=RPDI2G(G1A,G2A,G1B,G2B,G11POM,G12POM,G22POM)
          IF (DIST2.LE.BSTEP2) THEN
C           Criterion 3: (Boundary rays on the other side
C           of the boundary then rays J3 and J3+1 should display
C           the same value of the history function.)
            IF ((KLINE(J3,4).NE.0).AND.(KLINE(J3+1,4).NE.0).AND.
     *          (KLINE(J3,4).NE.KLINE(J3+1,4))) THEN
              GOTO 107
            ENDIF
C           Now proceeding with the next ray of KLINE:
            J3=J3+1
            IF (J3+2.LE.NLINE) THEN
              GOTO 141
            ELSE
              GOTO 145
            ENDIF
          ENDIF
        ELSE
          KLINE(J3+1,1)=-IABS(KLINE(J3+1,1))
        ENDIF
      ENDIF
      GOTO 107
C
  145 CONTINUE
      IF (J3.LE.NLINE-1) THEN
C       Criterion 2: (Distance of the rays J3 and J3+1)**2 .lt. BSTEP2:
        IF (KLINE(J3,1).LT.0) THEN
          KLINE(J3,1)=IABS(KLINE(J3,1))
          GOTO 107
        ENDIF
        CALL RPRAY(IABS(KLINE(J3,1)),LRAY,ITYPEB,ISHB,G1B,G2B,G11B,G12B,
     *             G22B,X1,X2,G1X1,G2X1,G1X2,G2X2)
        IF (.NOT.LRAY) CALL RPERR(1)
        CALL RPRAY(IABS(KLINE(J3+1,1)),LRAY,ITYPEA,ISHA,G1A,G2A,
     *             G11A,G12A, G22A,X1,X2,G1X1,G2X1,G1X2,G2X2)
        IF (.NOT.LRAY) CALL RPERR(1)
        G11POM=(G11A+G11B)/2.
        G12POM=(G12A+G12B)/2.
        G22POM=(G22A+G22B)/2.
        DIST2=RPDI2G(G1A,G2A,G1B,G2B,G11POM,G12POM,G22POM)
        IF (DIST2.GT.BSTEP2) GOTO 107
C       Criterion 3: (Boundary rays on the other side
C       of the boundary then rays J3 and J3+1 should display
C       the same value of the history function.)
        IF ((KLINE(J3,4).NE.0).AND.(KLINE(J3+1,4).NE.0).AND.
     *      (KLINE(J3,4).NE.KLINE(J3+1,4)))    GOTO 107
      ENDIF
C
C     Boundary is found:
      IF (J30.NE.999999) THEN
        J3=J30
        J30=999999
        GOTO 107
      ENDIF
C     GOTO 143
C
C     The boundary closing the homogeneous polygon is found.
C     Both homogeneous and inhomogeneous polygons will be corrected now:
  143 CONTINUE
      IF (NPOL.EQ.NPOLH) THEN
C       End of the division of this triangle:
        NPOL=0
      ELSE
        NPOL=NPOL-NPOLH
        DO 144, I2=J1,NPOL
          KPOL(I2,1)=KPOL(I2+NPOLH,1)
          KPOL(I2,2)=KPOL(I2+NPOLH,2)
          KPOL(I2,3)=KPOL(I2+NPOLH,3)
          KPOL(I2,4)=KPOL(I2+NPOLH,4)
          GPOL(I2,1)=GPOL(I2+NPOLH,1)
          GPOL(I2,2)=GPOL(I2+NPOLH,2)
  144   CONTINUE
        NPOL=NPOL+NLINE-2
        IF (NPOL.GT.MPOL) CALL RPERR(5)
        DO 146, I2=NPOL,NLINE+J1-2,-1
          KPOL(I2,1)=KPOL(I2-NLINE+2,1)
          KPOL(I2,2)=KPOL(I2-NLINE+2,2)
          KPOL(I2,3)=KPOL(I2-NLINE+2,3)
          KPOL(I2,4)=KPOL(I2-NLINE+2,4)
          GPOL(I2,1)=GPOL(I2-NLINE+2,1)
          GPOL(I2,2)=GPOL(I2-NLINE+2,2)
  146   CONTINUE
        DO 148, I2=2,NLINE-1
          KPOL(J1+I2-2,1)=KLINE(I2,3)
          KPOL(J1+I2-2,4)=KLINE(I2,2)
          CALL RPRAY(KLINE(I2,3),LRAY,ITYPEA,ISHA,G1A,G2A,G11A,G12A,G22A
     *              ,X1,X2,G1X1,G2X1,G1X2,G2X2)
          IF (.NOT.LRAY) CALL RPERR(1)
          KPOL(J1+I2-2,2)=ISHA
          KPOL(J1+I2-2,3)=ITYPEA
          GPOL(J1+I2-2,1)=G1A
          GPOL(J1+I2-2,2)=G2A
  148   CONTINUE
        IF (NLINE.LE.2) THEN
          IF ((J1.GT.1).AND.(J1.LE.NPOL)) THEN
            KPOL(J1-1,3)=KPOL(J1,1)
          ELSE
            KPOL(NPOL,3)=KPOL(1,1)
          ENDIF
        ENDIF
      ENDIF
      IF (NPOLH+NLINE-2.GE.MPOLH) CALL RPERR(6)
      DO 149, I2=NLINE-1,2,-1
        NPOLH=NPOLH+1
        KPOLH(NPOLH,1)=IABS(KLINE(I2,1))
        KPOLH(NPOLH,2)=KLINE(I2,2)
        KPOLH(NPOLH,3)=KLINE(I2,3)
        KPOLH(NPOLH,4)=KLINE(I2,4)
        CALL RPRAY(KPOLH(NPOLH,1),LRAY,ITYPEA,ISHA,G1A,G2A,G11A,G12A,
     *             G22A,X1,X2,G1X1,G2X1,G1X2,G2X2)
        IF (.NOT.LRAY) CALL RPERR(1)
        GPOLH(NPOLH,1)=G1A
        GPOLH(NPOLH,2)=G2A
  149 CONTINUE
      NLINE=0
C
      J5=0
      IF (ISTART.GT.0.) THEN
C       Inhomogeneous polygon will be shifted now:
        ISTART=0
        I2=0
  152   CONTINUE
        I2=I2+1
        IF (NPOL.GE.MPOL) CALL RPERR(5)
        KPOL(NPOL+1,1)=KPOL(1,1)
        KPOL(NPOL+1,2)=KPOL(1,2)
        KPOL(NPOL+1,3)=KPOL(1,3)
        KPOL(NPOL+1,4)=KPOL(1,4)
        GPOL(NPOL+1,1)=GPOL(1,1)
        GPOL(NPOL+1,2)=GPOL(1,2)
        DO 153, I1=1,NPOL
          KPOL(I1,1)=KPOL(I1+1,1)
          KPOL(I1,2)=KPOL(I1+1,2)
          KPOL(I1,3)=KPOL(I1+1,3)
          KPOL(I1,4)=KPOL(I1+1,4)
          GPOL(I1,1)=GPOL(I1+1,1)
          GPOL(I1,2)=GPOL(I1+1,2)
  153   CONTINUE
        IF ((KPOL(1,2).EQ.KPOL(NPOL,2)).AND.(I2.LT.NPOL)) GOTO 152
      ENDIF
C
C     The homogeneous polygon is prepared to be divided:
  155 CONTINUE
      LNEWAR=.FALSE.
      IF (NPOLH.LT.3) THEN
C       In this situation a very small part of the domain
C       will escape notice.
        DO 156, I1=1,NPOL
          IF (KPOL(I1,1).EQ.KPOLH(1,1)) THEN
            IF ((I1.GT.1).AND.(I1+NPOLH.LE.NPOL)) THEN
              KPOL(I1-1,3)=KPOL(I1+NPOLH,1)
            ELSEIF (I1.EQ.1) THEN
              KPOL(NPOL,3)=KPOL(I1+NPOLH,1)
            ELSE
              KPOL(I1-1,3)=KPOL(1,1)
            ENDIF
          ENDIF
  156   CONTINUE
        NPOLH=0
        IF (NPOL.GE.2) THEN
          GOTO 15
        ENDIF
        KTRID(6)=2
        CALL RPTRI2(KTRID(4),LTRI,KTRID)
        IF (.NOT.LTRI) CALL RPERR(2)
        LNEWAR=.FALSE.
        RETURN
      ENDIF
C
      IF (NPOLH.EQ.3) THEN
        IF (RPLRIT(.FALSE.,GPOLH(1,1),GPOLH(1,2),GPOLH(2,1),GPOLH(2,2),
     *            GPOLH(3,1),GPOLH(3,2),G1A,G2A,AREA)) THEN
          ITRI=ITRI+1
          KTRIN(1)=KPOLH(1,1)
          KTRIN(2)=KPOLH(2,1)
          KTRIN(3)=KPOLH(3,1)
          KTRIN(4)=ITRI
          IF (KTRID(5).EQ.0) THEN
            KTRIN(5)=KTRID(4)
          ELSE
            KTRIN(5)=KTRID(5)
          ENDIF
          KTRIN(6)=3
          CALL RPTRI1(ITRI,KTRIN)
          CALL RPSTOR('T',1,KTRIN)
        ENDIF
        NPOLH=0
        IF (NPOL.GE.2) THEN
          GOTO 15
        ENDIF
        KTRID(6)=2
        CALL RPTRI2(KTRID(4),LTRI,KTRID)
        IF (.NOT.LTRI) CALL RPERR(2)
        LNEWAR=.FALSE.
        RETURN
      ENDIF
C
C     Dividing the homogeneous polygon into triangles:
      CALL RPRAY(KPOLH(1,1),LRAY,ITYPEX,ISHX,G1X,G2X,G11X,G12X,G22X
     *                     ,X1,X2,G1X1,G2X1,G1X2,G2X2)
      IF (.NOT.LRAY) CALL RPERR(1)
  160 CALL RPHPDI(NPOLH,KPOLH,GPOLH,IRAY,ITRI,KTRID,LNEWAR,
     *            G1NEW,G2NEW)
      IF (LNEWAR) THEN
C       Trace the new ray and go to 160:
        IGOTO=5
        RETURN
      ENDIF
      IF (NPOLH.LE.0) THEN
        IF (NPOL.GE.2) THEN
          GOTO 15
        ENDIF
        KTRID(6)=2
        CALL RPTRI2(KTRID(4),LTRI,KTRID)
        IF (.NOT.LTRI) CALL RPERR(2)
        LNEWAR=.FALSE.
        RETURN
      ENDIF
      GOTO 155
      END
C
C=======================================================================
C
      SUBROUTINE RPNEW(IRAY,ITRI,G1NEW,G2NEW,LNEWAR)
C
C-----------------------------------------------------------------------
      INTEGER IRAY,ITRI
      REAL G1NEW,G2NEW
      LOGICAL LNEWAR
C
C Subroutine designed to determine a new basic triangle and
C to adjust the boundary of the region covered by the basic triangles.
C Subroutine also determines normalized ray parameters of a new ray,
C if needed.
C
C Input:
C     IRAY... Index of the last computed ray.
C     ITRI... Index of the last computed triangle.
C Output:
C     G1NEW,G2NEW...If a new basic ray is to be traced,
C                   parameters of the new ray.
C     LNEWAR... Indicates whether the new basic ray is to be computed.
C
C Subroutines and external functions required:
      EXTERNAL RPDI2G,RPLRIL,RPLRIT
      REAL RPDI2G
      LOGICAL RPLRIL,RPLRIT
C
C Coded by Petr Bulant
C
C.......................................................................
C
C Common blocks /GLIM/ and /POLY/:
      INCLUDE 'rp3d.inc'
C     rp3d.inc
C.......................................................................
C
      REAL SIDE,NEAR,SIDE2,NEAR2
      PARAMETER (SIDE=1.1547)
      PARAMETER (SIDE2=SIDE**2)
      PARAMETER (NEAR=SIDE*.618)
      PARAMETER (NEAR2=NEAR**2)
      REAL ZERO
      PARAMETER (ZERO =.0000001)
      INTEGER IRADD1,IRADD2
      INTEGER IONPOL,ICOR
      INTEGER NPL0
      INTEGER KTRIN(6)
      INTEGER ITYPE,ISHEET
      REAL G1,G2,G11,G12,G22,X1,X2
      REAL G1X1,G2X1,G1X2,G2X2
      REAL G1I,G2I,G11I,G12I,G22I,X1I,X2I
      REAL G1J,G2J,G11J,G12J,G22J,X1J,X2J
      REAL G1R2,G2R2,G11R2,G12R2,G22R2,X1R2,X2R2
      REAL G1M,G2M,G11M,G12M,G22M,X1M,X2M
      REAL G1N,G2N,G11N,G12N,G22N,X1N,X2N
      REAL G11POM,G12POM,G22POM,AAA,BBB,BBB1,DETG,VECT,DIST2,DIST21
      INTEGER I1,J1
      LOGICAL LRAY,LINTS,LIONPL
C     SIDE... Length of basic triangles sides.
C     NEAR... Length to identify rays.
C             SIDE=SQRT(4/3) , NEAR=SIDE*0.618
C     SIDE2,NEAR2 ... Second powers of SIDE and NEAR.
C     ZERO ...Constant used to decide whether the real variable.EQ.zero.
C     IRADD1,IRADD2...Sequence (in KPL) of two rays of polyline,
C                     suitable to add a new ray between them.
C     IONPOL..When as the new ray is taken some ray of the polyline, the
C             sequence (in KPL) of this ray on polyline;
C             when as the new ray is taken a corner ray of the
C             normalized domain, zero.
C     ICOR ...ICOR.NE.0 indicates that the new ray is a corner ray
C             of domain.  (then in ICOR is sign of this corner ray.)
C     NPL0... Number of the rays on the polyline before adding a new
C             triangle.
C     KTRIN...All parameters of a new triangle to be registrated.
C     ITYPE.. Type of ray:
C             0: .......... Basic ray.
C             ITYPE.GT.0:.. Boundary ray, ITYPE is the index of the
C                           boundary ray at the other side of the bound.
C             -2:.......... Auxiliary ray, not used.
C             -3:.......... Auxiliary ray, used.
C             -1000-I:..... Two-point ray (to the I'th receiver).
C     ISHEET..Value of integer function distinguishing between rays of
C             different histories.
C     G1,G2 ..Normalized parameters of rays.
C     G11,G12,G22 ... Ray-parameter metric tensor.
C     X1,X2 ..Coordinates of the ray on the reference surface.
C     G1X1,G2X1,G1X2,G2X2 ... Derivations of ray parameters according to
C                             surface coordinates.
C     G1.,G2.,G11..,G12..,G22..,X1..,X2..,   auxiliary variables.
C     AAA,BBB ..Auxiliary variables.
C     DETG... Determinant.
C     VECT... Vector product.
C     DIST2...(Distance of rays)**2
C     I1  ... Implied-do variable or variable controlling the loop.
C     J1  ... Auxiliary variable (number).
C     LRAY ...Indicates whether the ray IRAY is in memory.
C     LINTS...Indicates whether the intersection appeared.
C     LIONPL..Indicates that the new ray is the IONPOL's ray on polyline
C             or that it is a corner ray of domain (then IONPOL=0).
C-----------------------------------------------------------------------
C
      LIONPL=.FALSE.
C
C     Start of computation -  computation of first polyline rays:
      IF (IRAY.EQ.0) THEN
        NPL=0
      ENDIF
      IF (NPL.EQ.0) THEN
        IF (IRAY.EQ.0) THEN
          G1NEW=GLIMIT(1)
          G2NEW=GLIMIT(3)
          LNEWAR=.TRUE.
          RETURN
        ELSEIF (IRAY.EQ.1) THEN
          G1NEW=GLIMIT(2)
          G2NEW=GLIMIT(3)
          LNEWAR=.TRUE.
          RETURN
        ELSEIF (IRAY.EQ.2) THEN
          G1NEW=GLIMIT(1)
          G2NEW=GLIMIT(4)
          LNEWAR=.TRUE.
          RETURN
        ELSEIF (IRAY.EQ.3) THEN
          G1NEW=GLIMIT(2)
          G2NEW=GLIMIT(4)
          LNEWAR=.TRUE.
          RETURN
        ELSEIF (IRAY.EQ.4) THEN
          J1=1
        ELSE
          J1=IRAY
        ENDIF
        CALL RPRAY(J1,LRAY,ITYPE,ISHEET,G1I,G2I,G11I,G12I,G22I,X1I,X2I,
     *             G1X1,G2X1,G1X2,G2X2)
        IF (.NOT.LRAY) CALL RPERR(1)
        CALL RPRAY(2,LRAY,ITYPE,ISHEET,G1R2,G2R2,G11R2,G12R2,G22R2,
     *             X1R2,X2R2,G1X1,G2X1,G1X2,G2X2)
        IF (.NOT.LRAY) CALL RPERR(1)
        G1NEW=SQRT(SIDE2/G11I)+G1I
        G2NEW=GLIMIT(3)
        G11POM=(G11I+G11R2)/2.
        G12POM=(G12I+G12R2)/2.
        G22POM=(G22I+G22R2)/2.
        DIST2=RPDI2G(G1NEW,G2NEW,G1R2,G2R2,G11POM,G12POM,G22POM)
        IF ((DIST2.GT.NEAR2).AND.(G1NEW.LT.GLIMIT(2))) THEN
          LNEWAR=.TRUE.
          RETURN
        ENDIF
        KPL(1)=1
        NPL=1
        DO 10, I1=5,IRAY
          IF (NPL.GE.MPL) CALL RPERR(10)
          NPL=NPL+1
          KPL(NPL)=I1
  10    CONTINUE
        IF(NPL.GE.MPL) CALL RPERR(10)
        NPL=NPL+1
        KPL(NPL)=2
      ENDIF
C
C     Determination where to add a new ray.
      NPL0=NPL
      CALL RPWHAD(IRADD1,IRADD2)
      CALL RPRAY(KPL(IRADD1),LRAY,ITYPE,ISHEET,G1M,G2M,
     *           G11M,G12M,G22M,X1M,X2M,G1X1,G2X1,G1X2,G2X2)
      IF (.NOT.LRAY) CALL RPERR(1)
      CALL RPRAY(KPL(IRADD2),LRAY,ITYPE,ISHEET,G1N,G2N,
     *           G11N,G12N,G22N,X1N,X2N,G1X1,G2X1,G1X2,G2X2)
      IF (.NOT.LRAY) CALL RPERR(1)
C     ..M,..N ... Two rays of polyline between which we are
C                 adding a new ray.
C
C     All domain covered - return without adding new ray or triangle.
      IF ((G2M.EQ.GLIMIT(4)).AND.(G2N.EQ.GLIMIT(4))) THEN
        LNEWAR=.FALSE.
        RETURN
      ENDIF
C
C     Proposing of ray parameters G1NEW, G2NEW of a new ray.
      G11POM=(G11M+G11N)/2.
      G12POM=(G12M+G12N)/2.
      G22POM=(G22M+G22N)/2.
      AAA=(G11POM*(G1M-G1N)+G12POM*(G2M-G2N))
      BBB=(G12POM*(G1M-G1N)+G22POM*(G2M-G2N))
      DETG=G11POM*G22POM - G12POM*G12POM
      IF (DETG.LT.ZERO) CALL RPERR(4)
      DIST2=(G1M-G1N)*AAA + (G2M-G2N)*BBB
      G1NEW=(G1M+G1N)/2. + SIDE/SQRT(DIST2)*0.5*SQRT(3./DETG)*BBB
      G2NEW=(G2M+G2N)/2. - SIDE/SQRT(DIST2)*0.5*SQRT(3./DETG)*AAA
C
C     Checking whether the new ray is not out of the domain.
      IF (G1NEW.LT.GLIMIT(1)) THEN
        G2=G2NEW + (G1NEW-GLIMIT(1))*G12POM/G22POM
        G1NEW=GLIMIT(1)
        IF (RPLRIT(.FALSE.,G1M,G2M,G1N,G2N,G1NEW,G2,0.,0.,AAA)) G2NEW=G2
      ENDIF
      IF (G1NEW.GT.GLIMIT(2)) THEN
        G2=G2NEW + (G1NEW-GLIMIT(2))*G12POM/G22POM
        G1NEW=GLIMIT(2)
        IF (RPLRIT(.FALSE.,G1M,G2M,G1N,G2N,G1NEW,G2,0.,0.,AAA)) G2NEW=G2
      ENDIF
      IF (G2NEW.LT.GLIMIT(3)) THEN
        G1=G1NEW + (G2NEW-GLIMIT(3))*G12POM/G11POM
        G2NEW=GLIMIT(3)
        IF (RPLRIT(.FALSE.,G1M,G2M,G1N,G2N,G1,G2NEW,0.,0.,AAA)) G1NEW=G1
      ENDIF
      IF (G2NEW.GT.GLIMIT(4)) THEN
        G1=G1NEW + (G2NEW-GLIMIT(4))*G12POM/G11POM
        G2NEW=GLIMIT(4)
        IF (RPLRIT(.FALSE.,G1M,G2M,G1N,G2N,G1,G2NEW,0.,0.,AAA)) G1NEW=G1
      ENDIF
C
C     Checking whether the new ray is not too near
C     the domain boundary.
      BBB=GLIMIT(4)-G2NEW
      AAA=-BBB*G12POM/G11POM
      DIST2=AAA*(AAA*G11POM+2*BBB*G12POM)+BBB*G22POM*BBB
      IF (DIST2.LT.NEAR2) THEN
        G2=GLIMIT(4)
        G1=G1NEW+AAA
        IF (RPLRIT(.FALSE.,G1M,G2M,G1N,G2N,G1,G2,0.,0.,AAA)) THEN
          IF ((G1.GE.GLIMIT(1)).AND.(G1.LE.GLIMIT(2))) G1NEW=G1
          IF ((G2.GE.GLIMIT(3)).AND.(G2.LE.GLIMIT(4))) G2NEW=G2
        ENDIF
      ENDIF
C
      IF ((G1NEW.EQ.GLIMIT(1)).OR.(G1NEW.EQ.GLIMIT(2))) GOTO 12
C
      AAA=GLIMIT(1)-G1NEW
      BBB=-AAA*G12POM/G22POM
      DIST2=AAA*(AAA*G11POM+2*BBB*G12POM)+BBB*G22POM*BBB
      AAA=GLIMIT(2)-G1NEW
      BBB1=-AAA*G12POM/G22POM
      DIST21=AAA*(AAA*G11POM+2*BBB1*G12POM)+BBB1*G22POM*BBB1
      IF ((DIST2.LT.NEAR2).OR.(DIST21.LT.NEAR2)) THEN
        IF (DIST2.LT.DIST21) THEN
          G1=GLIMIT(1)
          G2=G2NEW+BBB
          IF (RPLRIT(.FALSE.,G1M,G2M,G1N,G2N,G1,G2,0.,0.,AAA)) THEN
            IF ((G1.GE.GLIMIT(1)).AND.(G1.LE.GLIMIT(2))) G1NEW=G1
            IF ((G2.GE.GLIMIT(3)).AND.(G2.LE.GLIMIT(4))) G2NEW=G2
          ENDIF
        ELSE
          G1=GLIMIT(2)
          G2=G2NEW+BBB1
          IF (RPLRIT(.FALSE.,G1M,G2M,G1N,G2N,G1,G2,0.,0.,AAA)) THEN
            IF ((G1.GE.GLIMIT(1)).AND.(G1.LE.GLIMIT(2))) G1NEW=G1
            IF ((G2.GE.GLIMIT(3)).AND.(G2.LE.GLIMIT(4))) G2NEW=G2
          ENDIF
        ENDIF
      ENDIF
C
  12  CONTINUE
C
      IF (((G1NEW.EQ.GLIMIT(1)).OR.(G1NEW.EQ.GLIMIT(2))).AND.
     *    (G2NEW.EQ.GLIMIT(4))) THEN
        LIONPL=.TRUE.
        IONPOL=0
        GOTO 16
      ENDIF
C
C     Checking whether the new ray is not too near to any other ray
C     in polyline or to the domain corner ray.
      DO 15, I1=3,4
        CALL RPRAY(I1,LRAY,ITYPE,ISHEET,G1,G2,G11,G12,G22,X1,X2,
     *             G1X1,G2X1,G1X2,G2X2)
        IF (.NOT.LRAY) CALL RPERR(1)
        DIST2=RPDI2G(G1NEW,G2NEW,G1,G2,G11,G12,G22)
        IF ((DIST2.LT.NEAR2).AND.
     *      RPLRIT(.FALSE.,G1M,G2M,G1N,G2N,G1,G2,0.,0.,AAA)) THEN
          G1NEW=G1
          G2NEW=G2
          LIONPL=.TRUE.
          IONPOL=0
          GOTO 16
        ENDIF
  15  CONTINUE
  16  CONTINUE
ccc   DO 20, I1=MAX0(1,IRADD1-1),MIN0(NPL,IRADD2+1)
      DO 20, I1=MAX0(2,IRADD1-1),MIN0(NPL-1,IRADD2+1)
        IF ((I1.NE.IRADD1).AND.(I1.NE.IRADD2)) THEN
          CALL RPRAY(KPL(I1),LRAY,ITYPE,ISHEET,G1,G2,G11,G12,G22,X1,X2,
     *               G1X1,G2X1,G1X2,G2X2)
          IF (.NOT.LRAY) CALL RPERR(1)
          DIST2=RPDI2G(G1NEW,G2NEW,G1,G2,G11,G12,G22)
          IF ((DIST2.LT.NEAR2).AND.
     *        RPLRIT(.FALSE.,G1M,G2M,G1N,G2N,G1,G2,0.,0.,AAA)) THEN
            G1NEW=G1
            G2NEW=G2
            LIONPL=.TRUE.
            IONPOL=I1
            GOTO 21
          ENDIF
        ENDIF
  20  CONTINUE
  21  CONTINUE
C
C     Checking intersection of polyline.
  30  CALL RPINTS(IRADD1,G1NEW,G2NEW,IRADD1,IRADD2,LIONPL,IONPOL,LINTS)
      IF (LINTS) GOTO 30
      CALL RPINTS(IRADD2,G1NEW,G2NEW,IRADD1,IRADD2,LIONPL,IONPOL,LINTS)
      IF (LINTS) GOTO 30
      IF (.NOT.LIONPL) GOTO 50
      IF (IONPOL.EQ.0) GOTO 50
      IF (((IRADD1-IONPOL).EQ.1).OR.((IRADD2-IONPOL).EQ.-1)) GOTO 50
      IF ((IRADD1-IONPOL).GT.0) THEN
        CALL RPRAY(KPL(IRADD1-1),LRAY,ITYPE,ISHEET,G1J,G2J,
     *             G11J,G12J,G22J,X1J,X2J,G1X1,G2X1,G1X2,G2X2)
        IF (.NOT.LRAY) CALL RPERR(1)
        VECT=(G1M-G1NEW)*(G2J-G2NEW)-(G1J-G1NEW)*(G2M-G2NEW)
        IF (VECT.GT.ZERO) THEN
          IONPOL=IRADD1-1
          G1NEW=G1J
          G2NEW=G2J
        ELSE
C         RP3D-011
          CALL ERROR('RP3D-011: Error in coverage of the ray domain.')
C         A part of the ray domain is probably not covered by basic
C         triangles.
C         This error should not appear.
C         Please contact the author or try to
C         change the input data.
        ENDIF
      ELSE
        CALL RPRAY(KPL(IRADD2+1),LRAY,ITYPE,ISHEET,G1J,G2J,
     *              G11J,G12J,G22J,X1J,X2J,G1X1,G2X1,G1X2,G2X2)
        IF (.NOT.LRAY) CALL RPERR(1)
        VECT=(G1N-G1NEW)*(G2J-G2NEW)-(G1J-G1NEW)*(G2N-G2NEW)
        IF (VECT.LT.ZERO) THEN
          IONPOL=IRADD2+1
          G1NEW=G1J
          G2NEW=G2J
        ELSE
C         RP3D-012
          CALL ERROR('RP3D-012: Error in coverage of the ray domain.')
C         A part of the ray domain is probably not covered by basic
C         triangles.
C         This error should not appear.
C         Please contact the author or try to
C         change the input data.
        ENDIF
      ENDIF
  50  CONTINUE
C
C     New ray is proposed, now performing the last check:
      IF (((G1NEW.EQ.G1M).AND.(G2NEW.EQ.G2M)).OR.
     *    ((G1NEW.EQ.G1N).AND.(G2NEW.EQ.G2N)).OR.
     *    RPLRIL(G1NEW,G2NEW,G1N,G2N,G1M,G2M)) THEN
        IF (G2NEW.EQ.GLIMIT(4)) THEN
          G1NEW=(G1M+G1N)/2.
          GOTO 30
        ELSE
C         RP3D-013
          CALL ERROR('RP3D-013: Error in proposing a new ray.')
C         A new ray, which should create a new basic triangle together
C         with the rays M and N lies on the line connecting the rays.
C         This error should not appear.
C         Please contact the author or try to
C         change the input data.
        ENDIF
      ENDIF
      IF (LIONPL) THEN
        LNEWAR=.FALSE.
      ELSE
        LNEWAR=.TRUE.
      ENDIF
C
      IF (.NOT.RPLRIT(.FALSE.,G1M,G2M,G1N,G2N,G1NEW,G2NEW,0.,0.,AAA))
     *    THEN
C       RP3D-030
        CALL ERROR('RP3D-030: Error in proposing a new ray.')
C       A new ray was proposed in such a way, that a left-handed
C       triangle was constructed.
C       This error should not appear.
C       Please contact the author or try to
C       change the input data.
      ENDIF
C     Adding new triangle and correcting polyline in the case that the
C     new ray is on polyline.
      IF ((LIONPL).AND.(IONPOL.NE.0)) THEN
        ITRI=ITRI+1
        KTRIN(1)=KPL(IRADD1)
        KTRIN(2)=KPL(IRADD2)
        KTRIN(3)=KPL(IONPOL)
        KTRIN(4)=ITRI
        KTRIN(5)=0
        KTRIN(6)=0
        CALL RPTRI1 (ITRI,KTRIN)
        IF ((IRADD1-IONPOL).GT.0) THEN
          DO 100, I1=1,(NPL-IRADD2+1)
            KPL(IONPOL+I1)=KPL(IRADD2+I1-1)
  100     CONTINUE
          NPL=NPL-(IRADD1-IONPOL)
        ELSE
          DO 110, I1=1,(NPL-IONPOL+1)
            KPL(IRADD1+I1)=KPL(IONPOL+I1-1)
  110     CONTINUE
          NPL=NPL-(IONPOL-IRADD2)
        ENDIF
      ENDIF
C
C     Adding new triangle and correcting polyline in the case that the
C     new ray is really the new one.
      IF (.NOT.LIONPL) THEN
        ITRI=ITRI+1
        KTRIN(1)=KPL(IRADD1)
        KTRIN(2)=KPL(IRADD2)
        KTRIN(3)=IRAY+1
        KTRIN(4)=ITRI
        KTRIN(5)=0
        KTRIN(6)=0
        CALL RPTRI1 (ITRI,KTRIN)
        IF (NPL.GE.MPL) CALL RPERR(10)
        NPL=NPL+1
        DO 120, I1=NPL,(IRADD2+1),-1
          KPL(I1)=KPL(I1-1)
  120   CONTINUE
        KPL(IRADD2)=IRAY+1
      ENDIF
C
C     Adding new triangle and correcting polyline in the case that the
C     new ray is a corner ray of domain.
      ICOR=0
      IF ((LIONPL).AND.(IONPOL.EQ.0)) THEN
        IF (G1NEW.EQ.GLIMIT(1)) THEN
          ICOR=3
        ELSE
          ICOR=4
        ENDIF
        ITRI=ITRI+1
        KTRIN(1)=KPL(IRADD1)
        KTRIN(2)=KPL(IRADD2)
        KTRIN(3)=ICOR
        KTRIN(4)=ITRI
        KTRIN(5)=0
        KTRIN(6)=0
        CALL RPTRI1 (ITRI,KTRIN)
        IF(NPL.GE.MPL) CALL RPERR(10)
        NPL=NPL+1
        DO 130, I1=NPL,(IRADD2+1),-1
          KPL(I1)=KPL(I1-1)
  130   CONTINUE
        KPL(IRADD2)=ICOR
      ENDIF
C
C     Correcting polyline in the case when the second and the third
C     polyline ray or the second and the third one from the end are
C     on the boundary of the normalized ray domain.
      IF (IRADD1.EQ.2) THEN
        IF (G1NEW.EQ.GLIMIT(1)) THEN
C         Correcting polyline:
          DO 142, I1=2,(NPL-1)
            KPL(I1)=KPL(I1+1)
  142     CONTINUE
          NPL=NPL-1
        ENDIF
      ENDIF
      IF (IRADD2.EQ.NPL0-1) THEN
C       NPL0 ... Value of NPL when calling subroutine RPWHAD.
        IF (G1NEW.EQ.GLIMIT(2)) THEN
          KPL(NPL-1)=KPL(NPL)
          NPL=NPL-1
        ENDIF
      ENDIF
      RETURN
      END
C
C=======================================================================
C
      SUBROUTINE RPINTS(ISIGN,G1NEW,G2NEW,IRADD1,IRADD2,
     *                  LIONPL,IONPOL,LINTS)
C
C-----------------------------------------------------------------------
      INTEGER ISIGN,IRADD1,IRADD2,IONPOL
      REAL G1NEW,G2NEW
      LOGICAL LINTS,LIONPL
C Subroutine will test whether the abscissa
C  [ (ISIGN's ray on polyline) , (ray with parameters G1NEW,G2NEW) ]
C has intersection with some abscissa of polyline.
C If the intersection appears, the nearer ray is taken as the new one.
C Input:
C     ISIGN ...       Sequence (in KPL) of ray of tested abscissa.
C     G1NEW,G2NEW ... New ray parameters proposed.
C     IRADD1,IRADD2...Sequence (in KPL) of two rays of polyline,
C                     between them a new ray is to be added.
C     LIONPL..Indicates that the new ray is the IONPOL's ray on polyline
C             or that it is a corner ray of domain (then IONPOL=0).
C     IONPOL..When as the new ray is taken some ray of the polyline, the
C             sequence (in KPL) of this ray on polyline;
C             when as the new ray is taken a corner ray of the
C             normalized domain, zero.
C Output:
C     LINTS...Indicates whether the intersection appeared.
C     LIONPL..Indicates that the new ray is the IONPOL's ray on polyline
C             or that it is a corner ray of domain (then IONPOL=0).
C     IONPOL..When as the new ray is taken some ray of the polyline, the
C             sequence (in KPL) of this ray on polyline;
C             when as the new ray is taken a corner ray of the
C             normalized domain, zero.
C
C Coded by Petr Bulant
C
C.......................................................................
C Common block /POLY/:
      INCLUDE 'rp3d.inc'
C     rp3d.inc
C.......................................................................
C
      REAL ZERO
      PARAMETER (ZERO =.0000001)
      INTEGER ITYPE,ISHEET
      REAL G1J,G2J,G11J,G12J,G22J,X1J,X2J
      REAL G1K,G2K,G11K,G12K,G22K,X1K,X2K
      REAL G1L,G2L,G11L,G12L,G22L,X1L,X2L
      REAL G1IO,G2IO,G11IO,G12IO,G22IO,X1IO,X2IO
      REAL G1IP,G2IP,G11IP,G12IP,G22IP,X1IP,X2IP
      REAL G1X1,G2X1,G1X2,G2X2
      REAL G1X,G2X
      INTEGER I1
      LOGICAL LRAY
C     ZERO ...Constant used to decide whether the real variable.EQ.zero.
C     ITYPE.. Type of ray:
C             0: .......... Basic ray.
C             ITYPE.GT.0:.. Boundary ray, ITYPE is the index of the
C                           boundary ray at the other side of the bound.
C             -2:.......... Auxiliary ray,not used.
C             -3:.......... Auxiliary ray,used.
C             -1000-I:..... Two-point ray (to the I'th receiver).
C     ISHEET..Value of integer function distinguishing between rays of
C             different histories.
C     G1.,G2.  ...      Normalized parameters of rays.
C     G11.,G12.,G22. .. Ray-parameter metric tensor.
C     X1.,X2.  ...      Coordinates of the ray on the reference surface.
C     G1X1,G2X1,G1X2,G2X2... Derivations of ray parameters according to
C                            surface coordinates.
C     I1  ... Implied-do variable or variable controlling the loop.
C     LRAY ...Indicates whether the ray IRAY is in memory.
C-----------------------------------------------------------------------
      DO 10, I1=1,NPL-1
        IF (I1.EQ.ISIGN-1) GOTO 10
        IF (I1.EQ.ISIGN) GOTO 10
        IF (LIONPL) THEN
          IF (I1.EQ.IONPOL) GOTO 10
          IF (I1.EQ.IONPOL-1) GOTO 10
        ENDIF
        CALL RPRAY(KPL(I1),LRAY,ITYPE,ISHEET,G1J,G2J,G11J,G12J,G22J,
     *             X1J,X2J,G1X1,G2X1,G1X2,G2X2)
        IF (.NOT.LRAY) CALL RPERR(1)
        CALL RPRAY(KPL(I1+1),LRAY,ITYPE,ISHEET,G1K,G2K,G11K,G12K,G22K,
     *             X1K,X2K,G1X1,G2X1,G1X2,G2X2)
        IF (.NOT.LRAY) CALL RPERR(1)
        CALL RPRAY(KPL(ISIGN),LRAY,ITYPE,ISHEET,G1L,G2L,
     *             G11L,G12L,G22L,X1L,X2L,G1X1,G2X1,G1X2,G2X2)
        IF (.NOT.LRAY) CALL RPERR(1)
C       ..J,..K ... The rays of tested polyline abscissa.
C       ..L     ... The ray of tested triangle abscissa.
C       ..IO,..IP ..The rays beside the polyline abscissa
C                   in which we are adding a new ray.
        CALL RPCROS(G1L,G2L,G1NEW,G2NEW,G1J,G2J,G1K,G2K,LINTS,G1X,G2X)
        IF (LINTS) GOTO 20
  10  CONTINUE
C     No intersection with polyline.
      LINTS=.FALSE.
      RETURN
  20  CONTINUE
C     Intersection with polyline between I1 and I1+1 polyline ray.
      IF (I1.LT.ISIGN) THEN
        IF (I1.EQ.ISIGN-1) THEN
          CALL RPRAY(KPL(IRADD1-1),LRAY,ITYPE,ISHEET,G1IO,G2IO,G11IO,
     *                     G12IO,G22IO,X1IO,X2IO,G1X1,G2X1,G1X2,G2X2)
          IF (.NOT.LRAY) CALL RPERR(1)
          G1NEW=G1IO
          G2NEW=G2IO
          LIONPL=.TRUE.
          IONPOL=IRADD1-1
        ELSE
          G1NEW=G1J
          G2NEW=G2J
          LIONPL=.TRUE.
          IONPOL=I1
        ENDIF
      ELSE
        IF (I1.EQ.ISIGN+1) THEN
          CALL RPRAY(KPL(IRADD2+1),LRAY,ITYPE,ISHEET,G1IP,G2IP,G11IP,
     *                     G12IP,G22IP,X1IP,X2IP,G1X1,G2X1,G1X2,G2X2)
          IF (.NOT.LRAY) CALL RPERR(1)
          G1NEW=G1IP
          G2NEW=G2IP
          LIONPL=.TRUE.
          IONPOL=IRADD2+1
        ELSE
          G1NEW=G1J
          G2NEW=G2J
          LIONPL=.TRUE.
          IONPOL=I1
        ENDIF
      ENDIF
      LINTS=.TRUE.
      RETURN
      END
C
C=======================================================================
C
      SUBROUTINE RPWHAD(IRADD1,IRADD2)
C-----------------------------------------------------------------------
      INTEGER IRADD1,IRADD2
C Subroutine designed to determine two rays of polyline, suitable
C to add a new ray between them. The normalized ray domain is covered
C from G2MIN to G2MAX.
C
C No input.
C Output:
C     IRADD1,IRADD2...Sequence (in KPL) of two rays of polyline,
C                     suitable to add a new ray between them.
C
C Coded by Petr Bulant
C
C.......................................................................
C
C Common blocks /GLIM/ and /POLY/:
      INCLUDE 'rp3d.inc'
C     rp3d.inc
C.......................................................................
      INTEGER ITYPE,ISHEET
      REAL G1,G2,G11,G12,G22,X1,X2
      REAL G1J,G2J,G11J,G12J,G22J,X1J,X2J
      REAL G1K,G2K,G11K,G12K,G22K,X1K,X2K
      REAL G1X1,G2X1,G1X2,G2X2
      REAL MIN
      INTEGER I1
      LOGICAL LRAY
C     ITYPE.. Type of ray:
C             0: .......... Basic ray.
C             ITYPE.GT.0:.. Boundary ray, ITYPE is the index of the
C                           boundary ray at the other side of the bound.
C             -2:.......... Auxiliary ray,not used.
C             -3:.......... Auxiliary ray,used.
C             -1000-I:..... Two-point ray (to the I'th receiver).
C     ISHEET..Value of integer function distinguishing between rays of
C             different histories.
C     G1,G2 ..Normalized parameters of rays.
C     G11,G12,G22 ... Ray-parameter metric tensor.
C     X1,X2  ...      Coordinates of the ray on the reference surface.
C     G1X1,G2X1,G1X2,G2X2 ... Derivations of ray parameters according to
C                             surface coordinates.
C     G1.,G2.,G11..,G12..,G22..,X1..,X2..,   auxiliary variables.
C     MIN ... Minimum G2 of rays of polyline.
C     I1  ... Implied-do variable or variable controlling the loop.
C     LRAY ...Indicates whether the ray IRAY is in memory.
C-----------------------------------------------------------------------
C
C     First ray:
      IF (NPL.LT.2) THEN
C         RP3D-014
          CALL ERROR('RP3D-014: Error in adding a new ray.')
C         This error should not appear.
C         Please contact the author or try to
C         change the input data.
      ENDIF
      IRADD1=2
      MIN=GLIMIT(4)
      DO 10, I1=NPL-1,2,-1
        CALL RPRAY(KPL(I1),LRAY,ITYPE,ISHEET,G1,G2,G11,G12,G22,X1,X2,
     *             G1X1,G2X1,G1X2,G2X2)
        IF (.NOT.LRAY) CALL RPERR(1)
        IF (G2.LE.MIN) THEN
          MIN=G2
          IRADD1=I1
        ENDIF
  10  CONTINUE
C
C     Second ray:
      IF (IRADD1.EQ.2) THEN
        CALL RPRAY(KPL(2),LRAY,ITYPE,ISHEET,G1,G2,G11,G12,G22,X1,X2,
     *             G1X1,G2X1,G1X2,G2X2)
        IF (.NOT.LRAY) CALL RPERR(1)
        IF (G1.EQ.GLIMIT(1)) THEN
          IF (G2.EQ.GLIMIT(4)) THEN
            CALL RPRAY(KPL(NPL-1),LRAY,ITYPE,ISHEET,G1,G2,G11,G12,G22,
     *                 X1,X2,G1X1,G2X1,G1X2,G2X2)
            IF (.NOT.LRAY) CALL RPERR(1)
            IF (G1.EQ.GLIMIT(2)) THEN
              IRADD1=NPL-2
              IRADD2=NPL-1
            ELSE
              IRADD1=NPL-1
              IRADD2=NPL
            ENDIF
          ELSE
            IRADD2=3
          ENDIF
        ELSE
          IRADD1=1
          IRADD2=2
        ENDIF
        RETURN
      ENDIF
      IF (IRADD1.EQ.NPL-1) THEN
        CALL RPRAY(KPL(NPL-1),LRAY,ITYPE,ISHEET,G1,G2,G11,G12,G22,X1,X2,
     *             G1X1,G2X1,G1X2,G2X2)
        IF (.NOT.LRAY) CALL RPERR(1)
        IF (G1.EQ.GLIMIT(2)) THEN
          IRADD1=NPL-2
          IRADD2=NPL-1
        ELSE
          IRADD2=NPL
        ENDIF
        RETURN
      ENDIF
      CALL RPRAY(KPL(IRADD1+1),LRAY,ITYPE,ISHEET,G1J,G2J,
     *           G11J,G12J,G22J,X1J,X2J,G1X1,G2X1,G1X2,G2X2)
      IF (.NOT.LRAY) CALL RPERR(1)
      CALL RPRAY(KPL(IRADD1-1),LRAY,ITYPE,ISHEET,G1K,G2K,
     *           G11K,G12K,G22K,X1K,X2K,G1X1,G2X1,G1X2,G2X2)
      IF (.NOT.LRAY) CALL RPERR(1)
      IF (G2J.LT.G2K) THEN
        IRADD2=IRADD1+1
      ELSE
        IRADD2=IRADD1
        IRADD1=IRADD2-1
      ENDIF
      END
C
C=======================================================================
C
      SUBROUTINE RPMEM(IRAY,ITYPE,ISHEET,G1,G2,G11,G12,G22,S11,S12,S22,
     *                 X1,X2,G1X1,G2X1,G1X2,G2X2)
C-----------------------------------------------------------------------
      INTEGER IRAY,ITYPE,ISHEET,ICRTB
      REAL G1,G2,G11,G12,G22,S11,S12,S22,X1,X2
      REAL G1X1,G2X1,G1X2,G2X2
C Subroutine designed to store the computed rays.
C Input:
C     IRAY... Sign of the stored ray.
C     ITYPE.. Type of ray:
C             0: .......... Basic ray.
C             ITYPE.GT.0:.. Boundary ray, ITYPE is the index of the
C                           boundary ray at the other side of the bound.
C             -2:.......... Auxiliary ray,not used.
C             -3:.......... Auxiliary ray,used.
C             -1000-I:..... Two-point ray (to the I'th receiver).
C     ISHEET..Value of integer function distinguishing between rays of
C             different histories. Two rays with different histories
C             have different values of ISHEET. For instance, rays
C             refracted in different layers or incident at different
C             surfaces have different histories.
C     G1,G2.. Normalized parameters of ray.
C     G11,G12,G22...  Components of the ray-parameter
C             metric tensor.
C     S11,S12,S22 ... Components of the ray-tube metric tensor,
C             describing thickness of the ray tubes.
C     X1,X2 ..Coordinates of the ray on the reference surface.
C     G1X1,G2X1,G1X2,G2X2... Derivations of ray parameters according to
C                            surface coordinates.
C No output.
C
C Subroutines and external functions required:
C
      EXTERNAL LENGTH
      INTEGER LENGTH
C
C Coded by Petr Bulant
C
C.......................................................................
C Common block /RPARD/:
      INCLUDE 'rpard.inc'
C     rpard.inc
C     XERR... Maximum distance of the two-point ray from the receiver
C             at the reference surface.
C     PRM0(5)... Maximum distance of the two-point ray from the receiver
C             at the reference surface, if no ray distant less than XERR
C             has been found.
C None of the storage locations of the common block are altered.
C............................
C Common block /RAY/:
      INCLUDE 'rp3d.inc'
C     rp3d.inc
C............................
C Common block /NST/:
C     Common block storing the ray, which was nearest to the current
C     receiver. If a two-point ray to the receiver cannot be found,
C     this ray is taken instead of the two-point ray and a warning is
C     generated to the logout file.
      REAL DISNST
      LOGICAL LNST
      COMMON/NST/LNST,DISNST
      SAVE/NST/
C     DISNST   ...    Distance of the ray from the receiver.
C     LNST     ...    Indicates, that the nearest ray is to be taken
C                     as a two-point ray.
C.......................................................................
      INTEGER IREC
      INTEGER INDRAY,IIRAY
      INTEGER ID
      INTEGER I1,I2,I3,I4,KALL
      REAL DIST2,DISNS
      LOGICAL LRAY
      CHARACTER*24  FORMAT
      CHARACTER*240 TXTERR
      SAVE I1,I2
C
C     IREC  ..If the two-point ray is being determined, index
C             of the corresponding receiver.
C     INDRAY..Sequence in KRAY of the given ray.
C     IIRAY ..Absolute value of IRAY.
C     I1,I2...Implied-do variables or variables controlling the loop.
C     LRAY ...Indicates whether the ray IRAY is in memory.
C-----------------------------------------------------------------------
C
      IF (IRAY.EQ.0) THEN
        NRAY=0
        IF ((PRM0(5).NE.0.).AND.(PRM0(5).LE.XERR)) THEN
C         RP3D-034
          CALL ERROR('RP3D-034: Wrong value of PRM0(5)')
C         PRM0(5), if specified, should be positive and greater
C         than XERR. See the description in file
C         rpar.for.
        ENDIF
      ELSE
        IF (ITYPE.LT.-1000) THEN
          IREC=-ITYPE-1000
          IF ((IREC.LT.1).OR.(IREC.GT.NREC)) THEN
C           RP3D-646
            CALL ERROR('RP3D-646: Wrong index of the receiver')
C           This error should not appear.
C           Please contact the author.
          ENDIF
          IF (LNST) THEN
            DISNS=SQRT(DISNST)
            IF ((PRM0(5).NE.0.).AND.(DISNS.GT.PRM0(5))) THEN
C               RP3D-035
                FORMAT='(A,1I0,A,1I0,A,1F15.6,A)'
                I4=INT(ALOG10(FLOAT(IRAY)))+1
                FORMAT(6:6)=CHAR(ICHAR('0')+I4)
                I4=INT(ALOG10(FLOAT(IREC)))+1
                FORMAT(12:12)=CHAR(ICHAR('0')+I4)
                CALL FORM1(DISNS,DISNS,FORMAT(17:24))
                FORMAT(24:24)=')'
                WRITE(TXTERR,FORMAT)
     *          ' RP3D-035: The ray with index ',IRAY,
     *          ' is nearest ray to the receiver ',IREC,
     *          ' but its distance ',DISNS,
     *          ' is greater than PRM0(5)'
                CALL WARN(TXTERR(1:LENGTH(TXTERR)))
C               The program failed to find a ray distant from the
C               receiver under consideration less then XERR. The nearest
C               found ray (distant DISNS from the receiver) is
C               distant more than PRM0(5) and thus cannot be taken
C               instead.
                ITYPE=-2
            ELSE
C             RP3D-031
                FORMAT='(A,1I0,A,1I0,A,1F15.6,A)'
                I4=INT(ALOG10(FLOAT(IRAY)))+1
                FORMAT(6:6)=CHAR(ICHAR('0')+I4)
                I4=INT(ALOG10(FLOAT(IREC)))+1
                FORMAT(12:12)=CHAR(ICHAR('0')+I4)
                CALL FORM1(DISNS,DISNS,FORMAT(17:24))
                FORMAT(24:24)=')'
                WRITE(TXTERR,FORMAT)
     *        ' RP3D-031: The two-point ray with index ',IRAY,
     *        ' to the receiver ',IREC,
     *        ' is distant ',DISNS,
     *        ' from the receiver'
              CALL WARN(TXTERR(1:LENGTH(TXTERR)))
C             The program failed to find a ray distant from the receiver
C             under consideration less then XERR. The nearest found ray
C             (distant DISNS from the receiver) was taken
C             instead.
            ENDIF
          ELSE
            IF (ISHEET.GT.0) THEN
C             Determination of two-point rays:
              DIST2=(X1-XREC(1,IREC))**2+(X2-XREC(2,IREC))**2
              IF (DIST2.GT.XERR**2) THEN
                ITYPE=-2
              ENDIF
            ELSE
              ITYPE=-2
            ENDIF
          ENDIF
        ENDIF
C
        IF(NRAY.GE.MRAY) THEN
C         RP3D-015
          CALL ERROR('RP3D-015: Insufficient memory for rays.')
C         This error may be caused by too small dimension of array
C         KRAY. Try to enlarge the parameter MRAY in common block RAY
C         in file rp3d.inc.
        ENDIF
        NRAY=NRAY+1
        KRAY(NRAY)=IRAY
        ITRAY(NRAY)=ITYPE
        ISRAY(NRAY)=ISHEET
        IBRAY(NRAY)=0
        G1RAY(NRAY)=G1
        G2RAY(NRAY)=G2
        X1RAY(NRAY)=X1
        X2RAY(NRAY)=X2
        G11RAY(NRAY)=G11
        G12RAY(NRAY)=G12
        G22RAY(NRAY)=G22
        S11RAY(NRAY)=S11
        S12RAY(NRAY)=S12
        S22RAY(NRAY)=S22
        G1X1RA(NRAY)=G1X1
        G1X2RA(NRAY)=G1X2
        G2X1RA(NRAY)=G2X1
        G2X2RA(NRAY)=G2X2
      ENDIF
      RETURN
C
C-----------------------------------------------------------------------
C
      ENTRY RPMC1(IRAY,ITYPE)
      KALL=1
      GOTO 5
C.......................................................................
      ENTRY RPMC2(IRAY,ICRTB)
      KALL=2
C.......................................................................
  5   CONTINUE
C
C-----------------------------------------------------------------------
C     Entry designed to change value ITYPE
C     for ray with sign IRAY.
C Input:
C     IRAY... Sign of the ray which is to be changed.
C     ITYPE.. Type of ray.
C     ICRTB.. Identification, whether the ray has been written to the
C             file 'CRT-B'.
C No output.
C-----------------------------------------------------------------------
      I2=MAX0(2,NRAY-KRAY(NRAY)+IRAY)
      DO 1, I1=I2,I2-1,-1
        IF(KRAY(I1).EQ.IRAY) THEN
          INDRAY=I1
          GOTO 10
        ENDIF
  1   CONTINUE
      DO 2, I1=I2+1,NRAY
        IF(KRAY(I1).EQ.IRAY) THEN
          INDRAY=I1
          GOTO 10
        ENDIF
  2   CONTINUE
      DO 3, I1=I2-2,1,-1
        IF(KRAY(I1).EQ.IRAY) THEN
          INDRAY=I1
          GOTO 10
        ENDIF
  3   CONTINUE
      CALL RPERR(1)
C
  10  CONTINUE
      IF (KALL.EQ.1) ITRAY(INDRAY)=ITYPE
      IF (KALL.EQ.2) IBRAY(INDRAY)=ICRTB
      RETURN
C
C-----------------------------------------------------------------------
C
      ENTRY RPRAY (IRAY,LRAY,ITYPE,ISHEET,G1,G2,G11,G12,G22,
     *             X1,X2,G1X1,G2X1,G1X2,G2X2)
      KALL=1
      GOTO 11
C.......................................................................
      ENTRY RPRAY2(IRAY,LRAY,ITYPE,ISHEET,G1,G2,G11,G12,G22,
     *             S11,S12,S22,X1,X2,G1X1,G2X1,G1X2,G2X2)
      KALL=2
      GOTO 11
C.......................................................................
      ENTRY RPRAY3(IRAY,LRAY,ITYPE,ISHEET,ICRTB,G1,G2,G11,G12,G22,
     *             X1,X2,G1X1,G2X1,G1X2,G2X2)
C.......................................................................
      KALL=3
  11  CONTINUE
C
C-----------------------------------------------------------------------
C
C Entry designed to give all information about ray with sign IRAY
C or to remove the ray from the memory (if IRAY is negative).
C Input:
C     IRAY... Index of the ray.
C Output:
C     LRAY... Identifies whether the ray has been found in the memory.
C     ITYPE.. Type of ray:
C             0:.......... Basic ray.
C             ITYPE.GT.0:. Boundary ray, ITYPE is the index of the
C                          boundary ray at the other side of the
C                          boundary.
C             -2:........  Auxiliary ray,not used.
C             -3:........  Auxiliary ray,used.
C             -1000-I:...  Two-point ray.
C     ISHEET..Value of integer function distinguishing between rays of
C             different histories.  Two rays with different histories
C             have different values of ISHEET.  For instance, rays
C             refracted in different layers or incident at different
C             surfaces have different histories.
C     ICRTB.. Identification, whether the ray has been written to CRT-B.
C     G1,G2.. Normalized parameters of ray.
C     G11,G12,G22...  Components of the ray-parameter metric tensor.
C     S11,S12,S22...  Components of the ray-tube metric tensor.
C     X1,X2 ..Coordinates of the ray on the ref. surface.
C     G1X1,G2X1,G1X2,G2X2... Derivations of ray parameters according to
C                            surface coordinates.
C-----------------------------------------------------------------------
C
      IIRAY=IABS(IRAY)
      I1=1
      I2=NRAY
C     The ray is being searched for within interval I1,I2.
   15 CONTINUE
        I3=I2-KRAY(I2)+IIRAY
        IF(I3.EQ.I2) THEN
          INDRAY=I2
          GOTO 20
        ELSE IF(I3.GT.I2) THEN
          LRAY=.FALSE.
          RETURN
        ELSE
          I2=I2-1
          IF(I3.GT.I1) THEN
            I1=I3
          ENDIF
        ENDIF
C
        I3=I1-KRAY(I1)+IIRAY
        IF(I3.EQ.I1) THEN
          INDRAY=I1
          GOTO 20
        ELSE IF(I3.LT.I1) THEN
          LRAY=.FALSE.
          RETURN
        ELSE
          I1=I1+1
          IF(I3.LT.I2) THEN
            I2=I3
          ENDIF
        ENDIF
C
        IF(I1.LT.I2) THEN
          I3=(I1+I2)/2
          IF(KRAY(I3).EQ.IIRAY) THEN
            INDRAY=I3
            GOTO 20
          ELSE IF(KRAY(I3).LT.IIRAY) THEN
            I1=I3+1
          ELSE
            I2=I3-1
          ENDIF
        ENDIF
C
        IF(I1.GT.I2) THEN
          LRAY=.FALSE.
          RETURN
        ENDIF
       GOTO 15
C
   20 CONTINUE
      LRAY=.TRUE.
      IF(IRAY.GT.0) THEN
        ITYPE =ITRAY(INDRAY)
        ISHEET=ISRAY(INDRAY)
        IF (KALL.EQ.3) THEN
          ICRTB =IBRAY(INDRAY)
        ENDIF
        G1    =G1RAY(INDRAY)
        G2    =G2RAY(INDRAY)
        X1    =X1RAY(INDRAY)
        X2    =X2RAY(INDRAY)
        G11   =G11RAY(INDRAY)
        G12   =G12RAY(INDRAY)
        G22   =G22RAY(INDRAY)
        IF (KALL.EQ.2) THEN
          S11   =S11RAY(INDRAY)
          S12   =S12RAY(INDRAY)
          S22   =S22RAY(INDRAY)
        ENDIF
        G1X1  =G1X1RA(INDRAY)
        G1X2  =G1X2RA(INDRAY)
        G2X1  =G2X1RA(INDRAY)
        G2X2  =G2X2RA(INDRAY)
      ELSE
C       Removing the ray from the memory:
        IF (IRAY.GE.-4) THEN
          RETURN
        END IF
        NRAY=NRAY-1
        DO 21, I1=INDRAY,NRAY
          I2=I1+1
          KRAY(I1)  =KRAY(I2)
          ITRAY(I1) =ITRAY(I2)
          ISRAY(I1) =ISRAY(I2)
          IBRAY(I1) =IBRAY(I2)
          G1RAY(I1) =G1RAY(I2)
          G2RAY(I1) =G2RAY(I2)
          X1RAY(I1) =X1RAY(I2)
          X2RAY(I1) =X2RAY(I2)
          G11RAY(I1)=G11RAY(I2)
          G12RAY(I1)=G12RAY(I2)
          G22RAY(I1)=G22RAY(I2)
          S11RAY(I1)=S11RAY(I2)
          S12RAY(I1)=S12RAY(I2)
          S22RAY(I1)=S22RAY(I2)
          G1X1RA(I1)=G1X1RA(I2)
          G1X2RA(I1)=G1X2RA(I2)
          G2X1RA(I1)=G2X1RA(I2)
          G2X2RA(I1)=G2X2RA(I2)
   21   CONTINUE
      ENDIF
      RETURN
C
C-----------------------------------------------------------------------
C
      ENTRY RPRAYP(ID,LRAY,IRAY,ITYPE,ISHEET,G1,G2,G11,G12,G22,
     *             X1,X2,G1X1,G2X1,G1X2,G2X2)
C
C-----------------------------------------------------------------------
C
C Entry designed to give consequently an information about all the rays
C stored in the memory.
C Input:
C     ID: ID.NE.0 ... Initialization of the listing:
C           ID .gt. 0 .. The listing is started from the ID's ray
C                     stored in the memory going up.
C           ID .lt. 0 .. The listing is started from the (IABS(ID))'s
C                     ray stored in the memory going down.
C           No output when ID.NE.0.
C         ID.EQ.0 ... Next ray.
C Output:
C     LRAY... Identifies whether some ray has been found in the memory.
C     IRAY,ITYPE,ISHEET, G1,...  ... Information about the ray.
C-----------------------------------------------------------------------
      IF (ID.EQ.0) THEN
        I1=I1+I2
      ELSEIF (ID.GT.0) THEN
        I1=ID-1
        I2= 1
      ELSE
        I1=MIN0(NRAY,-ID)+1
        I2=-1
      ENDIF
      IF ((I1.LT.1).OR.(I1.GT.NRAY)) THEN
        LRAY=.FALSE.
      ELSE
        IRAY  =KRAY  (I1)
        ITYPE =ITRAY (I1)
        ISHEET=ISRAY (I1)
        G1    =G1RAY (I1)
        G2    =G2RAY (I1)
        X1    =X1RAY (I1)
        X2    =X2RAY (I1)
        G11   =G11RAY(I1)
        G12   =G12RAY(I1)
        G22   =G22RAY(I1)
        G1X1  =G1X1RA(I1)
        G1X2  =G1X2RA(I1)
        G2X1  =G2X1RA(I1)
        G2X2  =G2X2RA(I1)
        LRAY=.TRUE.
      ENDIF
      RETURN
      END
C
C=======================================================================
C
      SUBROUTINE RPTRI1(ITRI,KTRIL)
C
C-----------------------------------------------------------------------
      INTEGER ITRI,KTRIL(6)
C Subroutine designed to store triangles.
C Input:
C     ITRI... Index of the stored triangle.
C     KTRIL...All parameters of the triangle which will be stored.
C No output.
C
C Subroutines and external functions required:
C
C Coded by Petr Bulant
C
C.......................................................................
C Common block /TRIAN/:
      INCLUDE 'rp3d.inc'
C     rp3d.inc
C ...........................
      INTEGER ITRIA,INDTRI
      INTEGER ITYPE,ISHEET
      REAL G1,G2,G11,G12,G22,X1,X2
      REAL G1X1,G2X1,G1X2,G2X2
      INTEGER I1,I2,I3,J1
      INTEGER ID
      LOGICAL LTRI
      LOGICAL LRAY
      SAVE I1,I2
C     ITRIA ..Absolute value of ITRI.
C     INDTRI..Sequence in KTRI of the triangle with index ITRIA.
C     ITYPE.. Type of ray:
C             0: .......... Basic ray.
C             ITYPE.GT.0:.. Boundary ray, ITYPE is the index of the
C                           boundary ray at the other side of the bound.
C             -2:.......... Auxiliary ray,not used.
C             -3:.......... Auxiliary ray,used.
C             -1000-I:..... Two-point ray (to the I'th receiver).
C     ISHEET..Value of integer function distinguishing between rays of
C             different histories.
C     G1,G2 ..Normalized parameters of rays.
C     G11,G12,G22 ... Ray-parameter metric tensor.
C     X1,X2 ..Coordinates of the ray on the reference surface.
C     G1X1,G2X1,G1X2,G2X2 ... Derivations of ray parameters according to
C                             surface coordinates.
C     I1,I2 ..Implied-do variables or variables controlling the loop.
C     J1  ... Auxiliary variable (number).
C     LTRI ...Indicates whether the triangle ITRI is in memory.
C     LRAY ...Indicates whether the ray IRAY is in memory.
C-----------------------------------------------------------------------
      IF (ITRI.EQ.0) THEN
C       Initialization:
        NTRI=0
        RETURN
      ENDIF
      IF (KTRIL(6).EQ.3) THEN
        CALL RPRAY(KTRIL(1),LRAY,ITYPE,ISHEET,G1,G2,G11,G12,G22,X1,X2,
     *             G1X1,G2X1,G1X2,G2X2)
        IF (.NOT.LRAY) CALL RPERR(1)
        IF (ISHEET.GT.0)  CALL RPAUX1(ITRI,0)
      ENDIF
C
      IF (NTRI.GE.MTRI) THEN
C       RP3D-016
        CALL ERROR('RP3D-016: Insufficient memory for triangles.')
C       This error may be caused by too small dimension of array
C       KTRI. Try to enlarge the parameter MTRI in common block TRIAN
C       in file rp3d.inc.
      ENDIF
      NTRI=NTRI+1
      DO 10, I1=1,6
        KTRI(I1,NTRI)=KTRIL(I1)
  10  CONTINUE
      RETURN
C
C-----------------------------------------------------------------------
C
      ENTRY RPTRI2(ITRI,LTRI,KTRIL)
C
C-----------------------------------------------------------------------
C Entry designed to change values (in array KTRI) for triangle
C with sign ITRI.
C Input:
C     ITRI... Index of the triangle which is to be changed.
C     KTRIL...All parameters of this triangle.
C Output:
C     LTRI ...Indicates whether the triangle ITRI is in memory.
C-----------------------------------------------------------------------
C
      CALL RPSTOR('T',1,KTRIL)
      J1=MAX0(2,NTRI-KTRI(4,NTRI)+ITRI)
      DO 11, I1=J1,J1-1,-1
        IF(KTRI(4,I1).EQ.ITRI) THEN
          INDTRI=I1
          GOTO 20
        ENDIF
  11   CONTINUE
      DO 12, I1=J1+1,NTRI
        IF(KTRI(4,I1).EQ.ITRI) THEN
          INDTRI=I1
          GOTO 20
        ENDIF
  12   CONTINUE
      DO 13, I1=J1-2,1,-1
        IF(KTRI(4,I1).EQ.ITRI) THEN
          INDTRI=I1
          GOTO 20
        ENDIF
  13   CONTINUE
      LTRI=.FALSE.
      RETURN
C
  20  CONTINUE
      DO 25, I1=1,6
        KTRI(I1,INDTRI)=KTRIL(I1)
  25  CONTINUE
      IF (KTRIL(6).EQ.3) THEN
        CALL RPRAY(KTRIL(1),LRAY,ITYPE,ISHEET,G1,G2,G11,G12,G22,X1,X2,
     *             G1X1,G2X1,G1X2,G2X2)
        IF (.NOT.LRAY) CALL RPERR(1)
        IF (ISHEET.GT.0)  CALL RPAUX1(ITRI,0)
      ENDIF
      LTRI=.TRUE.
      RETURN
C
C-----------------------------------------------------------------------
C
      ENTRY RPTRI3(ITRI,LTRI,KTRIL)
C
C-----------------------------------------------------------------------
C
C Entry designed to give all information about triangle with sign ITRI
C or to remove the triangle from the memory (when ITRI is negative).
C Input:
C     ITRI... Index of the triangle.
C Output:
C     LTRI ...Indicates whether the triangle ITRI is in memory.
C     KTRIL...All parameters of the triangle with index ITRI.
C-----------------------------------------------------------------------
C
      IF (NTRI.LE.0) THEN
        LTRI=.FALSE.
        RETURN
      ENDIF
      ITRIA=IABS(ITRI)
      J1=MAX0(2,NTRI-KTRI(4,NTRI)+ITRIA)
      DO 31, I1=J1,J1-1,-1
        IF(KTRI(4,I1).EQ.ITRIA) THEN
          INDTRI=I1
          GOTO 40
        ENDIF
  31  CONTINUE
      DO 32, I1=J1+1,NTRI
        IF(KTRI(4,I1).EQ.ITRIA) THEN
          INDTRI=I1
          GOTO 40
        ENDIF
  32  CONTINUE
      DO 33, I1=J1-2,1,-1
        IF(KTRI(4,I1).EQ.ITRIA) THEN
          INDTRI=I1
          GOTO 40
        ENDIF
  33  CONTINUE
      LTRI=.FALSE.
      RETURN
C
  40  CONTINUE
      IF (ITRI.GT.0) THEN
        DO 45, I1=1,6
          KTRIL(I1)=KTRI(I1,INDTRI)
  45    CONTINUE
        LTRI=.TRUE.
        RETURN
      ELSE
C       Removing the triangle from the memory:
        J1=MIN0(NTRI,MTRI-1)
        DO 100, I1=INDTRI,J1
          DO 95, I2=1,6
            KTRI(I2,I1)=KTRI(I2,I1+1)
  95      CONTINUE
  100   CONTINUE
        NTRI=NTRI-1
      ENDIF
C
C-----------------------------------------------------------------------
C
      ENTRY RPTRIP(ID,LTRI,KTRIL)
C
C-----------------------------------------------------------------------
C
C Entry designed to give consequently all information about all the
C triangles stored in the memory.
C Input:
C     ID: ID.NE.0 ... Initialization of the listing:
C           ID .gt. 0 .. The listing is started from the ID's triangle
C                     stored in the memory going up.
C           ID .lt. 0 .. The listing is started from the (IABS(ID))'s
C                     triangle stored in the memory going down.
C           No output when ID.NE.0.
C         ID.EQ.0 ... Next triangle.
C Output:
C     LTRI... Identifies whether some triangle has been found in memory.
C     KTRIL  ... Information about the triangle.
C-----------------------------------------------------------------------
      IF (ID.EQ.0) THEN
        I1=I1+I2
      ELSEIF (ID.GT.0) THEN
        I1=ID-1
        I2= 1
      ELSE
        I1=MIN0(NTRI,-ID)+1
        I2=-1
      ENDIF
      IF ((I1.LT.1).OR.(I1.GT.NTRI)) THEN
        LTRI=.FALSE.
      ELSE
        DO 55, I3=1,6
          KTRIL(I3)=KTRI(I3,I1)
  55    CONTINUE
        LTRI=.TRUE.
      ENDIF
      RETURN
      END
C
C=======================================================================
C
      SUBROUTINE RPAUX1(ITRI,IRAY)
C
C-----------------------------------------------------------------------
      INTEGER ITRI,IRAY
C Subroutine designed to store auxiliary rays according to triangles,
C where they most probably start and terminate, to delete ray from the
C register or to remove triangle from the register.
C In current version only the vertices of homogeneous triangles
C and found two-point rays are stored.
C Input:
C     ITRI... Index of the triangle in which the ray most probably
C             terminates, or of a new triangle. ITRI=0 when erasing
C             auxiliary ray IRAY from register. ITRI .LT. 0 when
C             deleting triangle from register.
C     IRAY... IRAY=0 if a new triangle has been created,
C             otherwise IRAY is the index of an auxiliary ray.
C No output.
C
C Subroutines and external functions required:
C
C Coded by Petr Bulant
C
C.......................................................................
C     Common block /AUX/:
      INCLUDE 'rp3d.inc'
C     rp3d.inc
C
C............................
      INTEGER ISEQ
      INTEGER ITYPE,ISHEET
      REAL G1,G2,G11,G12,G22,X1,X2
      REAL G1X1,G2X1,G1X2,G2X2
      INTEGER I1,I2
      INTEGER J1,J2
      LOGICAL LRAY
      INTEGER KTRIS(6)
C
C     MARAY...Maximum number of auxiliary rays in memory
C             (dimension of array KARAY).
C     NARAY.. Number of auxiliary rays in memory.
C     KARAY.. List of triangle indices,numbers of auxiliary rays and
C             indices of auxiliary rays.
C     ITYPE,ISHEET,G1,G2,G11,G12,G22,X1,X2 ... All parameters of ray.
C     G1X1,G2X1,G1X2,G2X2... Derivations of ray parameters according to
C                            surface coordinates.
C     I1,I2,..Implied-do variables or variables controlling the loop.
C     J1,J2,..Auxiliary variables (numbers).
C     LRAY ...Indicates whether the ray IRAY is in memory.
C     KTRIS...Not used here.
C-----------------------------------------------------------------------
C
      IF (ITRI.EQ.0) THEN
        IF (IRAY.EQ.0) THEN
C         Initialization:
          NARAY=0
          RETURN
        ENDIF
C       Removing the ray from register of auxiliary rays:
        IF (NARAY.LE.0) RETURN
        J1=2
  5     DO 7, I1=1,KARAY(J1)
          IF (KARAY(J1+I1).EQ.IRAY) THEN
            KARAY(J1)=KARAY(J1)-1
            NARAY=NARAY-1
            DO 8, I2=J1+I1,NARAY
              KARAY(I2)=KARAY(I2+1)
  8         CONTINUE
            GOTO 5
          ENDIF
  7     CONTINUE
        J1=J1+KARAY(J1)+2
        IF (J1.GE.NARAY) RETURN
        GOTO 5
      ELSEIF (ITRI.LT.0) THEN
C       Removing the triangle from the register:
        IF (NARAY.LE.0) RETURN
        J1=1
  9     IF (KARAY(J1).EQ.(-ITRI)) THEN
          J2=KARAY(J1+1) + 2
          DO 11, I1=J1,NARAY-J2
            KARAY(I1)=KARAY(I1+J2)
  11      CONTINUE
          NARAY=NARAY-J2
          IF (J1.LT.NARAY) GOTO 9
        ELSE
          J2=KARAY(J1+1)
          J1=J1+2+J2
          IF (J1.LT.NARAY) GOTO 9
        ENDIF
        RETURN
      ELSE
        IF (IRAY.EQ.0) THEN
          IF (NARAY.GE.MARAY-1) THEN
C           RP3D-017
            CALL ERROR('RP3D-017: Insufficient memory for KARAY.')
C           This error may be caused by too small dimension of array
C           KARAY. Try to enlarge the parameter MARAY in common block
C           AUX in file
C           rp3d.inc.
          ENDIF
          NARAY=NARAY+1
          KARAY(NARAY)=ITRI
          NARAY=NARAY+1
          KARAY(NARAY)=0
          RETURN
        ELSE
          J1=1
  10      IF (KARAY(J1).EQ.ITRI) THEN
            IF (NARAY.GE.MARAY) THEN
C             RP3D-018
              CALL ERROR('RP3D-018: Insufficient memory for KARAY.')
C             This error may be caused by too small dimension of array
C             KARAY. Try to enlarge the parameter MARAY in common block
C             AUX in file
C             rp3d.inc.
            ENDIF
            NARAY=NARAY+1
            DO 20, I2=NARAY,J1+3,-1
              KARAY(I2)=KARAY(I2-1)
  20        CONTINUE
            KARAY(J1+2)=IRAY
            KARAY(J1+1)=KARAY(J1+1)+1
C           Noting that auxiliary ray has been used:
            CALL RPRAY(IRAY,LRAY,ITYPE,ISHEET,G1,G2,G11,G12,G22,X1,X2,
     *                 G1X1,G2X1,G1X2,G2X2)
            IF (.NOT.LRAY) CALL RPERR(1)
            IF (ITYPE.EQ.-2) THEN
              CALL RPMC1(IRAY,-3)
              CALL RPSTOR('R',IRAY,KTRIS)
            ENDIF
            RETURN
          ELSE
            J2=KARAY(J1+1)
            J1=J1+2+J2
            IF (J1.GE.NARAY) THEN
C             RP3D-019
              CALL ERROR('RP3D-019: Error in RPAUX.')
C             This error should not appear.
C             Please contact the author or try to
C             change the input data.
            ENDIF
            GOTO 10
          ENDIF
        ENDIF
      ENDIF
C-----------------------------------------------------------------------
C
      ENTRY RPAUX2(ITRI,ISEQ,IRAY)
C
C-----------------------------------------------------------------------
C Entry designed to give the number of auxiliary rays terminating in
C triangle ITRI, or to give the index of the ISEQ-th auxiliary ray
C terminating in triangle ITRI, or to indicate, whether the ray IRAY is
C in register.
C Input:
C     ITRI... Index of a triangle or zero (when we are asking whether
C             the ray IRAY is in register).
C     ISEQ... Zero or the sequential index of a ray within triangle
C             ITRI.
C     IRAY... For ITRI=0: sign of the ray.
C Output:
C     ITRI... Zero if ray is not in register,otherwise index of triangle
C     IRAY... For ISEQ=0:... Number of auxiliary rays terminating in
C                            triangle ITRI.
C             For ISEQ.GT.0: index of the ISEQ-th auxiliary ray
C                            terminating in triangle ITRI, IRAY=0 if the
C                            number of auxiliary rays terminating in
C                            triangle ITRI is .LT. ISEQ.
C             FOR ITRI=0:... Sign of the ray.
C-----------------------------------------------------------------------
C
      IF (ITRI.EQ.0) THEN
        J1=2
  21    DO 22, I1=1,KARAY(J1)
          IF (KARAY(J1+I1).EQ.IRAY) THEN
            ITRI=KARAY(J1-1)
            RETURN
          ENDIF
  22    CONTINUE
        J1=J1+KARAY(J1)+2
        IF (J1.LT.NARAY) GOTO 21
        RETURN
      ENDIF
      J1=1
  30  IF (KARAY(J1).EQ.ITRI) THEN
        IF (ISEQ.EQ.0) THEN
          IRAY=KARAY(J1+1)
          RETURN
        ELSEIF (ISEQ.GT.KARAY(J1+1)) THEN
          IRAY=0
          RETURN
        ELSE
          IRAY=KARAY(J1+1+ISEQ)
          RETURN
        ENDIF
      ELSE
        J2=KARAY(J1+1)
        J1=J1+2+J2
        IF ((J1.GE.NARAY).AND.(ISEQ.EQ.0)) THEN
          IRAY=0
          RETURN
        ENDIF
        IF (J1.GE.NARAY) THEN
C         RP3D-020
          CALL ERROR('RP3D-020: Error in RPAUX.')
C         This error should not appear.
C         Please contact the author or try to
C         change the input data.
        ENDIF
        GOTO 30
      ENDIF
      END
C
C=======================================================================
C
      SUBROUTINE RPINTP(KTRIS,LNEWAR,IRAY,ITRI,LEND,
     *                  G1NEW,G2NEW,ITRNAR,ITYPEN)
C
C-----------------------------------------------------------------------
C Subroutine designed to search for two-point ray(s) inside homogeneous
C triangle with receiver(s) in its reference surface projection.
C Homogeneous triangle formed by not successful rays or without
C receivers in its reference surface projection will be marked as
C searched (type 4), as well as the triangle with all the two-point rays
C identified.
C Only the rays traced on request of RPINTP may be marked as
C two-point rays, thus any ray cannot be two-point ray for two or more
C receivers, and any basic or other ray cannot be later signed as
C two-point ray.
      INTEGER KTRIS(6),IRAY,ITRI,ITRNAR,ITYPEN
      REAL G1NEW,G2NEW
      LOGICAL LNEWAR,LEND
C Input:
C     KTRIS ..One column from KTRI (all parameters of the triangle
C             where we are searching for two-point rays).
C     LNEWAR..Indicates whether the new auxiliary ray have been computed
C     IRAY ...Index of last computed ray.
C     ITRI ...Index of last triangle.
C     LEND ...Indicates the end of the computation (all the normalized
C             ray domain covered by basic triangles).
C     ITRNAR..Unchanged output value from previous invocation,
C             if the new auxiliary ray was traced. Otherwise undefined.
C Output:
C     LNEWAR..Indicates whether the new auxiliary ray is to be computed.
C     G1NEW,G2NEW ... Normalized ray parameters of the new ray.
C     ITYPEN ...Itype of the new ray. For all new rays ITYPEN at first
C               equals -1000-IREC, ray tracer then computes the ray,
C               and RPMEM then makes decision whether the
C               ray is two-point ray and sets final ITYPE.
C     ITRNAR ...Index of the triangle containing the new auxiliary ray,
C               which will be actually traced.
C
C Subroutines and external functions required:
      EXTERNAL RPLRIT,LENGTH,RPDI2L
      INTEGER LENGTH
      REAL RPDI2L
      LOGICAL RPLRIT
C
C Coded by Petr Bulant
C
C.......................................................................
C
C Common blocks /GLIM/, /BOURA/ and /POLY/:
      INCLUDE 'rp3d.inc'
C     rp3d.inc
C............................
C
C Common block /RPARD/:
      INCLUDE 'rpard.inc'
C     rpard.inc
C     NREC... Number of receivers.
C     XREC... Receiver surface coordinates (x-coordinates along the
C             reference surface).
C     XERR... Maximum distance of the two-point ray from the receiver
C             at the reference surface.
C     AERR...Maximum distance of the boundary rays.
C None of the storage locations of the common block are altered.
C............................
C Common block /NST/:
C     Common block storing the ray, which was nearest to the current
C     receiver. If a two-point ray to the receiver cannot be found,
C     this ray is taken instead of the two-point ray and a warning is
C     generated to the logout file.
      REAL DISNST,G1NST,G2NST
      LOGICAL LNST
      COMMON/NST/LNST,DISNST
      SAVE/NST/
      SAVE G1NST,G2NST
C     G1NST,G2NST ... Parameters of a ray, which was nearest to the
C                     receiver being examined.
C     DISNST   ...    Distance of the ray from the receiver; DISNST=-1.
C                     indicates, that there is any nearest ray.
C     LNST     ...    Indicates, that the nearest ray is to be taken
C                     as a two-point ray in subroutine RPMEM.
C.......................................................................
C
      REAL ZERO,ZERO1
      PARAMETER (ZERO =.0000001)
      PARAMETER (ZERO1=.0000000001)
      INTEGER MTRIN
      PARAMETER (MTRIN=500)
      REAL VTRI(4,3),VTRIN(0:MTRIN,4,3)
      INTEGER NTRIN,INTRIN(0:MTRIN),KTRIN(0:MTRIN,3),ITTRIN(0:MTRIN,3)
      INTEGER MNOT
      PARAMETER (MNOT=20)
      INTEGER INOT,KNOT(MNOT)
      INTEGER IREC
      INTEGER INTERS,ISTART
      INTEGER NEAR1,NEAR2,NEAR3,INEAR
      INTEGER ITRIP,KTRIT(6)
      INTEGER ITYPE,ISHEET,ISH,ISHP
      INTEGER ITYPS(3),ICRTB(3),IB1,IB2,IB3,IB4,IBN
      REAL G1,G2,G11,G12,G22,X1,X2
      REAL G1X1,G2X1,G1X2,G2X2
      INTEGER ISHA
      REAL G1A,G2A,G1B,G2B,G1C,G2C
      REAL X1MIN,X1MAX,X2MIN,X2MAX
      REAL DG1,DG2,DX1,DX2
      REAL DIST1,DIST2
      REAL AREA,AREA1,AREA2,AREA3
      INTEGER I1,I2,I3,I4,I5,I6,I7,I8
      INTEGER J1,J2
      CHARACTER*14  FORMAT
      CHARACTER*240 TXTERR
      LOGICAL LTRI,LRAY,LINTS,LDISTG
      SAVE VTRI,VTRIN,NTRIN,INTRIN,KTRIN,ITTRIN,INOT,KNOT,IREC,
     *  ISTART,NEAR1,NEAR2,NEAR3,INEAR,ITRIP,X1MIN,X1MAX,X2MIN,X2MAX,
     *  DIST1,DG1,DG2,LDISTG
C     ZERO..Constant used to decide whether the real variable .EQ. zero.
C     MTRIN ..Maximum number of neighbouring triangles.
C     VTRI ...Vertices of triangle ITRIP:
C                VTRI(1,I) ... G1 of ray I   (I=1,2,3)
C                VTRI(2,I) ... G2 of ray I
C                VTRI(3,I) ... X1 of ray I
C                VTRI(4,I) ... X2 of ray I
C     VTRIN(J, ) ... Parameters of the vertices of J-th
C                    neighbouring triangle:
C                VTRIN(J,1,I) ... G1 of ray I   (I=1,2,3)
C                VTRIN(J,2,I) ... G2 of ray I
C                VTRIN(J,3,I) ... X1 of ray I
C                VTRIN(J,4,I) ... X2 of ray I
C     KTRIN(J,I) ...Indices of the vertices of J-th
C                   neighbouring triangle (I=1,2,3).
C     ITTRIN(J,I)...Types of the vertices of J-th neighbouring triangle.
C     NTRIN ..Number of neighbouring triangles.
C     INTRIN .Indices of neighbouring triangles.
C     MNOT,INOT,KNOT, ... Indices of the rays not suitable for
C             interpolation to actual receiver.
C     IREC ...Index of the receiver we are searching for.
C     INTERS..Counts intersection points.
C     ISTART..Counts from which nearest ray we start the interpolation.
C     INEAR ...  Number of rays to start interpolation.
C     NEAR1,2,3 .Signs of the rays nearest to the receiver.
C                Interpolation is started from these rays.
C     ITRIP ..Index of processed triangle.
C     KTRIT ..One column from KTRI (all parameters of the triangle
C             which we are testing).
C     ITYPE,ISHEET,ISH,G1,G2,G11,G12,G22,X1,X2 ...All parameters of ray.
C     G1X1,G2X1,G1X2,G2X2 .... Derivations.
C     ISHA,GIA,B,C,   ...      Auxiliary variables
C     X1MIN,X1MAX,X2MIN,X2MAX..Extremes of X1,X2 of triangle ITRIP.
C     DG1,DG2,DX1,DX2 ........ Differentials.
C     DIST1,2...  (distances of rays)**2
C     AREA1,2,3.. Auxiliary variables used when examining whether the
C                 ray lies in triangle.
C     I1,2,3..Implied-do variables or variables controlling the loop.
C     J1,2,3..Auxiliary variables (numbers).
C     LTRI ...Indicates whether the triangle ITRI is in memory.
C     LRAY ...Indicates whether the ray IRAY is in memory.
C     LINTS ..Indicates whether the intersection appeared.
C     LDISTG..Indicates that the distance was greater in interpolating
C             and the last ray was proposed as G1+DG1/2.
C-----------------------------------------------------------------------
C
      IF (LNEWAR) GOTO 50
      ITRIP=KTRIS(4)
      CALL RPRAY3(KTRIS(1),LRAY,ITYPS(1),ISHP,ICRTB(1),VTRI(1,1),
     *  VTRI(2,1),G11,G12,G22,VTRI(3,1),VTRI(4,1),G1X1,G2X1,G1X2,G2X2)
      IF (.NOT.LRAY) CALL RPERR(1)
      CALL RPRAY3(KTRIS(2),LRAY,ITYPS(2),ISHEET,ICRTB(2),VTRI(1,2),
     *  VTRI(2,2),G11,G12,G22,VTRI(3,2),VTRI(4,2),G1X1,G2X1,G1X2,G2X2)
      IF (.NOT.LRAY) CALL RPERR(1)
      CALL RPRAY3(KTRIS(3),LRAY,ITYPS(3),ISHEET,ICRTB(3),VTRI(1,3),
     *  VTRI(2,3),G11,G12,G22,VTRI(3,3),VTRI(4,3),G1X1,G2X1,G1X2,G2X2)
      IF (.NOT.LRAY) CALL RPERR(1)
C
C     Triangles by the boundary of covered part of the ray domain:
      IF (.NOT.LEND) THEN
        DO 2, I2=1,NPL
          IF ((KTRIS(1).EQ.KPL(I2)).OR.
     *        (KTRIS(2).EQ.KPL(I2)).OR.
     *        (KTRIS(3).EQ.KPL(I2))) RETURN
  2     CONTINUE
        J1=0
        IF (NBR.GT.2) THEN
  4     CONTINUE
          DO 6, I2=J1+4,J1+3+KBR(J1+3,1)
            IF ((KTRIS(1).EQ.KBR(I2,1)).OR.
     *          (KTRIS(2).EQ.KBR(I2,1)).OR.
     *          (KTRIS(3).EQ.KBR(I2,1))) RETURN
  6       CONTINUE
          J1=J1+KBR(J1+3,1)+3
        IF (J1.LT.NBR) GOTO 4
        ENDIF
      ENDIF
C
C     Recording the triangle to the file CRT-T:
      CALL WRITTR(KTRIS(1),KTRIS(2),KTRIS(3))
C
      IF ((ISHP.LT.0).AND.
     *    (.NOT.(((ITYPS(1).GT.0).AND.(ICRTB(1).EQ.0)).OR.
     *           ((ITYPS(2).GT.0).AND.(ICRTB(2).EQ.0)).OR.
     *           ((ITYPS(3).GT.0).AND.(ICRTB(3).EQ.0))))) THEN
C       These rays do not end on the reference surface, receivers
C       cannot lie here, and no boundary rays to store to CRT-B:
        KTRIS(6)=4
        CALL RPTRI2(ITRIP,LTRI,KTRIS)
        IF (.NOT.LTRI) CALL RPERR(2)
        RETURN
      ENDIF
C
C     Now searching for neighbouring homogeneous triangles.
      NTRIN=0
      INTRIN(0)=ITRIP
      KTRIN(NTRIN,  1)=KTRIS( 1)
      ITTRIN(NTRIN, 1)=ITYPS( 1)
      VTRIN(NTRIN,1,1)=VTRI(1,1)
      VTRIN(NTRIN,2,1)=VTRI(2,1)
      VTRIN(NTRIN,3,1)=VTRI(3,1)
      VTRIN(NTRIN,4,1)=VTRI(4,1)
      KTRIN(NTRIN,  2)=KTRIS( 2)
      ITTRIN(NTRIN, 2)=ITYPS( 2)
      VTRIN(NTRIN,1,2)=VTRI(1,2)
      VTRIN(NTRIN,2,2)=VTRI(2,2)
      VTRIN(NTRIN,3,2)=VTRI(3,2)
      VTRIN(NTRIN,4,2)=VTRI(4,2)
      KTRIN(NTRIN,  3)=KTRIS( 3)
      ITTRIN(NTRIN, 3)=ITYPS( 3)
      VTRIN(NTRIN,1,3)=VTRI(1,3)
      VTRIN(NTRIN,2,3)=VTRI(2,3)
      VTRIN(NTRIN,3,3)=VTRI(3,3)
      VTRIN(NTRIN,4,3)=VTRI(4,3)
      CALL RPTRIP(1,LTRI,KTRIT)
C     Loop for all the triangles in the memory:
  8   CONTINUE
        CALL RPTRIP(0,LTRI,KTRIT)
        IF (LTRI) THEN
          IF (((KTRIT(6).EQ.3).OR.(KTRIT(6).EQ.4)).AND.
     *        (KTRIT(4).NE.ITRIP)) THEN
            IF (((KTRIT(1).EQ.KTRIS(1)).OR.(KTRIT(1).EQ.KTRIS(2)).OR.
     *           (KTRIT(1).EQ.KTRIS(3))).OR.
     *          ((KTRIT(2).EQ.KTRIS(1)).OR.(KTRIT(2).EQ.KTRIS(2)).OR.
     *           (KTRIT(2).EQ.KTRIS(3))).OR.
     *          ((KTRIT(3).EQ.KTRIS(1)).OR.(KTRIT(3).EQ.KTRIS(2)).OR.
     *           (KTRIT(3).EQ.KTRIS(3)))) THEN
              DO 9, I2=1,NTRIN
                IF (KTRIT(4).EQ.INTRIN(I2)) GOTO 8
  9           CONTINUE
              NTRIN=NTRIN+1
              IF (NTRIN.GT.MTRIN) THEN
C               RP3D-021
                CALL ERROR
     * ('RP3D-021: Insufficient memory for the neighbouring triangles.')
C               This error may be caused by too small dimension of array
C               KTRIN. Try to enlarge the parameter MTRIN at the
C               beginning of this subroutine.
              ENDIF
              KTRIN(NTRIN,1)=KTRIT(1)
              CALL RPRAY(KTRIT(1),LRAY,ITTRIN(NTRIN,1),ISHEET,
     *          VTRIN(NTRIN,1,1),VTRIN(NTRIN,2,1),G11,G12,G22,
     *          VTRIN(NTRIN,3,1),VTRIN(NTRIN,4,1),G1X1,G2X1,G1X2,G2X2)
              IF (.NOT.LRAY) CALL RPERR(1)
              KTRIN(NTRIN,2)=KTRIT(2)
              CALL RPRAY(KTRIT(2),LRAY,ITTRIN(NTRIN,2),ISHEET,
     *          VTRIN(NTRIN,1,2),VTRIN(NTRIN,2,2),G11,G12,G22,
     *          VTRIN(NTRIN,3,2),VTRIN(NTRIN,4,2),G1X1,G2X1,G1X2,G2X2)
              IF (.NOT.LRAY) CALL RPERR(1)
              KTRIN(NTRIN,3)=KTRIT(3)
              CALL RPRAY(KTRIT(3),LRAY,ITTRIN(NTRIN,3),ISHEET,
     *          VTRIN(NTRIN,1,3),VTRIN(NTRIN,2,3),G11,G12,G22,
     *          VTRIN(NTRIN,3,3),VTRIN(NTRIN,4,3),G1X1,G2X1,G1X2,G2X2)
              IF (.NOT.LRAY) CALL RPERR(1)
              INTRIN(NTRIN)=KTRIT(4)
            ENDIF
          ENDIF
          GOTO 8
        ENDIF
C     End of the loop for all the triangles in the memory.
C
C     Recording the boundary rays to the file CRT-B:
      DO 18, I1=1,3
        IF ((ITYPS(I1).GT.0).AND.(ICRTB(I1).EQ.0)) THEN
C         Boundary ray IB1=KTRIS(I1) to be recorded to CRT-B:
          IB1=KTRIS(I1)
          IB2=ITYPS(I1)
          IB3=0
          IB4=0
C         Storing history of the ray IB2 to I4:
          CALL RPRAY(IB2,LRAY,ITYPE,I4,G1,G2,
     *             G11,G12,G22,X1,X2,G1X1,G2X1,G1X2,G2X2)
          IF (.NOT.LRAY) CALL RPERR(1)
C         Loop over all rays of the neighbouring triangles:
          DO 14, I2=0,NTRIN
            DO 12, I3=1,3
              I5=I3-1
              IF (I5.EQ.0) I5=3
              I6=I3+1
              IF (I6.EQ.4) I6=1
              IF ((ITTRIN(I2,I3).GT.0).AND.
     *            (KTRIN(I2,I3).NE.IB1).AND.
     *            ((KTRIN(I2,I5).EQ.IB1).OR.(KTRIN(I2,I6).EQ.IB1))) THEN
C               Boundary ray IBN different from IB1 found:
                IBN=KTRIN(I2,I3)
                CALL RPRAY(ITTRIN(I2,I3),LRAY,ITYPE,ISHEET,G1,G2,
     *             G11,G12,G22,X1,X2,G1X1,G2X1,G1X2,G2X2)
                IF (.NOT.LRAY) CALL RPERR(1)
                IF (ISHEET.EQ.I4) THEN
C                 The boundary ray corresponding to the boundary
C                 ray IBN is of the same history as the ray IB2.
C                 Now looking, whether the side [IB1,IBN] is
C                 contained only once within the set of neighbouring
C                 triangles:
                  DO 11, I7=0,NTRIN
                    IF (I7.EQ.I2) GOTO 11
                    IF (((IB1.EQ.KTRIN(I7,1)).OR.(IB1.EQ.KTRIN(I7,2))
     *               .OR.(IB1.EQ.KTRIN(I7,3))).AND.
     *                  ((IBN.EQ.KTRIN(I7,1)).OR.(IBN.EQ.KTRIN(I7,2))
     *               .OR.(IBN.EQ.KTRIN(I7,3)))) THEN
C                     The side [IB1,IBN] is contained within triangles
C                     INTRIN(I2) and INTRIN(I7).  Such side is not
C                     located at the boundary of the ray history, and
C                     cannot be used.
                      GOTO 12
                    ENDIF
  11              CONTINUE
C                 The ray IBN may be used as the ray IB3 or IB4:
                  IF ((IB3.EQ.0).OR.(IB3.EQ.IBN)) THEN
                    IB3=IBN
                  ELSEIF ((IB4.EQ.0).OR.(IB4.EQ.IBN)) THEN
                    IB4=IBN
                  ELSE
C                   Three mutually different boundary rays IB3, IB4
C                   and IBN found.
                    IF (RPDI2L(IB3,IB1,IB4).GT.16*AERR**2) THEN
C                     Boundary demarcated by IB3,IB1,IB4 is too curved:
                      IF     (RPDI2L(IBN,IB1,IB4).LE.16*AERR**2) THEN
C                       Boundary demarcated by IBN,IB1,IB4 is OK:
                        IB3=IBN
                      ELSEIF (RPDI2L(IB3,IB1,IBN).LE.16*AERR**2) THEN
C                       Boundary demarcated by IB3,IB1,IBN is OK:
                        IB4=IBN
                      ENDIF
                    ENDIF
                  ENDIF
                ENDIF
              ENDIF
  12        CONTINUE
  14      CONTINUE
  16      CONTINUE
C         IF (IB3.EQ.0) THEN
C           No neighbouring boundary ray found.
C         ENDIF
          IF (IB4.NE.0) THEN
C           Checking the curvature of the boundary:
            IF (RPDI2L(IB3,IB1,IB4).GT.16*AERR**2) THEN
              IB3=0
              IB4=0
            ENDIF
          ENDIF
          CALL WRITBR(IB1,IB2,IB3,IB4)
          CALL RPMC2(IB1,1)
        ENDIF
  18  CONTINUE
C
      IF (ISHP.LT.0) THEN
C       These rays do not end on the reference surface, receivers
C       cannot lie here:
        KTRIS(6)=4
        CALL RPTRI2(ITRIP,LTRI,KTRIS)
        IF (.NOT.LTRI) CALL RPERR(2)
        RETURN
      ENDIF
C
C     Searching for receivers, lying (on reference surface)
C     in triangle ITRIP:
      IREC=1
      X1MIN=AMIN1(VTRI(3,1),VTRI(3,2),VTRI(3,3))
      X1MAX=AMAX1(VTRI(3,1),VTRI(3,2),VTRI(3,3))
      X2MIN=AMIN1(VTRI(4,1),VTRI(4,2),VTRI(4,3))
      X2MAX=AMAX1(VTRI(4,1),VTRI(4,2),VTRI(4,3))
  20  INOT=0
      IF ((XREC(1,IREC).LT.X1MIN).OR.(XREC(1,IREC).GT.X1MAX).OR.
     *    (XREC(2,IREC).LT.X2MIN).OR.(XREC(2,IREC).GT.X2MAX)) THEN
        IREC=IREC+1
        IF (IREC.LE.NREC) GOTO 20
        GOTO 200
      ENDIF
      AREA1=(VTRI(3,2)-XREC(1,IREC))*(VTRI(4,3)-XREC(2,IREC))-
     *      (VTRI(3,3)-XREC(1,IREC))*(VTRI(4,2)-XREC(2,IREC))
      IF (ABS(AREA1).LT.ZERO1) AREA1=0.
      AREA2=(VTRI(3,3)-XREC(1,IREC))*(VTRI(4,1)-XREC(2,IREC))-
     *      (VTRI(3,1)-XREC(1,IREC))*(VTRI(4,3)-XREC(2,IREC))
      IF (ABS(AREA2).LT.ZERO1) AREA2=0.
      AREA3=(VTRI(3,1)-XREC(1,IREC))*(VTRI(4,2)-XREC(2,IREC))-
     *      (VTRI(3,2)-XREC(1,IREC))*(VTRI(4,1)-XREC(2,IREC))
      IF (ABS(AREA3).LT.ZERO1) AREA3=0.
      IF (((AREA1.LT.0.).OR.(AREA2.LT.0.).OR.(AREA3.LT.0.)).AND.
     *    ((AREA1.GT.0.).OR.(AREA2.GT.0.).OR.(AREA3.GT.0.))) THEN
        IREC=IREC+1
        IF (IREC.LE.NREC) GOTO 20
        GOTO 200
      ENDIF
C
C     Controlling, whether two-point ray has not yet been found:
      CALL RPRAY(KTRIS(1),LRAY,ITYPE,ISHEET,G1,G2,
     *               G11,G12,G22,X1,X2,G1X1,G2X1,G1X2,G2X2)
      IF (.NOT.LRAY) CALL RPERR(1)
      CALL RPRAYP(5,LRAY,I1,ITYPE,ISH,G1,G2,
     *               G11,G12,G22,X1,X2,G1X1,G2X1,G1X2,G2X2)
C     Loop for all the rays in the memory:
  26  CONTINUE
        CALL RPRAYP(0,LRAY,I1,ITYPE,ISH,G1,G2,
     *               G11,G12,G22,X1,X2,G1X1,G2X1,G1X2,G2X2)
        IF (LRAY) THEN
          IF ((ITYPE.EQ.(-1000-IREC)).AND.(ISH.EQ.ISHEET)) THEN
C           Two-point ray with this ISHEET is already found.  Now
C           examining, whether it starts in triangles being considered:
            IF (RPLRIT(.TRUE.,VTRI(1,1),VTRI(2,1),VTRI(1,2),
     *          VTRI(2,2),VTRI(1,3),VTRI(2,3),G1,G2,AREA)) THEN
C             Two-point ray starts in tested triangle,continuing with
C             the next receiver:
              IREC=IREC+1
              IF (IREC.LE.NREC) GOTO 20
              GOTO 200
            ENDIF
            DO 28, I2=1,NTRIN
              IF (RPLRIT(.TRUE.,
     *            VTRIN(I2,1,1),VTRIN(I2,2,1),VTRIN(I2,1,2)
     *           ,VTRIN(I2,2,2),VTRIN(I2,1,3),VTRIN(I2,2,3)
     *           ,G1,G2,AREA)) THEN
C               Two-point ray starts in neighbouring triangle,
C               continuing with the next receiver:
                IREC=IREC+1
                IF (IREC.LE.NREC) GOTO 20
                GOTO 200
              ENDIF
  28        CONTINUE
          ENDIF
          GOTO 26
        ENDIF
C     End of the loop for all the rays in the memory.
C
C     Receiver IREC lies (on ref. surface) in triangle ITRIP.
      DISNST=-1.
C     Now searching for 3 rays nearest to the receiver:
C     Searching among auxiliary rays:
  30  CONTINUE
      INEAR=0
      CALL RPAUX2(ITRIP,0,J1)
      DO 32, I1=1,J1
        CALL RPAUX2(ITRIP,I1,J2)
        DO 31, I3=1,INOT
          IF (J2.EQ.KNOT(I3)) GOTO 32
  31    CONTINUE
        CALL RPRAY(J2,LRAY,ITYPE,ISHEET,G1,G2,G11,G12,G22,X1,X2,
     *             G1X1,G2X1,G1X2,G2X2)
        IF (.NOT.LRAY) CALL RPERR(1)
        DIST2=(X1-XREC(1,IREC))**2 +(X2-XREC(2,IREC))**2
        IF ((DIST2.LT.DIST1).OR.(INEAR.EQ.0)) THEN
          NEAR3=NEAR2
          NEAR2=NEAR1
          NEAR1=J2
          DIST1=DIST2
          IF (INEAR.LT.3) INEAR=INEAR+1
        ENDIF
  32  CONTINUE
C     Searching among vertices of the triangle:
      DO 33, I1=1,3
        J2=KTRIS(I1)
        DO 37, I3=1,INOT
          IF (J2.EQ.KNOT(I3)) GOTO 33
  37    CONTINUE
        CALL RPRAY(J2,LRAY,ITYPE,ISHEET,G1,G2,G11,G12,G22,X1,X2,
     *             G1X1,G2X1,G1X2,G2X2)
        IF (.NOT.LRAY) CALL RPERR(1)
        DIST2=(X1-XREC(1,IREC))**2 +(X2-XREC(2,IREC))**2
        IF ((DIST2.LT.DIST1).OR.(INEAR.EQ.0)) THEN
          NEAR3=NEAR2
          NEAR2=NEAR1
          NEAR1=J2
          DIST1=DIST2
          IF (INEAR.LT.3) INEAR=INEAR+1
        ENDIF
  33  CONTINUE
C     Searching also in neighbouring triangles:
      DO 36, I1=1,NTRIN
        CALL RPAUX2(INTRIN(I1),0,J1)
        DO 34, I2=1,J1
          CALL RPAUX2(INTRIN(I1),I2,J2)
          DO 38, I3=1,INOT
            IF (J2.EQ.KNOT(I3)) GOTO 34
  38      CONTINUE
          CALL RPRAY(J2,LRAY,ITYPE,ISHEET,G1,G2,G11,G12,G22,X1,X2,
     *               G1X1,G2X1,G1X2,G2X2)
          IF (.NOT.LRAY) CALL RPERR(1)
          DIST2=(X1-XREC(1,IREC))**2 +(X2-XREC(2,IREC))**2
          IF (DIST2.LT.DIST1) THEN
            NEAR3=NEAR2
            NEAR2=NEAR1
            NEAR1=J2
            DIST1=DIST2
            IF (INEAR.LT.3) INEAR=INEAR+1
          ENDIF
  34    CONTINUE
        DO 35, I2=1,3
          J2=KTRIN(I1,I2)
          DO 39, I3=1,INOT
            IF (J2.EQ.KNOT(I3)) GOTO 35
  39      CONTINUE
          CALL RPRAY(J2,LRAY,ITYPE,ISHEET,G1,G2,G11,G12,G22,X1,X2,
     *               G1X1,G2X1,G1X2,G2X2)
          IF (.NOT.LRAY) CALL RPERR(1)
          DIST2=(X1-XREC(1,IREC))**2 +(X2-XREC(2,IREC))**2
          IF (DIST2.LT.DIST1) THEN
            NEAR3=NEAR2
            NEAR2=NEAR1
            NEAR1=J2
            DIST1=DIST2
            IF (INEAR.LT.3) INEAR=INEAR+1
          ENDIF
  35    CONTINUE
  36  CONTINUE
      IF (INEAR.EQ.0) THEN
        IF (DISNST.NE.-1.) THEN
C         The nearest ray will be taken as a two-point ray:
          G1NEW=G1NST
          G2NEW=G2NST
          DIST1=DISNST
          LNST=.TRUE.
          LDISTG=.FALSE.
          GOTO 90
        ELSE
C         RP3D-032
          WRITE(TXTERR,'(2A,1I6,A,1I6)')
     *    'Error RP3D-032: There is no ray to start the interpolation',
     *    ' of a two-point ray of history ',ISHEET,
     *    ' to the receiver ',IREC
          CALL ERROR(TXTERR(1:LENGTH(TXTERR)))
C         This error should not appear.
        ENDIF
        IREC=IREC+1
        IF (IREC.LE.NREC) GOTO 20
        GOTO 200
      ENDIF
C
C
C     Start of interpolation (from NEAR1):
      ISTART=1
  40  IF ((ISTART.EQ.1).AND.(ISTART.LE.INEAR)) THEN
        CALL RPRAY(NEAR1,LRAY,ITYPE,ISHEET,G1,G2,G11,G12,G22,X1,X2,
     *             G1X1,G2X1,G1X2,G2X2)
        IF (DISNST.EQ.-1.) THEN
C         Noting the nearest ray for the case that no better ray
C         will be found:
          DISNST=DIST1
          G1NST=G1
          G2NST=G2
        ENDIF
      ELSEIF ((ISTART.EQ.2).AND.(ISTART.LE.INEAR)) THEN
        CALL RPRAY(NEAR2,LRAY,ITYPE,ISHEET,G1,G2,G11,G12,G22,X1,X2,
     *             G1X1,G2X1,G1X2,G2X2)
      ELSEIF ((ISTART.EQ.3).AND.(ISTART.LE.INEAR)) THEN
        CALL RPRAY(NEAR3,LRAY,ITYPE,ISHEET,G1,G2,G11,G12,G22,X1,X2,
     *             G1X1,G2X1,G1X2,G2X2)
      ELSE
C       Deleting unneeded auxiliary rays from register
C       of auxiliary rays:
        IF (INEAR.GE.1) THEN
          INOT=INOT+1
          IF (INOT.GE.MNOT) THEN
            IREC=IREC+1
            IF (IREC.LE.NREC) GOTO 20
            GOTO 200
          ENDIF
          KNOT(INOT)=NEAR1
        ENDIF
        IF (INEAR.GE.2) THEN
          INOT=INOT+1
          IF (INOT.GE.MNOT) THEN
            IREC=IREC+1
            IF (IREC.LE.NREC) GOTO 20
            GOTO 200
          ENDIF
          KNOT(INOT)=NEAR2
        ENDIF
        IF (INEAR.GE.3) THEN
          INOT=INOT+1
          IF (INOT.GE.MNOT) THEN
            IREC=IREC+1
            IF (IREC.LE.NREC) GOTO 20
            GOTO 200
          ENDIF
          KNOT(INOT)=NEAR3
        ENDIF
        GOTO 30
      ENDIF
      IF (.NOT.LRAY) CALL RPERR(1)
      DX1=XREC(1,IREC)-X1
      DX2=XREC(2,IREC)-X2
      DG1=G1X1*DX1+G1X2*DX2
      DG2=G2X1*DX1+G2X2*DX2
      G1NEW=G1+DG1
      G2NEW=G2+DG2
      DIST1=(X1-XREC(1,IREC))**2 +(X2-XREC(2,IREC))**2
      LDISTG=.FALSE.
      GOTO 90
C
C
  50  CALL RPRAY(IRAY,LRAY,ITYPE,ISHEET,G1,G2,G11,G12,G22,X1,X2,
     *           G1X1,G2X1,G1X2,G2X2)
      IF (.NOT.LRAY) CALL RPERR(1)
C
      IF (ISHEET.LT.0) THEN
C       This may happen, when the ray starts in a triangle formed
C       by unsuccessful rays and is of the same history as the rays
C       of the triangle.
C       Start of interpolation from other ray:
        ISTART=ISTART+1
        GOTO 40
      ENDIF
C
      IF ((ITYPE.LT.-1000).OR.(LNST)) THEN
        IF (ITYPE.LT.-1000) THEN
C         The ray IRAY is two-point ray !
          CALL RPAUX1(ITRNAR,IRAY)
        ENDIF
        LNST=.FALSE.
        LNEWAR=.FALSE.
C       End of interpolation for this receiver:
        IREC=IREC+1
        IF (IREC.LE.NREC) GOTO 20
        GOTO 200
      ENDIF
C
      DIST2=(X1-XREC(1,IREC))**2 +(X2-XREC(2,IREC))**2
      IF (DIST2.GE.DIST1) THEN
        IF (.NOT.LDISTG) THEN
          DG1=-DG1*.5
          DG2=-DG2*.5
          G1NEW=G1+DG1
          G2NEW=G2+DG2
          LDISTG=.TRUE.
          GOTO 90
        ENDIF
        ISTART=ISTART+1
        GOTO 40
      ELSE
        IF (DIST2.LT.DISNST) THEN
C         Noting the nearest ray for the case that no better ray
C         will be found:
          DISNST=DIST2
          G1NST=G1
          G2NST=G2
        ENDIF
        DX1=XREC(1,IREC)-X1
        DX2=XREC(2,IREC)-X2
        DG1=G1X1*DX1+G1X2*DX2
        DG2=G2X1*DX1+G2X2*DX2
        G1NEW=G1+DG1
        G2NEW=G2+DG2
        DIST1=DIST2
        LDISTG=.FALSE.
C       Go to label 90.
      ENDIF
C
C     Now verifying, whether the new ray lies in the triangle or
C     in neighbouring triangles:
  90  CONTINUE
      IF ((ABS (DG1).LT.ZERO).AND.(ABS(DG2).LT.ZERO).AND.
     *     (.NOT.LNST)) THEN
C       RP3D-033
        FORMAT='(2A,1I6,A,1I6)'
        I8=INT(ALOG10(FLOAT(ISHEET)))+1
        FORMAT(7:7)=CHAR(ICHAR('0')+I8)
        I8=INT(ALOG10(FLOAT(IREC)))+1
        FORMAT(13:13)=CHAR(ICHAR('0')+I8)
        WRITE(TXTERR,FORMAT)
     *  'RP3D-033: Differences DG1, DG2 equal to zero',
     *  ' when searching for a two-point ray of history ',ISHEET,
     *  ' to the receiver ',IREC
        CALL WARN(TXTERR(1:LENGTH(TXTERR)))
C       Parameters of a new ray proposed as
C                         new ray = old ray +DGi
C       are computed here in order to find a two-point ray.
C       Small differences DGi indicate inconsistency between the
C       geometrical spreading of computed rays and values of input data
C       (e.g. too small XERR, too big STEP, ... ).
C       Input data RPAR.
C       Input data DCRT.
C       Start of interpolation from other ray:
        ISTART=ISTART+1
        GOTO 40
      ENDIF
      IF (RPLRIT(.TRUE.,VTRI(1,1),VTRI(2,1),VTRI(1,2),
     *    VTRI(2,2),VTRI(1,3),VTRI(2,3),G1NEW,G2NEW,AREA)) THEN
C       Auxiliary ray starts in tested triangle:
        ITYPEN=-1000-IREC
        ITRNAR=ITRIP
        LNEWAR=.TRUE.
        RETURN
      ENDIF
      DO 92, I1=1,NTRIN
        IF (RPLRIT(.TRUE.,VTRIN(I1,1,1),VTRIN(I1,2,1),VTRIN(I1,1,2),
     *      VTRIN(I1,2,2),VTRIN(I1,1,3),VTRIN(I1,2,3),
     *      G1NEW,G2NEW,AREA)) THEN
C         Auxiliary ray starts in neighbouring triangle:
          ITYPEN=-1000-IREC
          ITRNAR=INTRIN(I1)
          LNEWAR=.TRUE.
          RETURN
        ENDIF
  92  CONTINUE
C     Now verifying, whether the new ray lies in the part of domain
C     covered by basic triangles:
      IF (G1NEW.LT.GLIMIT(1)) THEN
        G1NEW=GLIMIT(1)
        GOTO 90
      ENDIF
      IF (G1NEW.GT.GLIMIT(2)) THEN
        G1NEW=GLIMIT(2)
        GOTO 90
      ENDIF
      IF (G2NEW.LT.GLIMIT(3)) THEN
        G2NEW=GLIMIT(3)
        GOTO 90
      ENDIF
      IF (G2NEW.GT.GLIMIT(4)) THEN
        G2NEW=GLIMIT(4)
        GOTO 90
      ENDIF
C     Testing whether the abscissa
C [(ray with parameters G1NEW,G2MIN),(ray with parameters G1NEW,G2NEW)]
C     has intersection with some abscissa of polyline.
      INTERS=0
      DO 94, I1=1,NPL-1
        CALL RPRAY(KPL(I1),LRAY,ITYPE,ISH,G1A,G2A,G11,G12,G22,
     *             X1,X2,G1X1,G2X1,G1X2,G2X2)
        IF (.NOT.LRAY) CALL RPERR(1)
        CALL RPRAY(KPL(I1+1),LRAY,ITYPE,ISH,G1B,G2B,G11,G12,G22,
     *             X1,X2,G1X1,G2X1,G1X2,G2X2)
        IF (.NOT.LRAY) CALL RPERR(1)
        G1C=G1NEW
        G2C=GLIMIT(3)
C       ..A,..B ... 'indices' of rays of tested polyline abscissa.
C       ..C,..NEW.. 'indices' of rays of tested abscissa.
        CALL RPCROS(G1C,G2C,G1NEW,G2NEW,G1A,G2A,G1B,G2B,LINTS,G1A,G2A)
        IF (LINTS) INTERS=INTERS+1
  94  CONTINUE
      IF (AMOD(REAL(INTERS),2.).NE.0.) THEN
C       Auxiliary ray does not start in the part of domain covered
C       by basic triangles:
        ITRNAR=0
        IF (.NOT.LDISTG) THEN
          DG1=DG1*.5
          DG2=DG2*.5
          G1NEW=G1+DG1
          G2NEW=G2+DG2
          LDISTG=.TRUE.
          GOTO 90
        ENDIF
        ISTART=ISTART+1
        GOTO 40
      ENDIF
C     Auxiliary ray starts in the part
C     of domain covered by basic triangles:
      CALL RPTRIP(-ITRI,LTRI,KTRIT)
C     Loop for all the triangles in the memory:
  101 CONTINUE
        CALL RPTRIP(0,LTRI,KTRIT)
        IF (LTRI) THEN
          IF (KTRIT(4).EQ.ITRIP) GOTO 101
          IF (KTRIT(6).NE.3) GOTO 101
          DO 102, I2=1,NTRIN
            IF (KTRIT(4).EQ.INTRIN(I2)) GOTO 101
  102     CONTINUE
          CALL RPRAY(KTRIT(1),LRAY,ITYPE,ISHA,G1A,G2A,
     *              G11,G12,G22,X1,X2,G1X1,G2X1,G1X2,G2X2)
          IF (.NOT.LRAY) CALL RPERR(1)
          CALL RPRAY(KTRIT(2),LRAY,ITYPE,ISH,G1B,G2B,
     *              G11,G12,G22,X1,X2,G1X1,G2X1,G1X2,G2X2)
          IF (.NOT.LRAY) CALL RPERR(1)
          CALL RPRAY(KTRIT(3),LRAY,ITYPE,ISH,G1C,G2C,
     *              G11,G12,G22,X1,X2,G1X1,G2X1,G1X2,G2X2)
          IF (.NOT.LRAY) CALL RPERR(1)
          IF (RPLRIT(.TRUE.,G1A,G2A,G1B,G2B,G1C,G2C,
     *               G1NEW,G2NEW,AREA)) THEN
C           Auxiliary ray starts in this triangle.
C           Controlling, whether two-point ray has not yet been found:
            CALL RPRAYP(5,LRAY,I1,ITYPE,ISH,G1,G2,
     *                  G11,G12,G22,X1,X2,G1X1,G2X1,G1X2,G2X2)
C           Loop for all the rays in the memory:
  104       CONTINUE
              CALL RPRAYP(0,LRAY,I2,ITYPE,ISH,G1,G2,
     *                    G11,G12,G22,X1,X2,G1X1,G2X1,G1X2,G2X2)
              IF (LRAY) THEN
                IF ((ITYPE.EQ.(-1000-IREC)).AND.(ISH.EQ.ISHA)) THEN
C                 Two-point ray with this ISHEET is already found.  Now
C                 examining, whether it starts in this triangle:
                  IF (RPLRIT(.TRUE.,G1A,G2A,G1B,G2B,G1C,G2C,
     *                       G1,G2,AREA)) THEN
C                   Two-point ray starts in tested triangle,continuing
C                   with the next receiver:
                    IREC=IREC+1
                    IF (IREC.LE.NREC) GOTO 20
                    GOTO 200
                  ENDIF
                ENDIF
                GOTO 104
              ENDIF
C           End of the loop for all the rays in the memory.
            ITRNAR=KTRIT(4)
            ITYPEN=-1000-IREC
            LNEWAR=.TRUE.
            RETURN
          ENDIF
          GOTO 101
        ENDIF
C     End of the loop for all the triangles in the memory.
C
C     Auxiliary ray starts neither in the triangle nor
C     in the neighbouring triangles, but it starts in the part
C     of domain covered by basic triangles:
      ITRNAR=0
      IF (.NOT.LDISTG) THEN
        DG1=DG1*.5
        DG2=DG2*.5
        G1NEW=G1+DG1
        G2NEW=G2+DG2
        LDISTG=.TRUE.
        GOTO 90
      ENDIF
      ISTART=ISTART+1
      GOTO 40
C
C     No other receivers lying in triangle ITRIP. End of interpolation.
  200 CONTINUE
      KTRIS(6)=4
      CALL RPTRI2(ITRIP,LTRI,KTRIS)
      LNEWAR=.FALSE.
      RETURN
      END
C
C=======================================================================
C
      SUBROUTINE RPERAS
C
C----------------------------------------------------------------------
C
C Subroutine designed to delete unneeded triangles and rays from memory.
C
C No input
C No output
C
C Subroutines and external functions required:
C
C Coded by Petr Bulant
C
C.......................................................................
C
C Common blocks /GLIM/, /POLY/, /BOURA/, /TRIAN/, /AUXER/ and /RAY/:
      INCLUDE 'rp3d.inc'
C     rp3d.inc
C.......................................................................
      REAL ZERO
      PARAMETER (ZERO =.0000001)
      INTEGER MREC
      PARAMETER (MREC=1024)
      INTEGER KTRIS(6)
      INTEGER ITYPE,ISH
      REAL G1,G2,G11,G12,G22,X1,X2,G1X1,G2X1,G1X2,G2X2
      REAL G2MI
      INTEGER I1,I2,I3,I4
      INTEGER J1,J2
      LOGICAL LERASE,LRAY
C     ZERO ...Constant used to decide whether the real variable.EQ.zero.
C     MAUAR...Maximum number of rays in KAUAR.
C     NAUAR...Number of rays in KAUAR.
C     KAUAR...Array with indices of rays which are not to be erased.
C     MREC ...Maximum number of receivers in the memory.
C     KTRIS...All parameters of the triangle to be erased.
C     G2MI .. Minimum of G2 of all the rays on the polyline.
C     I1,2,3,4..Implied-do variables or variables controlling the loop.
C     J1,J2 ...  Auxiliary variables (numbers).
C     LERASE... Indicates whether the part of the KBR being processed
C               is to be erased.
C     LRAY  ... Indicates whether the ray is in the memory.
C----------------------------------------------------------------------
C
C     First rays - return without erasing:
      IF (NPL.EQ.0) THEN
        RETURN
      ENDIF
C
C     Deleting unneeded rays in array KBR:
      G2MI=GLIMIT(4)
      DO 5, I1=2,NPL-1
        CALL RPRAY(KPL(I1),LRAY,ITYPE,ISH,G1,G2,G11,G12,G22,
     *           X1,X2,G1X1,G2X1,G1X2,G2X2)
        IF (.NOT.LRAY) CALL RPERR(1)
        IF (G2.LT.G2MI) G2MI=G2
  5   CONTINUE
      IF (G2MI.LE.GLIMIT(3)) GOTO 13
      LERASE=.FALSE.
      IF (NBR.EQ.0) GOTO 13
      J1=0
      IF (NBR.GT.2) THEN
  10  CONTINUE
        IF ((KBR(J1+2,1).EQ.KPL(2)).OR.(KBR(J1+1,1).EQ.KPL(NPL-1)))
     *    LERASE=.TRUE.
        IF (.NOT.LERASE) THEN
          CALL RPRAY(KBR(J1+1,1),LRAY,ITYPE,ISH,G1,G2,G11,G12,G22,
     *               X1,X2,G1X1,G2X1,G1X2,G2X2)
          IF (.NOT.LRAY) CALL RPERR(1)
          IF (G2.LT.G2MI-ZERO) LERASE=.TRUE.
        ENDIF
        IF (LERASE) THEN
          J2=KBR(J1+3,1)+3
          NBR=NBR-J2
          DO 12, I1=J1+1,NBR
            KBR(I1,1)=KBR(I1+J2,1)
            KBR(I1,2)=KBR(I1+J2,2)
            KBR(I1,3)=KBR(I1+J2,3)
            GBR(I1,1)=GBR(I1+J2,1)
            GBR(I1,2)=GBR(I1+J2,2)
  12      CONTINUE
          LERASE=.FALSE.
        ENDIF
        J1=J1+KBR(J1+3,1)+3
      IF (J1.LT.NBR) GOTO 10
      ENDIF
C
C     Searching for new triangles and for unprocessed homogeneous ones,
C     storing their vertices to the array KAUAR:
  13  CONTINUE
      NAUAR=0
      DO 30, I1=1,NTRI
        IF ((KTRI(6,I1).EQ.0).OR.(KTRI(6,I1).EQ.3)) THEN
          DO 40, I2=1,3
            IF (NAUAR.GE.MAUAR) THEN
C             RP3D-022
              CALL ERROR('RP3D-022: Insufficient memory for KAUAR.')
C             This error may be caused by too small dimension of array
C             KAUAR. Try to enlarge the parameter MAUAR in common block
C             AUXER in file
C             rp3d.inc.
            ENDIF
            NAUAR=NAUAR+1
            KAUAR(NAUAR)=KTRI(I2,I1)
  40      CONTINUE
        ENDIF
  30  CONTINUE
C
C     Marking unneeded triangles,deleting them from arrays in RPAUX:
      DO 50, I1=1,NTRI
        IF (KTRI(6,I1).EQ.2) THEN
          IF (KTRI(5,I1).EQ.0) THEN
C           Basic triangle:
            DO 55, I2=1,NPL
              IF ((KTRI(1,I1).EQ.KPL(I2)).OR.
     *            (KTRI(2,I1).EQ.KPL(I2)).OR.
     *            (KTRI(3,I1).EQ.KPL(I2))) GOTO 50
  55        CONTINUE
          ENDIF
          CALL RPAUX1(-KTRI(4,I1),0)
          KTRI(4,I1)=0
        ELSEIF (KTRI(6,I1).EQ.4) THEN
          DO 60, I2=1,NPL
            IF ((KTRI(1,I1).EQ.KPL(I2)).OR.
     *          (KTRI(2,I1).EQ.KPL(I2)).OR.
     *          (KTRI(3,I1).EQ.KPL(I2))) GOTO 50
  60      CONTINUE
          DO 70, I2=1,NAUAR
            IF ((KTRI(1,I1).EQ.KAUAR(I2)).OR.
     *          (KTRI(2,I1).EQ.KAUAR(I2)).OR.
     *          (KTRI(3,I1).EQ.KAUAR(I2))) GOTO 50
  70      CONTINUE
          J1=0
          IF (NBR.GT.2) THEN
  73      CONTINUE
            DO 75, I2=J1+4,J1+3+KBR(J1+3,1)
              IF ((KTRI(1,I1).EQ.KBR(I2,1)).OR.
     *            (KTRI(2,I1).EQ.KBR(I2,1)).OR.
     *            (KTRI(3,I1).EQ.KBR(I2,1))) GOTO 50
  75        CONTINUE
            J1=J1+KBR(J1+3,1)+3
          IF (J1.LT.NBR) GOTO 73
          ENDIF
          CALL RPAUX1(-KTRI(4,I1),0)
          KTRI(4,I1)=0
        ENDIF
  50  CONTINUE
C
      DO 78, I2=1,NTRI
        IF (KTRI(4,I2).EQ.0) THEN
C         This triangle will be deleted:
          KTRIS(1)=KTRI(1,I2)
          KTRIS(2)=KTRI(2,I2)
          KTRIS(3)=KTRI(3,I2)
          KTRIS(4)=KTRI(4,I2)
          KTRIS(5)=KTRI(5,I2)
          KTRIS(6)=2
          CALL RPSTOR('T',1,KTRIS)
        ENDIF
  78  CONTINUE
C
C     Marking all rays as unneeded:
      DO 80, I1=5,NRAY
        IF (ITRAY(I1).GT.-1000) KRAY(I1)=-KRAY(I1)
  80  CONTINUE
C
C     Marking needed rays,erasing unneeded triangles:
C     Marking vertices of triangles as needed:
      I1=0
      DO 90, I2=1,NTRI
        IF (KTRI(4,I2).EQ.0) THEN
C         This triangle will be deleted:
          GOTO 90
        ENDIF
        I1=I1+1
        DO 100, I3=1,6
          KTRI(I3,I1)=KTRI(I3,I2)
  100   CONTINUE
        DO 120, I3=1,3
          DO 114, I4=1,NRAY
C           Marking ray KTRI(I3,I1) as needed:
            IF (IABS(KRAY(I4)).EQ.KTRI(I3,I1)) THEN
              KRAY(I4)=IABS(KRAY(I4))
              ITYPE=ITRAY(I4)
              GOTO 116
            ENDIF
  114     CONTINUE
          CALL RPERR(1)
  116     CONTINUE
          IF (ITYPE.GT.0) THEN
C           Marking boundary ray coupled with KTRI(I3,I1) as needed:
            DO 118, I4=1,NRAY
              IF (IABS(KRAY(I4)).EQ.ITYPE) THEN
                KRAY(I4)=IABS(KRAY(I4))
                GOTO 120
              ENDIF
  118       CONTINUE
            CALL RPERR(1)
          ENDIF
  120   CONTINUE
C       Marking auxiliary rays:
        CALL RPAUX2(KTRI(4,I1),0,J2)
        DO 130, I3=1,J2
          CALL RPAUX2(KTRI(4,I1),I3,J1)
          DO 140, I4=1,NRAY
            IF (IABS(KRAY(I4)).EQ.J1) THEN
              KRAY(I4)=IABS(KRAY(I4))
              ITYPE=ITRAY(I4)
              GOTO 138
            ENDIF
  140     CONTINUE
          CALL RPERR(1)
  138     CONTINUE
          IF (ITYPE.GT.0) THEN
C           Marking boundary ray coupled with ray J1 as needed:
            DO 136, I4=1,NRAY
              IF (IABS(KRAY(I4)).EQ.ITYPE) THEN
                KRAY(I4)=IABS(KRAY(I4))
                GOTO 130
              ENDIF
  136       CONTINUE
            CALL RPERR(1)
          ENDIF
  130   CONTINUE
  90  CONTINUE
      NTRI=I1
C     Marking rays on the polyline:
      DO 150, I1=1,NPL
        DO 160, I4=1,NRAY
          IF (IABS(KRAY(I4)).EQ.KPL(I1)) THEN
            KRAY(I4)=IABS(KRAY(I4))
            ITYPE=ITRAY(I4)
            GOTO 158
          ENDIF
  160   CONTINUE
        CALL RPERR(1)
  158   CONTINUE
        IF (ITYPE.GT.0) THEN
C         Marking boundary ray coupled with ray KPL(I1) as needed:
          DO 156, I4=1,NRAY
            IF (IABS(KRAY(I4)).EQ.ITYPE) THEN
              KRAY(I4)=IABS(KRAY(I4))
              GOTO 150
            ENDIF
  156     CONTINUE
          CALL RPERR(1)
        ENDIF
  150 CONTINUE
C     Marking rays in the array KBR:
      J1=0
      IF (NBR.GT.2) THEN
  165 CONTINUE
        DO 170, I1=J1+1,J1+3+KBR(J1+3,1)
          IF (I1.EQ.J1+3) GOTO 170
          DO 180, I4=1,NRAY
            IF (IABS(KRAY(I4)).EQ.KBR(I1,1)) THEN
              KRAY(I4)=IABS(KRAY(I4))
              ITYPE=ITRAY(I4)
              GOTO 178
            ENDIF
  180     CONTINUE
          CALL RPERR(1)
  178     CONTINUE
          IF (ITYPE.GT.0) THEN
C           Marking boundary ray coupled with ray KBR(I1,1) as needed:
            DO 176, I4=1,NRAY
              IF (IABS(KRAY(I4)).EQ.ITYPE) THEN
                KRAY(I4)=IABS(KRAY(I4))
                GOTO 170
              ENDIF
  176       CONTINUE
            CALL RPERR(1)
          ENDIF
  170   CONTINUE
        J1=J1+KBR(J1+3,1)+3
      IF (J1.LT.NBR) GOTO 165
      ENDIF
C     Marking rays in the array KAUAR:
      DO 200, I1=1,NAUAR
        DO 190, I4=1,NRAY
          IF (IABS(KRAY(I4)).EQ.KAUAR(I1)) THEN
            KRAY(I4)=IABS(KRAY(I4))
            ITYPE=ITRAY(I4)
            GOTO 192
          ENDIF
  190   CONTINUE
        CALL RPERR(1)
  192   CONTINUE
        IF (ITYPE.GT.0) THEN
C         Marking boundary ray coupled with ray KAUAR(I1) as needed:
          DO 196, I4=1,NRAY
            IF (IABS(KRAY(I4)).EQ.ITYPE) THEN
              KRAY(I4)=IABS(KRAY(I4))
              GOTO 200
            ENDIF
  196     CONTINUE
          CALL RPERR(1)
        ENDIF
  200 CONTINUE
C
C     Deleting unneeded rays:
      J1=4
      DO 210, I1=5,NRAY
        IF (KRAY(I1).LT.0) GOTO 210
        J1=J1+1
        KRAY(J1)=KRAY(I1)
        ITRAY(J1)=ITRAY(I1)
        ISRAY(J1)=ISRAY(I1)
        IBRAY(J1)=IBRAY(I1)
        G1RAY(J1)=G1RAY(I1)
        G2RAY(J1)=G2RAY(I1)
        X1RAY(J1)=X1RAY(I1)
        X2RAY(J1)=X2RAY(I1)
        G11RAY(J1)=G11RAY(I1)
        G12RAY(J1)=G12RAY(I1)
        G22RAY(J1)=G22RAY(I1)
        S11RAY(J1)=S11RAY(I1)
        S12RAY(J1)=S12RAY(I1)
        S22RAY(J1)=S22RAY(I1)
        G1X1RA(J1)=G1X1RA(I1)
        G1X2RA(J1)=G1X2RA(I1)
        G2X1RA(J1)=G2X1RA(I1)
        G2X2RA(J1)=G2X2RA(I1)
  210 CONTINUE
      NRAY=J1
      RETURN
      END
C
C=======================================================================
C
      SUBROUTINE RPTMEA(JTRI,ITRI,IRAY,LNEWAR,
     *                  LAB20,G1NEW,G2NEW)
C
C----------------------------------------------------------------------
C Subroutine designed to measure the sides of the triangle JTRI in the
C ray-tube metric and to divide this triangle if it is too large.
C
      INTEGER JTRI,ITRI,IRAY
      LOGICAL LNEWAR,LAB20
      REAL G1NEW,G2NEW
C Input:
C     JTRI ...Index of the measured triangle.
C     ITRI ...Index of last computed triangle.
C     IRAY ...Index of last computed ray.
C     LNEWAR .Indicates whether the new auxiliary ray was computed.
C Output:
C     LNEWAR..Indicates whether the new auxiliary ray is to be computed.
C     LAB20 ..Indicates that inhomogeneous triangles have been formed
C             running RPTMEA.
C     G1NEW,G2NEW ... Coordinates of the new ray.
C
C Subroutines and external functions required:
      EXTERNAL RPDI2G,RPLRIL
      REAL RPDI2G
      LOGICAL RPLRIL
C
C Coded by Petr Bulant
C
C.......................................................................
C
C Common blocks /GLIM/, /DRAYS/ and /BOURA/:
      INCLUDE 'rp3d.inc'
C     rp3d.inc
C............................
C
C Common block /RPARD/:
      INCLUDE 'rpard.inc'
C     rpard.inc
C     AERR ... The distance of boundary rays.
C     PRM0(4) ... Maximum allowed thickness of the ray tubes.
C.......................................................................
      REAL ZERO
      PARAMETER (ZERO =.0000001)
      INTEGER KTRID(6),KTRIN(6),KTRIS(6)
      INTEGER KRAYA,ITYPEA,ISHA
      REAL G1A,G2A,G11A,G12A,G22A,G1X1A,G2X1A,G1X2A,G2X2A
      INTEGER KRAYB,ITYPEB,ISHB
      REAL G1B,G2B,G11B,G12B,G22B,G1X1B,G2X1B,G1X2B,G2X2B
      INTEGER KRAYC,ITYPEC,ISHC
      REAL G1C,G2C,G11C,G12C,G22C,G1X1C,G2X1C,G1X2C,G2X2C
      INTEGER KRAYD,ITYPED,ISHD
      REAL S11A,S12A,S22A,S11B,S12B,S22B,S11C,S12C,S22C
      REAL G1D,G2D,G11D,G12D,G22D
      INTEGER ITYPEG,ISHG
      REAL G1G,G2G,G11G,G12G,G22G
      INTEGER KRAYI,KRAYJ,ITYPE,ISH
      REAL G1I,G2I,G1J,G2J,G1K,G2K,G11,G12,G22
      REAL X1,X2,G1X1,G2X1,G1X2,G2X2
      REAL AREA,DIST2A,DIST2B,DIST2C,AERR2,PRM042
      REAL G11POM,G12POM,G22POM
      REAL DG1,DG2,DIST2,DETG
      INTEGER I1,I2,I3
      LOGICAL LRAY,LTRI
      SAVE KRAYA,KRAYB,KRAYC,ISHA,ITYPEA,ITYPEB,G1A,G1B,G2A,G2B
     *    ,G11A,G12A,G22A,G11B,G12B,G22B,AERR2,PRM042,KTRID
C     ZERO..Constant used to decide whether the real variable .EQ. zero.
C     KTRID...Parameters of the triangle to be measured.
C     KTRIN...Parameters of the new triangle to be registrated
C             (new column to be added into array KTRI).
C     KTRIS...Parameters of the examined triangle.
C     G1X1,G2X1,G1X2,G2X2 ... Derivations.
C     KRAYA,(B),(C),..  .... Signs of rays      |   auxiliary
C     ITYPEA,(B),(C),..  ... Types of rays      |   variables used
C     ISHA,(B),(C)...Value of history function  |   for different rays.
C     GiA,(B),(C)........ Parameters of rays |
C     AREA ...Auxiliary variable (area of the triangle).
C     DIST2A,B,C ...Auxiliary variables (second powers of the lengths
C                                        of the triangle sides).
C     AERR2 ... Second power of the maximum distance between the couple
C               of boundary rays in the normalized ray domain.
C     GiiPOM ...Auxiliary variables (metric tensor).
C     DG1,DG2,DIST2 ..Auxiliary variables.
C     DETG... Determinant.
C     I1,2,3..Implied-do variables or variables controlling the loop.
C     LRAY ...Indicates whether the ray IRAY is in memory.
C     LTRI ...Indicates whether the triangle ITRI is in memory.
C-----------------------------------------------------------------------
C
      IF (IRAY.EQ.0) THEN
        AERR2=AERR**2
        PRM042=PRM0(4)**2
        NDRAYS=0
      ENDIF
C
      IF (LNEWAR) GOTO 10
C
      CALL RPTRI3(JTRI,LTRI,KTRID)
      IF ((.NOT.LTRI).OR.(KTRID(6).NE.3)) THEN
        LNEWAR=.FALSE.
        RETURN
      ENDIF
C     Reading the rays of the triangle:
      KRAYA=KTRID(1)
      CALL RPRAY2(KTRID(1),LRAY,ITYPEA,ISHA,G1A,G2A,G11A,G12A,G22A,
     *            S11A,S12A,S22A,X1,X2,G1X1A,G2X1A,G1X2A,G2X2A)
      IF (.NOT.LRAY) CALL RPERR(1)
      KRAYB=KTRID(2)
      CALL RPRAY2(KTRID(2),LRAY,ITYPEB,ISHB,G1B,G2B,G11B,G12B,G22B,
     *            S11B,S12B,S22B,X1,X2,G1X1B,G2X1B,G1X2B,G2X2B)
      IF (.NOT.LRAY) CALL RPERR(1)
      KRAYC=KTRID(3)
      CALL RPRAY2(KTRID(3),LRAY,ITYPEC,ISHC,G1C,G2C,G11C,G12C,G22C,
     *            S11C,S12C,S22C,X1,X2,G1X1C,G2X1C,G1X2C,G2X2C)
      IF (.NOT.LRAY) CALL RPERR(1)
      IF ((ISHA.NE.ISHB).OR.(ISHA.NE.ISHC)) THEN
        KTRID(6)=0
        CALL RPTRI2(KTRID(4),LTRI,KTRID)
        IF (.NOT.LTRI) CALL RPERR(2)
        LAB20=.TRUE.
        LNEWAR=.FALSE.
        RETURN
      ENDIF
C     ..A,..B,..C .. Vertices of measured triangle.
C     Controlling the size of triangle surface :
      G11POM=(G11A+G11C+G11B)/3.
      G12POM=(G12A+G12C+G12B)/3.
      G22POM=(G22A+G22C+G22B)/3.
      DG1=G1B-G1A
      DG2=G2B-G2A
      DETG=G11POM*G22POM - G12POM*G12POM
      IF (DETG.LT.ZERO) CALL RPERR(4)
      AREA=SQRT(DETG)*((DG1*(G2C-G2A)-DG2*(G1C-G1A))*.5)
      IF (AREA.LT.(AERR2*0.4330127/9.)) THEN
C       0.4330127=Sqrt(3)/4
C       Triangle too small or left-handed.
        KTRID(6)=2
        CALL RPTRI2(KTRID(4),LTRI,KTRID)
        IF (.NOT.LTRI) CALL RPERR(2)
        RETURN
      ENDIF
C     Measuring the size of triangle sides using the ray-domain
C     matrix:
      G11POM=(G11A+G11B)/2.
      G12POM=(G12A+G12B)/2.
      G22POM=(G22A+G22B)/2.
      DIST2A=RPDI2G(G1A,G2A,G1B,G2B,G11POM,G12POM,G22POM)
      G11POM=(G11B+G11C)/2.
      G12POM=(G12B+G12C)/2.
      G22POM=(G22B+G22C)/2.
      DIST2B=RPDI2G(G1B,G2B,G1C,G2C,G11POM,G12POM,G22POM)
      G11POM=(G11A+G11C)/2.
      G12POM=(G12A+G12C)/2.
      G22POM=(G22A+G22C)/2.
      DIST2C=RPDI2G(G1A,G2A,G1C,G2C,G11POM,G12POM,G22POM)
C
      IF ((DIST2A.LE.AERR2/9.).OR.(DIST2B.LE.AERR2/9.).OR.
     *    (DIST2C.LE.AERR2/9.)) THEN
C       Triangle too small.
        KTRID(6)=2
        CALL RPTRI2(KTRID(4),LTRI,KTRID)
        IF (.NOT.LTRI) CALL RPERR(2)
        RETURN
      ENDIF
C
      IF (PRM0(4).EQ.0.) RETURN
C
C     Measuring the size of triangle sides using the ray-tube matrix:
      G11POM=(S11A+S11B)/2.
      G12POM=(S12A+S12B)/2.
      G22POM=(S22A+S22B)/2.
      DIST2A=RPDI2G(G1A,G2A,G1B,G2B,G11POM,G12POM,G22POM)
      G11POM=(S11B+S11C)/2.
      G12POM=(S12B+S12C)/2.
      G22POM=(S22B+S22C)/2.
      DIST2B=RPDI2G(G1B,G2B,G1C,G2C,G11POM,G12POM,G22POM)
      G11POM=(S11A+S11C)/2.
      G12POM=(S12A+S12C)/2.
      G22POM=(S22A+S22C)/2.
      DIST2C=RPDI2G(G1A,G2A,G1C,G2C,G11POM,G12POM,G22POM)
C
      IF ((DIST2A.LE.PRM042).AND.(DIST2B.LE.PRM042).AND.
     *    (DIST2C.LE.PRM042)) THEN
C       The triangle is O.K.
        RETURN
      ENDIF
C
C     Choosing the longest side to be divided:
      IF ((DIST2A.GE.DIST2B).AND.(DIST2A.GE.DIST2C)) THEN
C       No action
      ELSEIF ((DIST2B.GE.DIST2A).AND.(DIST2B.GE.DIST2C)) THEN
         KRAYD= KRAYA
        ITYPED=ITYPEA
          ISHD=  ISHA
           G1D=   G1A
           G2D=   G2A
          G11D=  G11A
          G12D=  G12A
          G22D=  G22A
         KRAYA= KRAYB
        ITYPEA=ITYPEB
          ISHA=  ISHB
           G1A=   G1B
           G2A=   G2B
          G11A=  G11B
          G12A=  G12B
          G22A=  G22B
         KRAYB= KRAYC
        ITYPEB=ITYPEC
          ISHB=  ISHC
           G1B=   G1C
           G2B=   G2C
          G11B=  G11C
          G12B=  G12C
          G22B=  G22C
         KRAYC= KRAYD
        ITYPEC=ITYPED
          ISHC=  ISHD
           G1C=   G1D
           G2C=   G2D
          G11C=  G11D
          G12C=  G12D
          G22C=  G22D
      ELSEIF ((DIST2C.GE.DIST2A).AND.(DIST2C.GE.DIST2B)) THEN
         KRAYD= KRAYA
        ITYPED=ITYPEA
          ISHD=  ISHA
           G1D=   G1A
           G2D=   G2A
          G11D=  G11A
          G12D=  G12A
          G22D=  G22A
         KRAYA= KRAYC
        ITYPEA=ITYPEC
          ISHA=  ISHC
           G1A=   G1C
           G2A=   G2C
          G11A=  G11C
          G12A=  G12C
          G22A=  G22C
         KRAYC= KRAYB
        ITYPEC=ITYPEB
          ISHC=  ISHB
           G1C=   G1B
           G2C=   G2B
          G11C=  G11B
          G12C=  G12B
          G22C=  G22B
         KRAYB= KRAYD
        ITYPEB=ITYPED
          ISHB=  ISHD
           G1B=   G1D
           G2B=   G2D
          G11B=  G11D
          G12B=  G12D
          G22B=  G22D
      ENDIF
C     Proposing the ray parameters of a new ray:
      G1NEW=(G1A+G1B)/2.
      G2NEW=(G2A+G2B)/2.
      IF (((G1NEW.EQ.G1A).AND.(G2NEW.EQ.G2A)).OR.
     *    ((G1NEW.EQ.G1B).AND.(G2NEW.EQ.G2B))) CALL RPERR(3)
C
C     Checking whether the ray has not yet been computed:
  2   CONTINUE
      IF (NDRAYS.GT.0) THEN
        IF ((G1NEW.NE.GLIMIT(1)).AND.(G1NEW.NE.GLIMIT(2)).AND.
     *      (G2NEW.NE.GLIMIT(3)).AND.(G2NEW.NE.GLIMIT(4))) THEN
          DO 5, I1=1,NDRAYS
            CALL RPRAY(KDRAYS(I1),LRAY,ITYPED,ISHD,G1D,G2D,
     *                G11G,G12G,G22G,X1,X2,G1X1,G2X1,G1X2,G2X2)
            IF (.NOT.LRAY) THEN
              DO 3, I2=I1,NDRAYS-1
                KDRAYS(I2)=KDRAYS(I2+1)
  3           CONTINUE
              NDRAYS=NDRAYS-1
              GOTO 2
            ENDIF
            IF ((ABS(G1D-G1NEW).LT.ZERO).AND.
     *          (ABS(G2D-G2NEW).LT.ZERO)) THEN
C             New ray found in the array KDRAYS:
              KRAYD=KDRAYS(I1)
              DO 4, I2=I1,NDRAYS-1
                KDRAYS(I2)=KDRAYS(I2+1)
 4            CONTINUE
              NDRAYS=NDRAYS-1
              GOTO 21
            ENDIF
 5        CONTINUE
        ENDIF
      ENDIF
      LNEWAR=.TRUE.
      RETURN
C
C
  10  CONTINUE
      KRAYD=IRAY
      CALL RPRAY(IRAY,LRAY,ITYPED,ISHD,G1D,G2D,G11D,G12D,G22D,
     *           X1,X2,G1X1,G2X1,G1X2,G2X2)
      IF (.NOT.LRAY) CALL RPERR(1)
C     Checking whether the ray is to be stored to the array KDRAYS:
      IF (((G1A.NE.GLIMIT(1)).OR.(G1B.NE.GLIMIT(1))).AND.
     *    ((G1A.NE.GLIMIT(2)).OR.(G1B.NE.GLIMIT(2))).AND.
     *    ((G2A.NE.GLIMIT(3)).OR.(G2B.NE.GLIMIT(3))).AND.
     *    ((G2A.NE.GLIMIT(4)).OR.(G2B.NE.GLIMIT(4)))) THEN
        NDRAYS=NDRAYS+1
        IF (NDRAYS.GT.MDRAYS) THEN
C         RP3D-023
          CALL ERROR('RP3D-023: Insufficient memory for KDRAYS.')
C         This error may be caused by too small dimension of array
C         KDRAYS. Try to enlarge the parameter MDRAYS in common block
C         DRAYS in file
C         rp3d.inc.
        ENDIF
        KDRAYS(NDRAYS)=KRAYD
      ENDIF
C
C     When the ray D is on the sides of the basic triangle which
C     contains the divided triangle, storing it to the KBR:
      IF (KTRID(5).NE.0) THEN
        CALL RPTRI3(KTRID(5),LTRI,KTRIS)
        IF (.NOT.LTRI) CALL RPERR(2)
      ELSE
        KTRIS(1)=KTRID(1)
        KTRIS(2)=KTRID(2)
        KTRIS(3)=KTRID(3)
      ENDIF
      CALL RPRAY(KTRIS(1),LRAY,ITYPE,ISH,G1I,G2I,G11,G12,G22,
     *           X1,X2,G1X1,G2X1,G1X2,G2X2)
      IF (.NOT.LRAY) CALL RPERR(1)
      CALL RPRAY(KTRIS(2),LRAY,ITYPE,ISH,G1J,G2J,G11,G12,G22,
     *           X1,X2,G1X1,G2X1,G1X2,G2X2)
      IF (.NOT.LRAY) CALL RPERR(1)
      CALL RPRAY(KTRIS(3),LRAY,ITYPE,ISH,G1K,G2K,G11,G12,G22,
     *           X1,X2,G1X1,G2X1,G1X2,G2X2)
      IF (.NOT.LRAY) CALL RPERR(1)
      IF (RPLRIL(G1D,G2D,G1K,G2K,G1I,G2I)) THEN
C       Boundary rays are lying on the side IK (side 3,1):
        KRAYI=KTRIS(1)
        KRAYJ=KTRIS(3)
      ELSEIF (RPLRIL(G1D,G2D,G1I,G2I,G1J,G2J)) THEN
C       Boundary rays are lying on the side IJ (side 1,2):
        KRAYI=KTRIS(2)
        KRAYJ=KTRIS(1)
      ELSEIF (RPLRIL(G1D,G2D,G1J,G2J,G1K,G2K)) THEN
C       Boundary rays are lying on the side JK (side 2,3):
        KRAYI=KTRIS(3)
        KRAYJ=KTRIS(2)
      ELSE
C       Ray is not on the sides of the basic triangle:
        GOTO 21
      ENDIF
      CALL RPKBR(KRAYI,KRAYJ,KRAYD)
C
  21  CONTINUE
      LNEWAR=.FALSE.
      IF (ISHD.EQ.ISHA) THEN
C       New triangles will be homogeneous:
        KTRIN(6)=3
      ELSE
C       A strange ray was identified inside the triangle.
C       New triangles will be inhomogeneous:
        KTRIN(6)=0
        LAB20=.TRUE.
      ENDIF
C     Now dividing the triangle KTRID into two new triangles:
      KTRID(6)=2
      IF (KTRID(5).EQ.0) THEN
        KTRIN(5)=KTRID(4)
      ELSE
        KTRIN(5)=KTRID(5)
      ENDIF
      CALL RPTRI2(KTRID(4),LTRI,KTRID)
      ITRI=ITRI+1
      KTRIN(1)=KRAYA
      KTRIN(2)=KRAYD
      KTRIN(3)=KRAYC
      KTRIN(4)=ITRI
      CALL RPTRI1(ITRI,KTRIN)
      CALL RPSTOR('T',1,KTRIN)
      ITRI=ITRI+1
      KTRIN(1)=KRAYD
      KTRIN(2)=KRAYB
      KTRIN(3)=KRAYC
      KTRIN(4)=ITRI
      CALL RPTRI1(ITRI,KTRIN)
      CALL RPSTOR('T',1,KTRIN)
C
      IF ((ITYPEA.GT.0).AND.(ITYPEB.GT.0)) THEN
C       Confirmation that the previous triangles
C       have been formed correctly:
        CALL RPTRIP(-ITRI+2,LTRI,KTRIS)
C       Loop for all the triangles in the memory:
  20    CONTINUE
          CALL RPTRIP(0,LTRI,KTRIS)
          IF (LTRI) THEN
            IF (KTRIS(6).EQ.2) GOTO 20
            IF (KTRIS(4).EQ.ITRI) GOTO 20
            IF (KTRIS(4).EQ.ITRI-1) GOTO 20
            DO 30, I2=1,3
              CALL RPRAY(KTRIS(I2),LRAY,ITYPEG,ISHG,G1G,G2G,
     *                  G11G,G12G,G22G,X1,X2,G1X1,G2X1,G1X2,G2X2)
              IF (.NOT.LRAY) CALL RPERR(1)
              G11POM=(G11A+G11G)/2.
              G12POM=(G12A+G12G)/2.
              G22POM=(G22A+G22G)/2.
              DIST2=RPDI2G(G1A,G2A,G1G,G2G,G11POM,G12POM,G22POM)
              IF (DIST2.LE.AERR2) THEN
                IF (KRAYA.EQ.KTRIS(I2)) GOTO 20
                DO 40, I3=1,3
                  IF (I3.EQ.I2) GOTO 40
                  CALL RPRAY(KTRIS(I3),LRAY,ITYPEG,ISHG,G1G,G2G,
     *                 G11G,G12G,G22G,X1,X2,G1X1,G2X1,G1X2,G2X2)
                  IF (.NOT.LRAY) CALL RPERR(1)
                  G11POM=(G11B+G11G)/2.
                  G12POM=(G12B+G12G)/2.
                  G22POM=(G22B+G22G)/2.
                  DIST2=RPDI2G(G1B,G2B,G1G,G2G,G11POM,G12POM,G22POM)
                  IF (DIST2.LE.AERR2) THEN
                    IF (KRAYB.EQ.KTRIS(I3)) GOTO 20
C                   Triangle KTRIS must be divided:
                    KTRIS(6)=2
                    CALL RPTRI2(KTRIS(4),LTRI,KTRIS)
                    IF (.NOT.LTRI) CALL RPERR(2)
                    ITRI=ITRI+1
                    KTRIN(1)=KTRIS(1)
                    KTRIN(2)=KTRIS(2)
                    KTRIN(3)=KTRIS(3)
                    KTRIN(I2)=KRAYD
                    KTRIN(4)=ITRI
                    IF (KTRIS(5).EQ.0) THEN
                      KTRIN(5)=KTRIS(4)
                    ELSE
                      KTRIN(5)=KTRIS(5)
                    ENDIF
                    KTRIN(6)=0
                    CALL RPTRI1(ITRI,KTRIN)
                    CALL RPSTOR('T',1,KTRIN)
                    ITRI=ITRI+1
                    KTRIN(1)=KTRIS(1)
                    KTRIN(2)=KTRIS(2)
                    KTRIN(3)=KTRIS(3)
                    KTRIN(I3)=KRAYD
                    KTRIN(4)=ITRI
                    CALL RPTRI1(ITRI,KTRIN)
                    CALL RPSTOR('T',1,KTRIN)
                    LAB20=.TRUE.
                    GOTO 50
                  ENDIF
  40            CONTINUE
              ENDIF
  30        CONTINUE
            GOTO 20
          ENDIF
C       End of the loop for all the triangles in the memory.
  50    CONTINUE
      ENDIF
      RETURN
      END
C
C=======================================================================
C
      LOGICAL FUNCTION RPLRIT(LRAY,S1A,S2A,S1B,S2B,S1C,S2C,S1X,S2X,AREA)
C
C----------------------------------------------------------------------
      REAL S1A,S2A,S1B,S2B,S1C,S2C,S1X,S2X,AREA
      LOGICAL LRAY
C In case LRAY=.TRUE. :
C Subroutine designed to decide, whether the ray X lies
C inside the triangle formed by rays A,B,C.
C In case LRAY=.FALSE. :
C Subroutine designed to decide, whether the triangle
C formed by rays A,B,C is right-handed.
C
C Cartesian metric tensor is used in both cases.
C
C Input:
C     LRAY .. Says what to do.
C     S1A,S2A,B,C ... Coordinates of rays forming the triangle.
C     S1X,S2X  ...    Coordinates of fourth ray.
C
C Output:
C     RPLRIT ....TRUE.  Means yes, ray lies in the triangle or the
C                       triangle is right-handed.
C               .FALSE. Means no, the ray is not in the triangle or the
C                       triangle is left-handed.
C     AREA   ...        Area of the triangle.
C
C Coded by Petr Bulant
C
      INCLUDE 'rpard.inc'
C     rpard.inc
C
C......................................................................
      REAL ZERO,ZERO1
      PARAMETER (ZERO =.0000001)
      PARAMETER (ZERO1=.0000000001)
      REAL AREA1,AREA2,AREA3
C     ZERO ...Constant used to decide whether the AREAI .EQ. zero.
C     AREA1,2,3 ... Auxiliary variables used when examining whether the
C                   ray X lies in triangle.
C-----------------------------------------------------------------------
      IF (.NOT.LRAY) THEN
        AREA=((S1B-S1A)*(S2C-S2A)-(S1C-S1A)*(S2B-S2A))/2.
        IF (AREA.LT.ZERO) AREA=0.
C       Triangle too small, it will be treated as left-handed.
        IF (AREA.GT.0.) THEN
C         Triangle A,B,C is right-handed.
          RPLRIT=.TRUE.
        ELSE
          RPLRIT=.FALSE.
        ENDIF
      ELSE
        IF (((S1A.EQ.S1X).AND.(S2A.EQ.S2X)).OR.
     *      ((S1B.EQ.S1X).AND.(S2B.EQ.S2X)).OR.
     *      ((S1C.EQ.S1X).AND.(S2C.EQ.S2X))) THEN
          RPLRIT=.TRUE.
        ELSE
          AREA1=(S1B-S1X)*(S2C-S2X)-(S1C-S1X)*(S2B-S2X)
          IF (ABS(AREA1).LT.ZERO1) AREA1=0.
          AREA2=(S1C-S1X)*(S2A-S2X)-(S1A-S1X)*(S2C-S2X)
          IF (ABS(AREA2).LT.ZERO1) AREA2=0.
          AREA3=(S1A-S1X)*(S2B-S2X)-(S1B-S1X)*(S2A-S2X)
          IF (ABS(AREA3).LT.ZERO1) AREA3=0.
          IF (((AREA1.GE.0.).AND.(AREA2.GE.0.).AND.(AREA3.GE.0.)).OR.
     *        ((AREA1.LE.0.).AND.(AREA2.LE.0.).AND.(AREA3.LE.0.))) THEN
C           Ray X lies in the triangle A,B,C.
            RPLRIT=.TRUE.
          ELSE
            RPLRIT=.FALSE.
          ENDIF
        ENDIF
      ENDIF
      RETURN
      END
C
C=======================================================================
C
      LOGICAL FUNCTION RPLRIP(NPOL,GPOL,G1X,G2X)
C
C----------------------------------------------------------------------
      INTEGER MPOL,NPOL
C                                                   
      PARAMETER (MPOL=500)
      REAL GPOL(MPOL,2)
      REAL G1X,G2X
C Subroutine designed to decide, whether the ray X lies in the polygon
C formed by rays stored in GPOL.
C
C Cartesian metric tensor is used.
C
C Input:
C     NPOL  ...    Number of rays forming the polygon GPOL.
C     GPOL(I,1),GPOL(I,2) ...Normalized parameters of rays forming
C                            the polygon.
C     G1X,G2X  ... Normalized parameters of the examined ray.
C
C Output:
C     RPLRIP... .TRUE.  Means yes, ray lies in the polygon.
C               .FALSE. Means no, the ray is not in the polygon.
C
C Subroutines and external functions required:
      EXTERNAL RPLRIL
      LOGICAL RPLRIL
C
C Coded by Petr Bulant
C
C......................................................................
      REAL ZERO
      PARAMETER (ZERO=.0000001)
      INTEGER INTERS
      REAL G1A,G2A,G1B,G2B,G1P
      REAL SMER1,SMER2
      INTEGER I1,I2,J1,J2
C     INTERS ...  Counts the intersection points.
C     SMER1,2 ... The direction of a line.
C-----------------------------------------------------------------------
      INTERS=0
      I1=NPOL
      I2=1
C     Loop for all the sides of the polygon:
  10  CONTINUE
        G1A=GPOL(I1,1)
        G2A=GPOL(I1,2)
        G1B=GPOL(I2,1)
        G2B=GPOL(I2,2)
        IF ((G2A.GT.G2X).AND.(G2B.GT.G2X)) GOTO 100
        IF ((G2A.LT.G2X).AND.(G2B.LT.G2X)) GOTO 100
        IF ((G1A.LT.G1X).AND.(G1B.LT.G1X)) GOTO 100
        IF (ABS(G1A-G1B).LT.ZERO) THEN
          IF (G2A.LT.G2B) THEN
            SMER1=999.
          ELSEIF (G2A.GT.G2B) THEN
            SMER1=-999.
          ELSE
            SMER1=0.
          ENDIF
        ELSE
          SMER1=(G2B-G2A)/(G1B-G1A)
        ENDIF
        IF (SMER1.EQ.0.) GOTO 100
        IF ((G1A.GE.G1X).AND.(G1B.GE.G1X)) THEN
          IF ((ABS(G1A-G1X).LT.ZERO).AND.(ABS(G1B-G1X).LT.ZERO)) THEN
            RPLRIP=.TRUE.
            RETURN
          ENDIF
          INTERS=INTERS+1
          IF (ABS(G2B-G2X).LT.ZERO) THEN
            J1=I2
            J2=I2+1
            IF (I2.EQ.NPOL) J2=1
  20        CONTINUE
            IF (ABS(GPOL(J1,1)-GPOL(J2,1)).LT.ZERO) THEN
              IF (GPOL(J1,2).LT.GPOL(J2,2)) THEN
                SMER2=999.
              ELSEIF (GPOL(J1,2).GT.GPOL(J2,2)) THEN
                SMER2=-999.
              ELSE
                SMER2=0.
              ENDIF
            ELSE
              SMER2=(GPOL(J2,2)-GPOL(J1,2))/(GPOL(J2,1)-GPOL(J1,1))
            ENDIF
            IF (SMER2.EQ.0) THEN
              I2=I2+1
              IF (I2.EQ.NPOL) THEN
                J1=NPOL
                J2=1
                GOTO 20
              ENDIF
              IF (I2.GT.NPOL) THEN
                J1=J2
                J2=J2+1
                GOTO 20
              ENDIF
            ENDIF
            IF (SMER1*SMER2.GT.0.) THEN
              I2=I2+1
            ENDIF
          ENDIF
        ELSE
          G1P=G1A+((G1B-G1A)/(G2B-G2A))*(G2X-G2A)
          IF (ABS(G1P-G1X).LT.ZERO) THEN
            RPLRIP=.TRUE.
            RETURN
          ENDIF
          IF (G1P.GE.G1X) INTERS=INTERS+1
        ENDIF
  100 CONTINUE
      I1=I2
      I2=I2+1
      IF (I2.LE.NPOL) GOTO 10
C
      IF (MOD(INTERS,2).EQ.0) THEN
        RPLRIP=.FALSE.
      ELSE
        RPLRIP=.TRUE.
      ENDIF
      RETURN
      END
C
C=======================================================================
C
      REAL FUNCTION RPDI2G(G1A,G2A,G1B,G2B,G11,G12,G22)
C
C----------------------------------------------------------------------
      REAL G1A,G2A,G1B,G2B,G11,G12,G22
C Subroutine designed to compute the second power of the distance
C between two rays A and B on the normalized ray domain using metric
C tensor of components G11, G12, G22.
C
C Input:
C     G1A,G2A,B,C ... Coordinates of the two rays.
C     G11,G12,G22 ... Components of the metric tensor.
C
C Output:
C     RPDI2G      ... Distance of the rays.
C
C Coded by Petr Bulant
C
C......................................................................
      REAL DG1,DG2,AAA,BBB
C-----------------------------------------------------------------------
      DG1=G1A-G1B
      DG2=G2A-G2B
      AAA=G11*DG1+G12*DG2
      BBB=G12*DG1+G22*DG2
      RPDI2G=DG1*AAA + DG2*BBB
      END
C
C=======================================================================
C
      LOGICAL FUNCTION RPLRIL(G1A,G2A,G1B,G2B,G1C,G2C)
C
C----------------------------------------------------------------------
      REAL G1A,G2A,G1B,G2B,G1C,G2C
C
C Subroutine designed to decide whether the ray A lies on the abscissa
C formed by the rays B and C.
C
C Cartesian metric is used.
C
C Input:  coordinates of the three points.
C
C Output: RPLRIL ... Indicates whether the ray is on the abscissa.
C
C Coded by Petr Bulant
C
C.......................................................................
      REAL ZERO
      PARAMETER (ZERO=.0000001)
      REAL A,B,C,D
C     ZERO...Constant used to decide whether the real variable.EQ.zero.
C     A,B,C,D ... Auxiliary variables.
C-----------------------------------------------------------------------
C
      RPLRIL=.FALSE.
      A=(G2A-G2B)
      B=(G1C-G1B)
      C=(G1A-G1B)
      D=(G2C-G2B)
      IF (C.EQ.0.) THEN
        IF (A.EQ.0.) RPLRIL=.TRUE.
      ELSEIF (D.EQ.0.) THEN
        IF (C.EQ.0.) RPLRIL=.TRUE.
      ELSE
        IF (ABS(A*B-C*D).LE.ZERO) THEN
          IF ((G2A.GE.AMIN1(G2B,G2C)).AND.(G2A.LE.AMAX1(G2B,G2C)).AND.
     *        (G1A.GE.AMIN1(G1B,G1C)).AND.(G1A.LE.AMAX1(G1B,G1C)))
     *         RPLRIL=.TRUE.
        ENDIF
      ENDIF
      RETURN
      END
C
C=======================================================================
C
      SUBROUTINE RPCROS(G1A,G2A,G1B,G2B,G1C,G2C,G1D,G2D,LINTS,G1X,G2X)
C
C----------------------------------------------------------------------
      REAL G1A,G2A,G1B,G2B,G1C,G2C,G1D,G2D,G1X,G2X
      LOGICAL LINTS
C
C This subroutine looks for the intersection point of abscissa A-B
C with the abscissa C-D. If the intersection appears, it computes the
C coordinates of the intersection point.
C
C Cartesian metric is used.
C
C Input:  coordinates of the four points.
C
C Output: LINTS ... Indicates whether the intersection appeared.
C         G1X,G2X . Coordinates of the intersection point (if any).
C
C Coded by Petr Bulant
C
C.......................................................................
      REAL ZERO,ZERO1
      PARAMETER (ZERO=.0000001)
      PARAMETER (ZERO1=.0000000001)
      REAL AAA,BBB,PART
      REAL A,B,C,D
C     ZERO1...Constant used to decide whether the real variable.EQ.zero.
C     AAA,BBB,PART,A,B,C,D ... Auxiliary variables.
C-----------------------------------------------------------------------
C
      IF (ABS(G1A-G1B).LT.ZERO) THEN
        IF (ABS(G1D-G1C).LT.ABS(G1A-G1C)) GOTO 118
        IF (ABS(G1D-G1C).LT.ZERO) THEN
          IF (G1A.NE.G1C) GOTO 118
          IF ((G2A.GE.AMIN1(G2C,G2D)).AND.(G2A.LE.AMAX1(G2C,G2D))) THEN
            G1X=G1A
            G2X=G2A
            GOTO 114
          ENDIF
          IF ((G2B.GE.AMIN1(G2C,G2D)).AND.(G2B.LE.AMAX1(G2C,G2D))) THEN
            G1X=G1B
            G2X=G2B
            GOTO 114
          ENDIF
          GOTO 118
        ENDIF
        PART=(G1A-G1C)/(G1D-G1C)
        IF ((PART.GE.0.).AND.(PART.LE.1.)) THEN
          G1X=G1A
          G2X=G2C+PART*(G2D-G2C)
          IF ((G2X.LT.AMIN1(G2A,G2B)).OR.(G2X.GT.AMAX1(G2A,G2B)))
     *      GOTO 118
          GOTO 114
        ELSE
          GOTO 118
        ENDIF
      ELSEIF (ABS(G2A-G2B).LT.ZERO) THEN
        IF (ABS(G2D-G2C).LT.ABS(G2A-G2C)) GOTO 118
        IF (ABS(G2D-G2C).LT.ZERO) THEN
          IF (G2A.NE.G2C) GOTO 118
          IF ((G1A.GE.AMIN1(G1C,G1D)).AND.(G1A.LE.AMAX1(G1C,G1D))) THEN
            G1X=G1A
            G2X=G2A
            GOTO 114
          ENDIF
          IF ((G1B.GE.AMIN1(G1C,G1D)).AND.(G1B.LE.AMAX1(G1C,G1D))) THEN
            G1X=G1B
            G2X=G2B
            GOTO 114
          ENDIF
          GOTO 118
        ENDIF
        PART=(G2A-G2C)/(G2D-G2C)
        IF ((PART.GE.0.).AND.(PART.LE.1.)) THEN
          G2X=G2A
          G1X=G1C+PART*(G1D-G1C)
          IF ((G1X.LT.AMIN1(G1A,G1B)).OR.(G1X.GT.AMAX1(G1A,G1B)))
     *      GOTO 118
          GOTO 114
        ELSE
          GOTO 118
        ENDIF
      ELSE
        AAA=(G1D-G1C)*(G2B-G2A)-(G2D-G2C)*(G1B-G1A)
        BBB=(G1B-G1A)*(G2C-G2A)-(G2B-G2A)*(G1C-G1A)
        IF (ABS(AAA).LT.ZERO1) AAA=0.
        IF (ABS(BBB).LT.ZERO1) BBB=0.
        IF ((AAA.EQ.0.).AND.(BBB.EQ.0.)) THEN
          IF((G1A.GE.AMIN1(G1C,G1D)).AND.(G1A.LE.AMAX1(G1C,G1D)))THEN
            G1X=G1A
            G2X=G2A
            GOTO 114
          ENDIF
          IF (((G1C.GE.AMIN1(G1A,G1B)).AND.(G1C.LE.AMAX1(G1A,G1B))).
     *    AND.((G1D.GE.AMIN1(G1A,G1B)).AND.(G1D.LE.AMAX1(G1A,G1B))))
     *        THEN
            IF (ABS(G1A-G1C).LT.ABS(G1A-G1D)) THEN
              G1X=G1C
              G2X=G2C
              GOTO 114
            ELSE
              G1X=G1D
              G2X=G2D
              GOTO 114
            ENDIF
          ENDIF
          IF((G1C.GE.AMIN1(G1A,G1B)).AND.(G1C.LE.AMAX1(G1A,G1B)))THEN
            G1X=G1C
            G2X=G2C
            GOTO 114
          ELSEIF((G1D.GE.AMIN1(G1A,G1B)).AND.(G1D.LE.AMAX1(G1A,G1B)))
     *      THEN
            G1X=G1D
            G2X=G2D
            GOTO 114
          ELSE
            GOTO 118
          ENDIF
        ELSEIF (BBB.EQ.0.) THEN
          IF((G1C.GE.AMIN1(G1A,G1B)).AND.(G1C.LE.AMAX1(G1A,G1B)))THEN
            G1X=G1C
            G2X=G2C
            GOTO 114
          ELSE
            GOTO 118
          ENDIF
        ELSEIF (AAA.EQ.0.) THEN
          GOTO 118
        ELSEIF (ABS(AAA).LT.ABS(BBB)) THEN
          GOTO 118
        ELSE
          PART=BBB/AAA
          IF ((PART.LT.0.).OR.(PART.GT.1.)) GOTO 118
          G1X=G1C+PART*(G1D-G1C)
          IF ((G1X.LT.AMIN1(G1A,G1B)).OR.(G1X.GT.AMAX1(G1A,G1B)))
     *      GOTO 118
          G2X=G2C+PART*(G2D-G2C)
        ENDIF
      ENDIF
  114 CONTINUE
      LINTS=.TRUE.
C     Correcting the coordinates of the intersection point:
      A=(G2X-G2C)
      B=(G1D-G1C)
      C=(G1X-G1C)
      D=(G2D-G2C)
      IF (ABS(B).GT.ZERO) THEN
        G2X=(C*D)/B+G2C
      ELSEIF (ABS(D).GT.ZERO) THEN
        G1X=(A*B)/D+G1C
      ELSE
        G1X=(G1C+G1D)/2.
        G2X=(G2C+G2D)/2.
      ENDIF
      RETURN
  118 CONTINUE
      LINTS=.FALSE.
      RETURN
      END
C
C=======================================================================
C
      SUBROUTINE RPXMEA(JTRI,ITRI,IRAY,LNEWAR,
     *                  LAB20,G1NEW,G2NEW)
C
C----------------------------------------------------------------------
C Subroutine designed to measure the sides of the triangle JTRI in the
C reference surface and to divide this triangle if it is too large.
C
      INTEGER JTRI,ITRI,IRAY
      LOGICAL LNEWAR,LAB20
      REAL G1NEW,G2NEW
C Input:
C     JTRI ...Index of the measured triangle.
C     ITRI ...Index of last computed triangle.
C     IRAY ...Index of last computed ray.
C     LNEWAR..Indicates whether the new auxiliary ray was computed.
C Output:
C     LNEWAR..Indicates whether the new auxiliary ray is to be computed.
C     LAB20 ..Indicates that inhomogeneous triangles have been formed
C             running RPXMEA.
C     G1NEW,G2NEW ... Coordinates of the new ray.
C
C Subroutines and external functions required:
      EXTERNAL RPDI2G,RPLRIL
      REAL RPDI2G
      LOGICAL RPLRIL
C
C Coded by Petr Bulant
C
C.......................................................................
C Common block /RPARD/:
      INCLUDE 'rpard.inc'
C     rpard.inc
C     AERR ... The distance of boundary rays.
C     PRM0(2) ... Maximum allowed length of the homogeneous triangles
C                 sides (measured on the reference surface).
C............................
C
C Common block /BOURA/ and /DRAYS/:
      INCLUDE 'rp3d.inc'
C     rp3d.inc
C
C.......................................................................
      REAL ZERO
      PARAMETER (ZERO =.0000001)
      INTEGER KTRID(6),KTRIN(6),KTRIS(6)
      INTEGER KRAYA,ITYPEA,ISHA
      REAL G1A,G2A,G11A,G12A,G22A,X1A,X2A,G1X1A,G2X1A,G1X2A,G2X2A
      INTEGER KRAYB,ITYPEB,ISHB
      REAL G1B,G2B,G11B,G12B,G22B,X1B,X2B,G1X1B,G2X1B,G1X2B,G2X2B
      INTEGER KRAYC,ITYPEC,ISHC
      REAL G1C,G2C,G11C,G12C,G22C,X1C,X2C,G1X1C,G2X1C,G1X2C,G2X2C
      INTEGER KRAYD,ITYPED,ISHD
      REAL G1D,G2D
      INTEGER KRAYI,KRAYJ,ITYPE,ISH
      REAL G1I,G2I,G1J,G2J,G1K,G2K
      REAL G11,G12,G22
      REAL X1,X2,G1X1,G2X1,G1X2,G2X2
      REAL AREA,AERR2
      REAL G11POM,G12POM,G22POM
      REAL DG1,DG2,DETG
      REAL DIST2A,DIST2B,DIST2C
      INTEGER I1,I2
      LOGICAL LRAY,LTRI
      SAVE KRAYA,KRAYB,KRAYC,ISHA,KTRID,AERR2
C     ZERO..Constant used to decide whether the real variable .EQ. zero.
C     KTRID...Parameters of the triangle to be measured.
C     KTRIN...Parameters of the new triangle to be registrated
C             (new column to be added into array KTRI).
C     KTRIS...Parameters of the examined triangle.
C     G1X1,G2X1,G1X2,G2X2 ...Derivations.
C     KRAYA,(B),(C),..  .... Signs of rays      |   Auxiliary
C     ITYPEA,(B),(C),..  ... Types of rays      |   variables used
C     ISHA,(B),(C)...Value of history function  |   for different rays.
C     GiA,(B),(C)........ Parameters of rays    |
C     AREA ...Auxiliary variable (area of the triangle).
C     DIST2A,B,C ...Auxiliary variables (second powers of the lengths
C                                        of the triangle sides).
C     AERR2 ... Second power of the distance of boundary rays.
C     GiiPOM ...Auxiliary variables (metric tensor).
C     DG1,DG2,DIST2 ..auxiliary variables.
C     DETG... Determinant.
C     I1,2,3..Implied-do variables or variables controlling the loop.
C     LRAY ...Indicates whether the ray IRAY is in memory.
C     LTRI ...Indicates whether the triangle ITRI is in memory.
C-----------------------------------------------------------------------
C
      IF (IRAY.EQ.0) THEN
        AERR2=AERR**2
        NDRAYS=0
      ENDIF
C
      IF (LNEWAR) GOTO 10
C
      CALL RPTRI3(JTRI,LTRI,KTRID)
      IF ((.NOT.LTRI).OR.(KTRID(6).NE.3)) THEN
        LNEWAR=.FALSE.
        RETURN
      ENDIF
C     Calculating lengths of the triangle's sides:
      KRAYA=KTRID(1)
      CALL RPRAY(KTRID(1),LRAY,ITYPEA,ISHA,G1A,G2A,G11A,G12A,G22A,
     *           X1A,X2A,G1X1A,G2X1A,G1X2A,G2X2A)
      IF (.NOT.LRAY) CALL RPERR(1)
      IF (ISHA.LE.0) THEN
        LNEWAR=.FALSE.
        RETURN
      ENDIF
      KRAYB=KTRID(2)
      CALL RPRAY(KTRID(2),LRAY,ITYPEB,ISHB,G1B,G2B,G11B,G12B,G22B,
     *           X1B,X2B,G1X1B,G2X1B,G1X2B,G2X2B)
      IF (.NOT.LRAY) CALL RPERR(1)
      KRAYC=KTRID(3)
      CALL RPRAY(KTRID(3),LRAY,ITYPEC,ISHC,G1C,G2C,G11C,G12C,G22C,
     *           X1C,X2C,G1X1C,G2X1C,G1X2C,G2X2C)
      IF (.NOT.LRAY) CALL RPERR(1)
      IF ((ISHA.NE.ISHB).OR.(ISHA.NE.ISHC)) THEN
        KTRID(6)=0
        CALL RPTRI2(KTRID(4),LTRI,KTRID)
        IF (.NOT.LTRI) CALL RPERR(2)
        LAB20=.TRUE.
        LNEWAR=.FALSE.
        RETURN
      ENDIF
C     ..A,..B,..C .. Vertices of measured triangle.
C     Controlling the size of triangle surface :
      G11POM=(G11A+G11C+G11B)/3.
      G12POM=(G12A+G12C+G12B)/3.
      G22POM=(G22A+G22C+G22B)/3.
      DG1=G1B-G1A
      DG2=G2B-G2A
      DETG=G11POM*G22POM - G12POM*G12POM
      IF (DETG.LT.ZERO) CALL RPERR(4)
      AREA=SQRT(DETG)*((DG1*(G2C-G2A)-DG2*(G1C-G1A))*.5)
      IF (AREA.LT.(AERR2*0.4330127)) THEN
C       0.4330127=Sqrt(3)/4
C       Triangle too small, it is not to be divided:
        LNEWAR=.FALSE.
        RETURN
      ENDIF
C     Measuring the size of triangle sides using matrix G:
      G11POM=(G11A+G11B)/2.
      G12POM=(G12A+G12B)/2.
      G22POM=(G22A+G22B)/2.
      DIST2A=RPDI2G(G1A,G2A,G1B,G2B,G11POM,G12POM,G22POM)
      G11POM=(G11B+G11C)/2.
      G12POM=(G12B+G12C)/2.
      G22POM=(G22B+G22C)/2.
      DIST2B=RPDI2G(G1B,G2B,G1C,G2C,G11POM,G12POM,G22POM)
      G11POM=(G11A+G11C)/2.
      G12POM=(G12A+G12C)/2.
      G22POM=(G22A+G22C)/2.
      DIST2C=RPDI2G(G1A,G2A,G1C,G2C,G11POM,G12POM,G22POM)
C
      IF ((DIST2A.LE.AERR2).OR.(DIST2B.LE.AERR2).OR.
     *    (DIST2C.LE.AERR2)) THEN
C       Triangle too small, it is not to be divided:
        LNEWAR=.FALSE.
        RETURN
      ENDIF
C
C
C     Measuring the size of triangle sides on the reference surface:
      DIST2A=((X1B-X1A)**2+(X2B-X2A)**2)
      DIST2B=((X1C-X1B)**2+(X2C-X2B)**2)
      DIST2C=((X1A-X1C)**2+(X2A-X2C)**2)
C
      IF ((DIST2A.LE.PRM0(2)).AND.(DIST2B.LE.PRM0(2)).AND.
     *    (DIST2C.LE.PRM0(2))) THEN
C       The triangle is O.K.
        RETURN
      ENDIF
C
C     Choosing the longest side to be divided:
      IF ((DIST2A.GE.DIST2B).AND.(DIST2A.GE.DIST2C)) THEN
C       No action.
      ELSEIF ((DIST2B.GE.DIST2A).AND.(DIST2B.GE.DIST2C)) THEN
         KRAYD= KRAYA
          ISHD=  ISHA
           G1D=   G1A
           G2D=   G2A
         KRAYA= KRAYB
          ISHA=  ISHB
           G1A=   G1B
           G2A=   G2B
         KRAYB= KRAYC
          ISHB=  ISHC
           G1B=   G1C
           G2B=   G2C
         KRAYC= KRAYD
          ISHC=  ISHD
           G1C=   G1D
           G2C=   G2D
      ELSEIF ((DIST2C.GE.DIST2A).AND.(DIST2C.GE.DIST2B)) THEN
         KRAYD= KRAYA
          ISHD=  ISHA
           G1D=   G1A
           G2D=   G2A
         KRAYA= KRAYC
          ISHA=  ISHC
           G1A=   G1C
           G2A=   G2C
         KRAYC= KRAYB
          ISHC=  ISHB
           G1C=   G1B
           G2C=   G2B
         KRAYB= KRAYD
          ISHB=  ISHD
           G1B=   G1D
           G2B=   G2D
      ENDIF
C     Proposing the ray parameters of a new ray:
      G1NEW=(G1A+G1B)/2.
      G2NEW=(G2A+G2B)/2.
      IF (((G1NEW.EQ.G1A).AND.(G2NEW.EQ.G2A)).OR.
     *    ((G1NEW.EQ.G1B).AND.(G2NEW.EQ.G2B))) CALL RPERR(3)
C
C     Checking whether the ray has not yet been computed:
  2   CONTINUE
      IF (NDRAYS.GT.0) THEN
        DO 5, I1=1,NDRAYS
          CALL RPRAY(KDRAYS(I1),LRAY,ITYPED,ISHD,G1D,G2D,
     *              G11,G12,G22,X1,X2,G1X1,G2X1,G1X2,G2X2)
          IF (.NOT.LRAY) THEN
            DO 3, I2=I1,NDRAYS-1
              KDRAYS(I2)=KDRAYS(I2+1)
  3         CONTINUE
            NDRAYS=NDRAYS-1
            GOTO 2
          ENDIF
          IF ((ABS(G1D-G1NEW).LT.ZERO).AND.
     *        (ABS(G2D-G2NEW).LT.ZERO)) THEN
C           New ray found in the array KDRAYS:
            KRAYD=KDRAYS(I1)
            DO 4, I2=I1,NDRAYS-1
              KDRAYS(I2)=KDRAYS(I2+1)
 4          CONTINUE
            NDRAYS=NDRAYS-1
            GOTO 21
          ENDIF
 5      CONTINUE
      ENDIF
      LNEWAR=.TRUE.
      RETURN
C
C
  10  CONTINUE
      KRAYD=IRAY
      CALL RPRAY(IRAY,LRAY,ITYPED,ISHD,G1D,G2D,G11,G12,G22,
     *           X1,X2,G1X1,G2X1,G1X2,G2X2)
      IF (.NOT.LRAY) CALL RPERR(1)
C     The ray is to be stored to the array KDRAYS:
      NDRAYS=NDRAYS+1
      IF (NDRAYS.GT.MDRAYS) THEN
C         RP3D-025
          CALL ERROR('RP3D-025: Insufficient memory for KDRAYS.')
C         This error may be caused by too small dimension of array
C         KDRAYS. Try to enlarge the parameter MDRAYS in common block
C         DRAYS in file
C         rp3d.inc.
      ENDIF
      KDRAYS(NDRAYS)=KRAYD
C
C     When the ray D is on the sides of the basic triangle which
C     contains the divided triangle, storing it to the KBR:
      IF (KTRID(5).NE.0) THEN
        CALL RPTRI3(KTRID(5),LTRI,KTRIS)
        IF (.NOT.LTRI) CALL RPERR(2)
      ELSE
        KTRIS(1)=KTRID(1)
        KTRIS(2)=KTRID(2)
        KTRIS(3)=KTRID(3)
      ENDIF
      CALL RPRAY(KTRIS(1),LRAY,ITYPE,ISH,G1I,G2I,G11,G12,G22,
     *           X1,X2,G1X1,G2X1,G1X2,G2X2)
      IF (.NOT.LRAY) CALL RPERR(1)
      CALL RPRAY(KTRIS(2),LRAY,ITYPE,ISH,G1J,G2J,G11,G12,G22,
     *           X1,X2,G1X1,G2X1,G1X2,G2X2)
      IF (.NOT.LRAY) CALL RPERR(1)
      CALL RPRAY(KTRIS(3),LRAY,ITYPE,ISH,G1K,G2K,G11,G12,G22,
     *           X1,X2,G1X1,G2X1,G1X2,G2X2)
      IF (.NOT.LRAY) CALL RPERR(1)
      IF (RPLRIL(G1D,G2D,G1K,G2K,G1I,G2I)) THEN
C       Boundary rays are lying on the side IK (side 3,1):
        KRAYI=KTRIS(1)
        KRAYJ=KTRIS(3)
      ELSEIF (RPLRIL(G1D,G2D,G1I,G2I,G1J,G2J)) THEN
C       Boundary rays are lying on the side IJ (side 1,2):
        KRAYI=KTRIS(2)
        KRAYJ=KTRIS(1)
      ELSEIF (RPLRIL(G1D,G2D,G1J,G2J,G1K,G2K)) THEN
C       Boundary rays are lying on the side JK (side 2,3):
        KRAYI=KTRIS(3)
        KRAYJ=KTRIS(2)
      ELSE
C       Ray is not on the sides of the basic triangle:
        GOTO 21
      ENDIF
      CALL RPKBR(KRAYI,KRAYJ,KRAYD)
C
  21  CONTINUE
      LNEWAR=.FALSE.
      IF (ISHD.EQ.ISHA) THEN
C       New triangles will be homogeneous:
        KTRIN(6)=3
      ELSE
C       A strange ray was identified inside the triangle.
C       New triangles will be inhomogeneous:
        KTRIN(6)=0
        LAB20=.TRUE.
      ENDIF
C     Now dividing the triangle KTRID into two new triangles:
      KTRID(6)=2
      CALL RPTRI2(KTRID(4),LTRI,KTRID)
      ITRI=ITRI+1
      KTRIN(1)=KRAYA
      KTRIN(2)=KRAYD
      KTRIN(3)=KRAYC
      KTRIN(4)=ITRI
      IF (KTRID(5).EQ.0) THEN
        KTRIN(5)=KTRID(4)
      ELSE
        KTRIN(5)=KTRID(5)
      ENDIF
      CALL RPTRI1(ITRI,KTRIN)
      CALL RPSTOR('T',1,KTRIN)
      ITRI=ITRI+1
      KTRIN(1)=KRAYD
      KTRIN(2)=KRAYB
      KTRIN(3)=KRAYC
      KTRIN(4)=ITRI
      CALL RPTRI1(ITRI,KTRIN)
      CALL RPSTOR('T',1,KTRIN)
C
      RETURN
      END
C
C=======================================================================
C
      SUBROUTINE RPLRTC(G1NEW,G2NEW,KTRID,KRAYI,KRAYJ,IGOTO)
C
C----------------------------------------------------------------------
      REAL G1NEW,G2NEW
      INTEGER KTRID(6),KRAYI,KRAYJ,IGOTO
C Subroutine designed to decide, whether the ray NEW lies on the
C sides of the basic triangle containing the triangle KTRID.
C If so, the subroutine looks, whether the ray NEW lies on the
C boundary of the covered part of the normalized ray domain.
C
C Input:
C     G1NEW,G2NEW ..  Coordinates of the ray.
C     KTRID  ......   All the parameters of the triangle.
C
C Output:
C     KRAYI,KRAYJ ... Indices of the rays forming the side of the basic
C                     triangle where the ray NEW lies.
C     IGOTO:  1 in case that the ray NEW lies on the side of the
C               basic triangle, which contains the triangle KTRID,
C               and that the ray NEW lies on the polyline - boundary
C               of the covered part of the normalized ray domain.
C             0 otherwise.
C
C Coded by Petr Bulant
C
C Subroutines and external functions required:
      EXTERNAL RPLRIL
      LOGICAL RPLRIL
C......................................................................
C
C Common blocks /GLIM/ and /POLY/:
      INCLUDE 'rp3d.inc'
C     rp3d.inc
C ...........................
      INTEGER KTRIS(6)
      INTEGER ITYPE,ISH
      REAL G1I,G2I,G1J,G2J,G1K,G2K
      REAL G11,G12,G22,X1,X2,G1X1,G2X1,G1X2,G2X2
      INTEGER I1
      LOGICAL LTRI,LRAY
C......................................................................
      IF ((G1NEW.EQ.GLIMIT(1)).OR.(G1NEW.EQ.GLIMIT(2)).OR.
     *    (G2NEW.EQ.GLIMIT(3))) THEN
        IGOTO=1
        KRAYI=0
        RETURN
      ENDIF
      IF (KTRID(5).NE.0) THEN
        CALL RPTRI3(KTRID(5),LTRI,KTRIS)
        IF (.NOT.LTRI) CALL RPERR(2)
      ELSE
        KTRIS(1)=KTRID(1)
        KTRIS(2)=KTRID(2)
        KTRIS(3)=KTRID(3)
      ENDIF
      CALL RPRAY(KTRIS(1),LRAY,ITYPE,ISH,G1I,G2I,G11,G12,G22,
     *           X1,X2,G1X1,G2X1,G1X2,G2X2)
      IF (.NOT.LRAY) CALL RPERR(1)
      CALL RPRAY(KTRIS(2),LRAY,ITYPE,ISH,G1J,G2J,G11,G12,G22,
     *           X1,X2,G1X1,G2X1,G1X2,G2X2)
      IF (.NOT.LRAY) CALL RPERR(1)
      CALL RPRAY(KTRIS(3),LRAY,ITYPE,ISH,G1K,G2K,G11,G12,G22,
     *           X1,X2,G1X1,G2X1,G1X2,G2X2)
      IF (.NOT.LRAY) CALL RPERR(1)
      IF (RPLRIL(G1NEW,G2NEW,G1K,G2K,G1I,G2I)) THEN
C       New ray is lying on the side IK (side 3,1):
        KRAYI=KTRIS(1)
        KRAYJ=KTRIS(3)
      ELSEIF (RPLRIL(G1NEW,G2NEW,G1I,G2I,G1J,G2J)) THEN
C       New ray is lying on the side IJ (side 1,2):
        KRAYI=KTRIS(2)
        KRAYJ=KTRIS(1)
      ELSEIF (RPLRIL(G1NEW,G2NEW,G1J,G2J,G1K,G2K)) THEN
C       New ray is lying on the side JK (side 2,3):
        KRAYI=KTRIS(3)
        KRAYJ=KTRIS(2)
      ELSE
C       Ray is not on the sides of the basic triangle:
        IGOTO=0
        RETURN
      ENDIF
C     Loop for the rays on the boundary of the covered part
C     of the normalized ray domain:
      DO 10, I1=1,NPL-1
        IF (KPL(I1).EQ.KRAYI) THEN
          IF (KPL(I1+1).EQ.KRAYJ) THEN
C           Ray is on polyline:
            IGOTO=1
            RETURN
          ENDIF
        ENDIF
  10  CONTINUE
      IGOTO=0
      END
C
C=======================================================================
C
      SUBROUTINE RPDPA(G1C,G2C,G1A,G2A,G1B,G2B,G11,G12,G22,
     *                 VERTEX,G1X,G2X)
C
C----------------------------------------------------------------------
      REAL G1A,G2A,G1B,G2B,G1C,G2C,G11,G12,G22,G1X,G2X
      CHARACTER VERTEX
C
C This subroutine computes the normalized parameters of the ray X,
C which lies on the abscissa A-B and is nearest to the point C.
C
C Input:  coordinates of the three points, value of the symmetric metric
C         tensor which is to be used.
C
C Output: vertex .. Indicates the position of the nearest point:
C             'A' ..  Point A (vertex of the abscissa).
C             'B' ..  Point B (vertex of the abscissa).
C             'X' ..  Other point of the abscissa.
C         G1X,G2X . Coordinates of the nearest point.
C
C Subroutines and external functions required:
      EXTERNAL RPDI2G,RPLRIT,RPLRIP
      REAL RPDI2G
      LOGICAL RPLRIT,RPLRIP
C
C Coded by Petr Bulant
C
C.......................................................................
      REAL ZERO
      PARAMETER (ZERO=.0000001)
      REAL AAA,BBB,CCC,PAR
      REAL DIST2
      REAL A,B
C     ZERO...Constant used to decide whether the real variable.EQ.zero.
C     AAA,BBB,PART,A,B,C,D ... Auxiliary variables.
C-----------------------------------------------------------------------
C
      A=(G1B-G1A)
      B=(G2B-G2A)
      AAA=A*G11+B*G12
      BBB=A*G12+B*G22
      CCC=-A*G11*G1C-A*G12*G2C-B*G12*G1C-B*G22*G2C
      DIST2=RPDI2G(G1A,G2A,G1B,G2B,G11,G12,G22)
      IF (DIST2.LT.ZERO) THEN
        G1X=(G1A+G1B)/2.
        G2X=(G2A+G2B)/2.
        VERTEX='X'
        RETURN
      ENDIF
      PAR=(-CCC-G1A*AAA-G2A*BBB)/(A*AAA+B*BBB)
      IF (PAR.GT.1.) THEN
        G1X=G1B
        G2X=G2B
        VERTEX='B'
      ELSEIF (PAR.LT.0.) THEN
        G1X=G1A
        G2X=G2A
        VERTEX='A'
      ELSE
        G1X=G1A+PAR*A
        G2X=G2A+PAR*B
        VERTEX='X'
      ENDIF
      RETURN
      END
C
C=======================================================================
C
      SUBROUTINE RPHPDI(NPOLH,KPOLH,GPOLH,IRAY,ITRI,KTRID,
     *                  LNEWAR,G1NEW,G2NEW)
C
C-----------------------------------------------------------------------
      INTEGER MPOLH
      PARAMETER (MPOLH=500)
      INTEGER NPOLH,KPOLH(MPOLH,4)
      REAL GPOLH(MPOLH,2)
      INTEGER IRAY,ITRI,KTRID(6)
      LOGICAL LNEWAR
      REAL G1NEW,G2NEW
C
C Subroutine designed to divide the homogeneous polygon KPOLH into
C the homogeneous triangles. NPOLH should be greater than 3.
C Method: searching for the two neighbouring shortest polygon
C         sides, adding new ray and making thus two triangles.
C Note: inhomogeneous triangles marked as homogeneous may be created
C       (RPXMEA must be run after).
C Subroutine also determines normalized ray parameters of a new ray,
C if needed.
C
C Input:
C     NPOLH...Number of rays forming the polygons GPOLH and KPOLH.
C     KPOLH(I,1)...Indices of the rays forming the homogeneous polygon
C                  to be divided into homogeneous triangles.
C     KPOLH(I,2) ...Sheets of rays forming the polygon.
C     KPOLH(I,3) ...Types of rays forming the polygon.
C     KPOLH(I,4) ...For boundary ray the value of history function of
C              the other ray from the pair of the boundary rays or zero.
C     GPOLH(I,1),GPOLH(I,2) ...Normalized parameters of the rays forming
C                              the homogeneous polygon.
C     IRAY... Index of the last computed ray.
C     ITRI... Index of the last computed triangle.
C     KTRID.. Parameters of the divided triangle.
C     LNEWAR... Indicates whether the new ray was actually traced.
C Output:
C     NPOLH,KPOLH,GPOLH ... New values.
C     G1NEW,G2NEW...If a new ray is to be traced,
C                   parameters of the new ray.
C     LNEWAR... Indicates whether the new ray is to be computed.
C
C Subroutines and external functions required:
      EXTERNAL RPDI2G,RPLRIT,RPLRIP,RPLRIL,RPLTCR
      REAL RPDI2G
      LOGICAL RPLRIT,RPLRIP,RPLRIL,RPLTCR
C
C Coded by Petr Bulant
C
C
C.......................................................................
C Common block /RPARD/:
      INCLUDE 'rpard.inc'
C     rpard.inc
C     AERR ... The distance of boundary rays.
C............................
C
C Common block /BOURA/:
      INCLUDE 'rp3d.inc'
C     rp3d.inc
C
C.......................................................................
      REAL ZERO,ZERO1
      PARAMETER (ZERO =.000001)
      PARAMETER (ZERO1=.0000000001)
      REAL AR0
      REAL NEAR
C     PARAMETER (NEAR=.618**2)
      PARAMETER (NEAR=.471**2)
C     0.471=3/2 * SQRT(2)/2
      INTEGER KTRIN(6)
      REAL G1,G2,G11,G12,G22
      REAL X1,X2,G1X1,G2X1,G1X2,G2X2
      INTEGER ITYPE,ISH,ISHEET
      INTEGER ITYPEA,ISHA,ITYPEB,ISHB
      REAL G1A,G2A,G11A,G12A,G22A,G1B,G2B,G11B,G12B,G22B
      REAL G1M,G2M,G11M,G12M,G22M,G1N,G2N,G11N,G12N,G22N
      INTEGER KRAYI,KRAYJ
      REAL G1X,G2X
      REAL DIST2,MINDIS,NEAR2
      REAL G11POM,G12POM,G22POM
      REAL AREA,AREA1,AREA2,AAA,BBB,DG1,DG2,DETG
      INTEGER KPOL(4)
      REAL GPOL(4,2)
      REAL COS
      INTEGER IDIAG,IGOTO
      INTEGER I1,I2,I3,I4,I5
      INTEGER J1,J2
      CHARACTER VERTEX
      LOGICAL LRAY,LINTS
      SAVE KRAYI,KRAYJ,IGOTO,KPOL,GPOL
C     ZERO... Constant used to decide whether the real variable.EQ.zero.
C     AR0 ... Area of the smallest considered triangle.
C     NEAR... Relative length to identify rays.
C     KTRIN...Parameters of the new triangle to be registrated (new
C             column to be added into array KTRI).
C     X1,X2 ..Coordinates of the ray on the reference surface.
C     G1X1,G2X1,G1X2,G2X2 ... Derivations of ray parameters according to
C                             surface coordinates.
C     KRAYA,B,..      ...  Signs of rays      |   Auxiliary
C     ITYPEA,B,..     ...  Types of rays      |   variables used
C     ISHA,B,..  .. Value of history function |   for different rays.
C     Gi(i)A,B,..     ...  Parameters of rays |  (always commented)
C     DIST2 ... Second power of the distance of two rays.
C     MINDIS... Minimum of the distances between the rays.
C     NEAR2 ... Length to identify rays.
C     GiiPOM... Average value of the metric tensor.
C     AREA,AREA1,2  ... Auxiliary variable (area of the triangle).
C     DG1,DG2,AAA,BBB,DETG ... Auxiliary variables used to compute
C               the parameters of a new ray.
C     KPOL,GPOL ... Indices and normalized ray parameters of the four
C               rays, which become vertices of the two new triangles.
C     COS ... Cosine of the angle of two vectors.
C     IDIAG ..Sequence in KPOLH of the ray whose neighbouring rays form
C             the shortest polygon diagonal.
C     I1,2 .. Implied-do variables or variables controlling the loop.
C     I1,I2,I3 ... From label 1 the rays where a new ray is to be added.
C     J1,2 .. Auxiliary variables (numbers).
C     VERTEX..Identifies, which point of the abscissa is the nearest
C             to the ray.
C     LRAY ...Indicates whether the ray IRAY is in memory.
C     LINTS...Indicates whether the intersection appeared.
C-----------------------------------------------------------------------
      IF (LNEWAR) THEN
        LNEWAR=.FALSE.
        GOTO (120,150) IGOTO
      ENDIF
      AR0=(AERR**2)*0.4330127/9.
C
C     Checking the size of the homogeneous polygon:
      AREA1=0.
      DO 2, I1=1,NPOLH-2
        CALL RPRAY(KPOLH(I1,1),LRAY,ITYPE,ISH,G1,G2,G11,G12,G22,
     *             X1,X2,G1X1,G2X1,G1X2,G2X2)
        IF (.NOT.LRAY) CALL RPERR(1)
        DG1=GPOLH(I1,1)-GPOLH(NPOLH,1)
        DG2=GPOLH(I1,2)-GPOLH(NPOLH,2)
        DETG=G11*G22 - G12*G12
        IF (DETG.LT.ZERO) CALL RPERR(4)
        AREA=SQRT(DETG)*((DG1*(GPOLH(I1+1,2)-GPOLH(I1,2))
     *       -DG2*(GPOLH(I1+1,1)-GPOLH(I1,1)))*.5)
        AREA1=AREA1+AREA
  2   CONTINUE
      IF (AREA1.LT.AR0) THEN
C       The area of the polygon is quite little,
C       polygon is not to be divided.
C       The polygon will be simply divided into homogeneous triangles:
        I1=1
  4     CONTINUE
          IF(I1.GT.1) THEN
            J1=I1-1
          ELSE
            J1=NPOLH
          ENDIF
          IF(I1.LT.NPOLH) THEN
            J2=I1+1
          ELSE
            J2=1
          ENDIF
          IF (RPLRIT(.FALSE.,GPOLH(J1,1),GPOLH(J1,2),GPOLH(I1,1),
     *        GPOLH(I1,2),GPOLH(J2,1),GPOLH(J2,2),G1A,G2A,AREA)) THEN
            IF (.NOT.RPLTCR(J1,I1,GPOLH(J2,1),GPOLH(J2,2),
     *                      NPOLH,GPOLH)) THEN
              ITRI=ITRI+1
              KTRIN(1)=KPOLH(J1,1)
              KTRIN(2)=KPOLH(I1,1)
              KTRIN(3)=KPOLH(J2,1)
              KTRIN(4)=ITRI
              IF (KTRID(5).EQ.0) THEN
                KTRIN(5)=KTRID(4)
              ELSE
                KTRIN(5)=KTRID(5)
              ENDIF
              KTRIN(6)=3
              CALL RPTRI1(ITRI,KTRIN)
              CALL RPSTOR('T',IRAY,KTRIN)
              NPOLH=NPOLH-1
              DO 6, I2=I1,NPOLH
                KPOLH(I1,1)=KPOLH(I1+1,1)
                KPOLH(I1,2)=KPOLH(I1+1,2)
                KPOLH(I1,3)=KPOLH(I1+1,3)
                KPOLH(I1,4)=KPOLH(I1+1,4)
                GPOLH(I1,1)=GPOLH(I1+1,1)
                GPOLH(I1,2)=GPOLH(I1+1,2)
  6           CONTINUE
              I1=1
              GOTO 4
            ENDIF
          ENDIF
        I1=I1+1
        IF (I1.LE.NPOLH) GOTO 4
        NPOLH=0
        LNEWAR=.FALSE.
        RETURN
      ENDIF
C
C
C     Easy dividing polygon with four rays:
  10  CONTINUE
      IF (NPOLH.EQ.4) THEN
        DO 8, I1=1,4
          KPOL(I1)=KPOLH(I1,1)
          GPOL(I1,1)=GPOLH(I1,1)
          GPOL(I1,2)=GPOLH(I1,2)
  8     CONTINUE
        NPOLH=0
        LNEWAR=.FALSE.
        GOTO 100
      ENDIF
C
C
C     Choosing the ray with minimal distance from his neighbours:
      IDIAG=0
      MINDIS=999999.
      DO 155, I2=1,NPOLH
        I1=I2-1
        IF (I1.EQ.0) I1=NPOLH
        I3=I2+1
        IF (I3.EQ.NPOLH+1) I3=1
        IF (KPOLH(I2,1).GT.0) THEN
          CALL RPRAY(IABS(KPOLH(I2,1)),LRAY,ITYPEA,ISHA,G1A,G2A,G11A,
     *               G12A,G22A,X1,X2,G1X1,G2X1,G1X2,G2X2)
          IF (.NOT.LRAY) CALL RPERR(1)
          DIST2=RPDI2G(G1A,G2A,GPOLH(I1,1),GPOLH(I1,2),G11A,G12A,G22A)
          DIST2=DIST2 +
     *          RPDI2G(G1A,G2A,GPOLH(I3,1),GPOLH(I3,2),G11A,G12A,G22A)
          IF (DIST2.LT.MINDIS) THEN
            IDIAG=I2
            MINDIS=DIST2
          ENDIF
        ENDIF
  155 CONTINUE
C
C
      IF (IDIAG.LE.0) THEN
C       All rays marked as not suitable for adding a new ray.
C       Trying to find a right-handed triangle which does not
C       contain any ray of the homogeneous polygon:
        IDIAG=2
        DO 157, I1=1,NPOLH
          IF(I1.GT.1) THEN
            J1=I1-1
          ELSE
            J1=NPOLH
          ENDIF
          IF(I1.LT.NPOLH) THEN
            J2=I1+1
          ELSE
            J2=1
          ENDIF
          IF (RPLRIT(.FALSE.,GPOLH(J1,1),GPOLH(J1,2),GPOLH(I1,1),
     *        GPOLH(I1,2),GPOLH(J2,1),GPOLH(J2,2),G1A,G2A,AREA)) THEN
            IF (.NOT.RPLTCR(J1,I1,GPOLH(J2,1),GPOLH(J2,2),
     *                      NPOLH,GPOLH)) THEN
              CALL RPRAY(IABS(KPOLH(J1,1)),LRAY,ITYPEA,ISHA,G1A,G2A,G11A
     *                   ,G12A,G22A,X1,X2,G1X1,G2X1,G1X2,G2X2)
              IF (.NOT.LRAY) CALL RPERR(1)
              CALL RPRAY(IABS(KPOLH(J2,1)),LRAY,ITYPEB,ISHB,G1B,G2B,G11B
     *                   ,G12B,G22B,X1,X2,G1X1,G2X1,G1X2,G2X2)
              IF (.NOT.LRAY) CALL RPERR(1)
              G11POM=(G11A+G11B)/2.
              G12POM=(G12A+G12B)/2.
              G22POM=(G22A+G22B)/2.
              DIST2=RPDI2G(G1A,G2A,G1B,G2B,G11POM,G12POM,G22POM)
              IF (DIST2.LT.MINDIS) THEN
                  IDIAG=I1
                  MINDIS=DIST2
              ENDIF
            ENDIF
          ENDIF
  157   CONTINUE
        IF(IDIAG.GT.1) THEN
          J1=IDIAG-1
        ELSE
          J1=NPOLH
        ENDIF
        IF(IDIAG.LT.NPOLH) THEN
          J2=IDIAG+1
        ELSE
          J2=1
        ENDIF
C       Separating the chosen triangle:
        IF (RPLRIT(.FALSE.,GPOLH(J1,1),GPOLH(J1,2),GPOLH(IDIAG,1),
     *      GPOLH(IDIAG,2),GPOLH(J2,1),GPOLH(J2,2),G1A,G2A,AREA)) THEN
          ITRI=ITRI+1
          KTRIN(1)=IABS(KPOLH(J1,1))
          KTRIN(2)=IABS(KPOLH(IDIAG,1))
          KTRIN(3)=IABS(KPOLH(J2,1))
          KTRIN(4)=ITRI
          IF (KTRID(5).EQ.0) THEN
            KTRIN(5)=KTRID(4)
          ELSE
            KTRIN(5)=KTRID(5)
          ENDIF
          KTRIN(6)=3
          CALL RPTRI1(ITRI,KTRIN)
          CALL RPSTOR('T',IRAY,KTRIN)
        ENDIF
        NPOLH=NPOLH-1
        DO 158, I1=IDIAG,NPOLH
          KPOLH(I1,1)=KPOLH(I1+1,1)
          KPOLH(I1,2)=KPOLH(I1+1,2)
          KPOLH(I1,3)=KPOLH(I1+1,3)
          KPOLH(I1,4)=KPOLH(I1+1,4)
          GPOLH(I1,1)=GPOLH(I1+1,1)
          GPOLH(I1,2)=GPOLH(I1+1,2)
  158   CONTINUE
        LNEWAR=.FALSE.
        GOTO 200
      ENDIF
C
C
C     The new ray is to be computed to create new triangles and
C     separate them from the homogeneous polygon.
C
C     Sorting the rays of the polygon,
C     so that the ray I2 is the third one:
      I2=IDIAG
      IF (I2.LT.3) THEN
        DO 12, I4=1,3-I2
          IF (NPOLH.GE.MPOLH) THEN
C           RP3D-026
            CALL ERROR('RP3D-026: Insufficient memory for KPOLH.')
C           This error may be caused by too small dimension of array
C           KPOLH. Try to enlarge the parameter MPOLH at the
C           beginning of this subroutine.
          ENDIF
          DO 11, I5=NPOLH+1,2,-1
            KPOLH(I5,1)=KPOLH(I5-1,1)
            KPOLH(I5,2)=KPOLH(I5-1,2)
            KPOLH(I5,3)=KPOLH(I5-1,3)
            KPOLH(I5,4)=KPOLH(I5-1,4)
            GPOLH(I5,1)=GPOLH(I5-1,1)
            GPOLH(I5,2)=GPOLH(I5-1,2)
  11      CONTINUE
          KPOLH(1,1)=KPOLH(NPOLH+1,1)
          KPOLH(1,2)=KPOLH(NPOLH+1,2)
          KPOLH(1,3)=KPOLH(NPOLH+1,3)
          KPOLH(1,4)=KPOLH(NPOLH+1,4)
          GPOLH(1,1)=GPOLH(NPOLH+1,1)
          GPOLH(1,2)=GPOLH(NPOLH+1,2)
  12    CONTINUE
      ELSEIF (I2.GT.3) THEN
        DO 14, I4=1,I2-3
          IF (NPOLH.GE.MPOLH) THEN
C           RP3D-027
            CALL ERROR('RP3D-027: Insufficient memory for KPOLH.')
C           This error may be caused by too small dimension of array
C           KPOLH. Try to enlarge the parameter MPOLH at the
C           beginning of this subroutine.
          ENDIF
          KPOLH(NPOLH+1,1)=KPOLH(1,1)
          KPOLH(NPOLH+1,2)=KPOLH(1,2)
          KPOLH(NPOLH+1,3)=KPOLH(1,3)
          KPOLH(NPOLH+1,4)=KPOLH(1,4)
          GPOLH(NPOLH+1,1)=GPOLH(1,1)
          GPOLH(NPOLH+1,2)=GPOLH(1,2)
          DO 13, I5=1,NPOLH
            KPOLH(I5,1)=KPOLH(I5+1,1)
            KPOLH(I5,2)=KPOLH(I5+1,2)
            KPOLH(I5,3)=KPOLH(I5+1,3)
            KPOLH(I5,4)=KPOLH(I5+1,4)
            GPOLH(I5,1)=GPOLH(I5+1,1)
            GPOLH(I5,2)=GPOLH(I5+1,2)
  13      CONTINUE
  14    CONTINUE
      ENDIF
      I1=2
      I2=3
      I3=4
C
C
      IF (IABS(KPOLH(I1,1)).EQ.IABS(KPOLH(I3,1))) THEN
C       This part of the homogeneous polygon will escape notice:
        KPOLH(1,1)=IABS(KPOLH(1,1))
        KPOLH(2,1)=IABS(KPOLH(2,1))
        DO 15, I4=I2,NPOLH-2
          KPOLH(I4,1)=IABS(KPOLH(I4+2,1))
          KPOLH(I4,2)=KPOLH(I4+2,2)
          KPOLH(I4,3)=KPOLH(I4+2,3)
          KPOLH(I4,4)=KPOLH(I4+2,4)
          GPOLH(I4,1)=GPOLH(I4+2,1)
          GPOLH(I4,2)=GPOLH(I4+2,2)
   15   CONTINUE
        NPOLH=NPOLH-2
        LNEWAR=.FALSE.
        GOTO 200
      ENDIF
C
C
      CALL RPRAY(IABS(KPOLH(I1,1)),LRAY,ITYPE,ISHEET,G1M,G2M,
     *           G11M,G12M,G22M,X1,X2,G1X1,G2X1,G1X2,G2X2)
      IF (.NOT.LRAY) CALL RPERR(1)
      CALL RPRAY(IABS(KPOLH(I3,1)),LRAY,ITYPE,ISHEET,G1N,G2N,
     *           G11N,G12N,G22N,X1,X2,G1X1,G2X1,G1X2,G2X2)
      IF (.NOT.LRAY) CALL RPERR(1)
C     ..M,..N ... Two rays between which we are adding a new ray.
      G11POM=(G11M+G11N)/2.
      G12POM=(G12M+G12N)/2.
      G22POM=(G22M+G22N)/2.
C
C
C     Looking, whether it is not possible to easy separate one
C     triangle I1,I2,I3, if it does not contain any ray of the
C     homogeneous polygon, and if it is not too narrow:
      IF (RPLRIT(.FALSE.,GPOLH(I1,1),GPOLH(I1,2),GPOLH(I2,1),
     *    GPOLH(I2,2),GPOLH(I3,1),GPOLH(I3,2),G1A,G2A,AREA)) THEN
        IF (.NOT.RPLTCR(I1,I2,GPOLH(I3,1),GPOLH(I3,2),
     *                  NPOLH,GPOLH)) THEN
          COS =( (G1N-GPOLH(I2,1))*G11POM*(G1M-GPOLH(I2,1))
     *         + (G1N-GPOLH(I2,1))*G12POM*(G2M-GPOLH(I2,2))
     *         + (G2N-GPOLH(I2,2))*G12POM*(G1M-GPOLH(I2,1))
     *         + (G2N-GPOLH(I2,2))*G22POM*(G2M-GPOLH(I2,2))  )  / SQRT
     *    (RPDI2G(GPOLH(I2,1),GPOLH(I2,2),G1M,G2M,G11POM,G12POM,G22POM)
     *    *RPDI2G(GPOLH(I2,1),GPOLH(I2,2),G1N,G2N,G11POM,G12POM,G22POM))
          IF (COS.GE.-0.5878) THEN
C           This triangle is to be separated:
            ITRI=ITRI+1
            KTRIN(1)=IABS(KPOLH(I1,1))
            KTRIN(2)=IABS(KPOLH(I2,1))
            KTRIN(3)=IABS(KPOLH(I3,1))
            KTRIN(4)=ITRI
            IF (KTRID(5).EQ.0) THEN
              KTRIN(5)=KTRID(4)
            ELSE
              KTRIN(5)=KTRID(5)
            ENDIF
            KTRIN(6)=3
            CALL RPTRI1(ITRI,KTRIN)
            CALL RPSTOR('T',IRAY,KTRIN)
            NPOLH=NPOLH-1
            DO 181, I1=I2,NPOLH
              I3=I1+1
              KPOLH(I1,1)=KPOLH(I3,1)
              KPOLH(I1,2)=KPOLH(I3,2)
              KPOLH(I1,3)=KPOLH(I3,3)
              KPOLH(I1,4)=KPOLH(I3,4)
              GPOLH(I1,1)=GPOLH(I3,1)
              GPOLH(I1,2)=GPOLH(I3,2)
  181       CONTINUE
            LNEWAR=.FALSE.
            GOTO 200
          ENDIF
        ENDIF
      ENDIF
C
C     Proposing of the parameters of the new ray:
  19  AAA=(G11POM*(G1M-G1N)+G12POM*(G2M-G2N))
      BBB=(G12POM*(G1M-G1N)+G22POM*(G2M-G2N))
      DETG=G11POM*G22POM - G12POM*G12POM
      IF (DETG.LT.ZERO) CALL RPERR(4)
      DIST2=(G1M-G1N)*AAA + (G2M-G2N)*BBB
      NEAR2=DIST2*NEAR
      IF (DIST2.LT.ZERO1) DIST2=ZERO1
CCC   NEAR2=MINDIS*NEAR
CCC   NEAR2=DIST2*NEAR
      G1NEW=(G1M+G1N)/2. + SQRT(MINDIS/DIST2)*0.5*SQRT(3./DETG)*BBB
      G2NEW=(G2M+G2N)/2. - SQRT(MINDIS/DIST2)*0.5*SQRT(3./DETG)*AAA
C
C
C     Controlling whether the new ray is proposed too near
C     to any other ray of the polygon.
C     Checking the ray I2:
      DIST2=RPDI2G(G1NEW,G2NEW,GPOLH(I2,1),GPOLH(I2,2),
     *             G11POM,G12POM,G22POM)
      IF (DIST2.LT.NEAR2) THEN
C       This would lead to creation of too narrow triangles:
        KPOLH(I2,1)=-IABS(KPOLH(I2,1))
        GOTO 10
      ENDIF
C     Checking the neighbouring rays:
      DIST2=RPDI2G(G1NEW,G2NEW,GPOLH(I1-1,1),GPOLH(I1-1,2),
     *             G11POM,G12POM,G22POM)
      IF (DIST2.LT.NEAR2) THEN
        IF (RPLTCR(I1-1,I1,GPOLH(I2,1),GPOLH(I2,2),
     *             NPOLH,GPOLH).OR.
     *      RPLTCR(I1-1,I2,GPOLH(I3,1),GPOLH(I3,2),
     *             NPOLH,GPOLH)) THEN
C         The triangles contain rays of polygon:
          KPOLH(I2,1)=-IABS(KPOLH(I2,1))
          GOTO 10
        ENDIF
C       This ray of polygon will be used as a new ray:
        KPOL(1)=IABS(KPOLH(I1-1,1))
        GPOL(1,1)=GPOLH(I1-1,1)
        GPOL(1,2)=GPOLH(I1-1,2)
        KPOL(2)=IABS(KPOLH(I1,1))
        GPOL(2,1)=GPOLH(I1,1)
        GPOL(2,2)=GPOLH(I1,2)
        KPOL(3)=IABS(KPOLH(I2,1))
        GPOL(3,1)=GPOLH(I2,1)
        GPOL(3,2)=GPOLH(I2,2)
        KPOL(4)=IABS(KPOLH(I3,1))
        GPOL(4,1)=GPOLH(I3,1)
        GPOL(4,2)=GPOLH(I3,2)
        NPOLH=NPOLH-2
        DO 16, I4=I1,NPOLH
          KPOLH(I4,1)=KPOLH(I4+2,1)
          KPOLH(I4,2)=KPOLH(I4+2,2)
          KPOLH(I4,3)=KPOLH(I4+2,3)
          KPOLH(I4,4)=KPOLH(I4+2,4)
          GPOLH(I4,1)=GPOLH(I4+2,1)
          GPOLH(I4,2)=GPOLH(I4+2,2)
  16    CONTINUE
        LNEWAR=.FALSE.
        GOTO 100
      ENDIF
C
      DIST2=RPDI2G(G1NEW,G2NEW,GPOLH(I3+1,1),GPOLH(I3+1,2),
     *             G11POM,G12POM,G22POM)
      IF (DIST2.LT.NEAR2) THEN
        IF (RPLTCR(I1,I2,GPOLH(I3+1,1),GPOLH(I3+1,2),
     *             NPOLH,GPOLH).OR.
     *      RPLTCR(I2,I3,GPOLH(I3+1,1),GPOLH(I3+1,2),
     *             NPOLH,GPOLH)) THEN
C         The triangles contain rays of polygon:
          KPOLH(I2,1)=-IABS(KPOLH(I2,1))
          GOTO 10
        ENDIF
C       This ray of polygon will be used as a new ray:
        KPOL(1)=IABS(KPOLH(I1,1))
        GPOL(1,1)=GPOLH(I1,1)
        GPOL(1,2)=GPOLH(I1,2)
        KPOL(2)=IABS(KPOLH(I2,1))
        GPOL(2,1)=GPOLH(I2,1)
        GPOL(2,2)=GPOLH(I2,2)
        KPOL(3)=IABS(KPOLH(I3,1))
        GPOL(3,1)=GPOLH(I3,1)
        GPOL(3,2)=GPOLH(I3,2)
        KPOL(4)=IABS(KPOLH(I3+1,1))
        GPOL(4,1)=GPOLH(I3+1,1)
        GPOL(4,2)=GPOLH(I3+1,2)
        NPOLH=NPOLH-2
        DO 17, I4=I2,NPOLH
          KPOLH(I4,1)=KPOLH(I4+2,1)
          KPOLH(I4,2)=KPOLH(I4+2,2)
          KPOLH(I4,3)=KPOLH(I4+2,3)
          KPOLH(I4,4)=KPOLH(I4+2,4)
          GPOLH(I4,1)=GPOLH(I4+2,1)
          GPOLH(I4,2)=GPOLH(I4+2,2)
  17    CONTINUE
        LNEWAR=.FALSE.
        GOTO 100
      ENDIF
C
C     Checking the other rays (except rays I1,I2 and I3):
      DO 20, I4=1,NPOLH
        IF (I4.EQ.I1) GOTO 20
        IF (I4.EQ.I3) GOTO 20
        IF (I4.EQ.I2) GOTO 20
        DIST2=RPDI2G(G1NEW,G2NEW,GPOLH(I4,1),GPOLH(I4,2),
     *               G11POM,G12POM,G22POM)
        IF (DIST2.LT.NEAR2) THEN
C         This would separate the polygon into two parts, or this
C         would lead to creation of too narrow triangles:
          KPOLH(I2,1)=-IABS(KPOLH(I2,1))
          GOTO 10
        ENDIF
  20  CONTINUE
C
C
C     Controlling whether the new ray is proposed too near the boundary
C     of the homogeneous polygon.
C     Checking the neighbouring sides:
      CALL RPDPA(G1NEW,G2NEW,GPOLH(I1-1,1),GPOLH(I1-1,2),GPOLH(I1,1),
     *           GPOLH(I1,2),G11POM,G12POM,G22POM,VERTEX,G1X,G2X)
      IF (VERTEX.EQ.'X') THEN
        DIST2=RPDI2G(G1NEW,G2NEW,G1X,G2X,G11POM,G12POM,G22POM)
        IF (DIST2.LT.NEAR2) THEN
          CALL RPLRTC(G1X,G2X,KTRID,KRAYI,KRAYJ,IGOTO)
          IF (IGOTO.EQ.1) THEN
            IF ((.NOT.RPLTCR(I1,I2,G1X,G2X,NPOLH,GPOLH)).AND.
     *          (.NOT.RPLTCR(I2,I3,G1X,G2X,NPOLH,GPOLH))) THEN
C             The ray X will be used as a new ray:
              IF (KRAYI.EQ.0) IGOTO=2
              KPOL(2)=IABS(KPOLH(I1,1))
              GPOL(2,1)=GPOLH(I1,1)
              GPOL(2,2)=GPOLH(I1,2)
              KPOL(3)=IABS(KPOLH(I2,1))
              GPOL(3,1)=GPOLH(I2,1)
              GPOL(3,2)=GPOLH(I2,2)
              KPOL(4)=IABS(KPOLH(I3,1))
              GPOL(4,1)=GPOLH(I3,1)
              GPOL(4,2)=GPOLH(I3,2)
              G1NEW=G1X
              G2NEW=G2X
              KPOL(1)=IRAY+1
              GPOL(1,1)=G1NEW
              GPOL(1,2)=G2NEW
              NPOLH=NPOLH-1
              KPOLH(I1,1)=IRAY+1
              GPOLH(I1,1)=G1NEW
              GPOLH(I1,2)=G2NEW
              DO 22, I4=I2,NPOLH
                KPOLH(I4,1)=KPOLH(I4+1,1)
                KPOLH(I4,2)=KPOLH(I4+1,2)
                KPOLH(I4,3)=KPOLH(I4+1,3)
                KPOLH(I4,4)=KPOLH(I4+1,4)
                GPOLH(I4,1)=GPOLH(I4+1,1)
                GPOLH(I4,2)=GPOLH(I4+1,2)
  22          CONTINUE
              LNEWAR=.TRUE.
              GOTO 100
            ENDIF
          ENDIF
C         This ray is not to be used:
          KPOLH(I2,1)=-IABS(KPOLH(I2,1))
          GOTO 10
        ENDIF
      ENDIF
      CALL RPDPA(G1NEW,G2NEW,GPOLH(I3,1),GPOLH(I3,2),GPOLH(I3+1,1),
     *           GPOLH(I3+1,2),G11POM,G12POM,G22POM,VERTEX,G1X,G2X)
      IF (VERTEX.EQ.'X') THEN
        DIST2=RPDI2G(G1NEW,G2NEW,G1X,G2X,G11POM,G12POM,G22POM)
        IF (DIST2.LT.NEAR2) THEN
          CALL RPLRTC(G1X,G2X,KTRID,KRAYI,KRAYJ,IGOTO)
          IF (IGOTO.EQ.1) THEN
            IF ((.NOT.RPLTCR(I1,I2,G1X,G2X,NPOLH,GPOLH)).AND.
     *          (.NOT.RPLTCR(I2,I3,G1X,G2X,NPOLH,GPOLH))) THEN
C             The ray X will be used as a new ray:
              IF (KRAYI.EQ.0) IGOTO=2
              KPOL(1)=IABS(KPOLH(I1,1))
              GPOL(1,1)=GPOLH(I1,1)
              GPOL(1,2)=GPOLH(I1,2)
              KPOL(2)=IABS(KPOLH(I2,1))
              GPOL(2,1)=GPOLH(I2,1)
              GPOL(2,2)=GPOLH(I2,2)
              KPOL(3)=IABS(KPOLH(I3,1))
              GPOL(3,1)=GPOLH(I3,1)
              GPOL(3,2)=GPOLH(I3,2)
              G1NEW=G1X
              G2NEW=G2X
              KPOL(4)=IRAY+1
              GPOL(4,1)=G1NEW
              GPOL(4,2)=G2NEW
              NPOLH=NPOLH-1
              DO 24, I4=I3,NPOLH
                KPOLH(I4,1)=KPOLH(I4+1,1)
                KPOLH(I4,2)=KPOLH(I4+1,2)
                KPOLH(I4,3)=KPOLH(I4+1,3)
                KPOLH(I4,4)=KPOLH(I4+1,4)
                GPOLH(I4,1)=GPOLH(I4+1,1)
                GPOLH(I4,2)=GPOLH(I4+1,2)
  24          CONTINUE
              KPOLH(I2,1)=IRAY+1
              GPOLH(I2,1)=G1NEW
              GPOLH(I2,2)=G2NEW
              LNEWAR=.TRUE.
              GOTO 100
            ENDIF
          ENDIF
C         This ray is not to be used:
          KPOLH(I2,1)=-IABS(KPOLH(I2,1))
          GOTO 10
        ENDIF
      ENDIF
C
C     Checking the other sides:
      I5=1
      I4=NPOLH
  30  CONTINUE
        CALL RPDPA(G1NEW,G2NEW,GPOLH(I4,1),GPOLH(I4,2),GPOLH(I5,1),
     *             GPOLH(I5,2),G11POM,G12POM,G22POM,VERTEX,G1X,G2X)
        IF (VERTEX.EQ.'X') THEN
          DIST2=RPDI2G(G1NEW,G2NEW,G1X,G2X,G11POM,G12POM,G22POM)
          IF (DIST2.LT.NEAR2) THEN
C           This would separate the polygon into two parts.
            KPOLH(I2,1)=-IABS(KPOLH(I2,1))
            GOTO 10
          ENDIF
        ENDIF
        I5=I4
        I4=I4-1
      IF (I4.GT.I3) GOTO 30
C
C
C     Controlling whether the  abscissa (ray I2 - new ray) intersects
C     the boundary of the homogeneous polygon.
C     Checking the neighbouring sides:
      CALL RPCROS(GPOLH(I2,1),GPOLH(I2,2),G1NEW,G2NEW,
     *            GPOLH(I1-1,1),GPOLH(I1-1,2),GPOLH(I1,1),
     *            GPOLH(I1,2),LINTS,G1X,G2X)
      IF (LINTS) THEN
        CALL RPLRTC(G1X,G2X,KTRID,KRAYI,KRAYJ,IGOTO)
        IF (IGOTO.EQ.1) THEN
          IF ((.NOT.RPLTCR(I1,I2,G1X,G2X,NPOLH,GPOLH)).AND.
     *        (.NOT.RPLTCR(I2,I3,G1X,G2X,NPOLH,GPOLH))) THEN
C           The ray X will be used as a new ray:
            IF (KRAYI.EQ.0) IGOTO=2
            KPOL(2)=IABS(KPOLH(I1,1))
            GPOL(2,1)=GPOLH(I1,1)
            GPOL(2,2)=GPOLH(I1,2)
            KPOL(3)=IABS(KPOLH(I2,1))
            GPOL(3,1)=GPOLH(I2,1)
            GPOL(3,2)=GPOLH(I2,2)
            KPOL(4)=IABS(KPOLH(I3,1))
            GPOL(4,1)=GPOLH(I3,1)
            GPOL(4,2)=GPOLH(I3,2)
            G1NEW=G1X
            G2NEW=G2X
            KPOL(1)=IRAY+1
            GPOL(1,1)=G1NEW
            GPOL(1,2)=G2NEW
            NPOLH=NPOLH-1
            KPOLH(I1,1)=IRAY+1
            GPOLH(I1,1)=G1NEW
            GPOLH(I1,2)=G2NEW
            DO 32, I4=I2,NPOLH
              KPOLH(I4,1)=KPOLH(I4+1,1)
              KPOLH(I4,2)=KPOLH(I4+1,2)
              KPOLH(I4,3)=KPOLH(I4+1,3)
              KPOLH(I4,4)=KPOLH(I4+1,4)
              GPOLH(I4,1)=GPOLH(I4+1,1)
              GPOLH(I4,2)=GPOLH(I4+1,2)
  32        CONTINUE
            LNEWAR=.TRUE.
            GOTO 100
          ENDIF
        ENDIF
C       This ray is not to be used:
        KPOLH(I2,1)=-IABS(KPOLH(I2,1))
        GOTO 10
      ENDIF
      CALL RPCROS(GPOLH(I2,1),GPOLH(I2,2),G1NEW,G2NEW,
     *            GPOLH(I3,1),GPOLH(I3,2),GPOLH(I3+1,1),
     *            GPOLH(I3+1,2),LINTS,G1X,G2X)
      IF (LINTS) THEN
        CALL RPLRTC(G1X,G2X,KTRID,KRAYI,KRAYJ,IGOTO)
        IF (IGOTO.EQ.1) THEN
          IF ((.NOT.RPLTCR(I1,I2,G1X,G2X,NPOLH,GPOLH)).AND.
     *        (.NOT.RPLTCR(I2,I3,G1X,G2X,NPOLH,GPOLH))) THEN
C           The ray X will be used as a new ray:
            IF (KRAYI.EQ.0) IGOTO=2
            KPOL(1)=IABS(KPOLH(I1,1))
            GPOL(1,1)=GPOLH(I1,1)
            GPOL(1,2)=GPOLH(I1,2)
            KPOL(2)=IABS(KPOLH(I2,1))
            GPOL(2,1)=GPOLH(I2,1)
            GPOL(2,2)=GPOLH(I2,2)
            KPOL(3)=IABS(KPOLH(I3,1))
            GPOL(3,1)=GPOLH(I3,1)
            GPOL(3,2)=GPOLH(I3,2)
            G1NEW=G1X
            G2NEW=G2X
            KPOL(4)=IRAY+1
            GPOL(4,1)=G1NEW
            GPOL(4,2)=G2NEW
            NPOLH=NPOLH-1
            DO 34, I4=I3,NPOLH
              KPOLH(I4,1)=KPOLH(I4+1,1)
              KPOLH(I4,2)=KPOLH(I4+1,2)
              KPOLH(I4,3)=KPOLH(I4+1,3)
              KPOLH(I4,4)=KPOLH(I4+1,4)
              GPOLH(I4,1)=GPOLH(I4+1,1)
              GPOLH(I4,2)=GPOLH(I4+1,2)
  34        CONTINUE
            KPOLH(I2,1)=IRAY+1
            GPOLH(I2,1)=G1NEW
            GPOLH(I2,2)=G2NEW
            LNEWAR=.TRUE.
            GOTO 100
          ENDIF
        ENDIF
C       This ray is not to be used:
        KPOLH(I2,1)=-IABS(KPOLH(I2,1))
        GOTO 10
      ENDIF
C
C     Checking the other sides:
      I5=1
      I4=NPOLH
  40  CONTINUE
        CALL RPCROS(GPOLH(I2,1),GPOLH(I2,2),G1NEW,G2NEW,
     *              GPOLH(I4,1),GPOLH(I4,2),GPOLH(I5,1),
     *              GPOLH(I5,2),LINTS,G1X,G2X)
        IF (LINTS) THEN
C         This would separate the polygon into two parts.
          KPOLH(I2,1)=-IABS(KPOLH(I2,1))
          GOTO 10
        ENDIF
        I5=I4
        I4=I4-1
      IF (I4.GT.I3) GOTO 40
C
C
C     Controlling whether the ray is in the polygon:
      IF (RPLRIP(NPOLH,GPOLH,G1NEW,G2NEW)) THEN
        IF ((.NOT.RPLTCR(I1,I2,G1NEW,G2NEW,NPOLH,GPOLH)).AND.
     *      (.NOT.RPLTCR(I2,I3,G1NEW,G2NEW,NPOLH,GPOLH))) THEN
C         This ray will be used:
          KPOL(1)=IRAY+1
          GPOL(1,1)=G1NEW
          GPOL(1,2)=G2NEW
          KPOL(2)  =IABS(KPOLH(I1,1))
          GPOL(2,1)=GPOLH(I1,1)
          GPOL(2,2)=GPOLH(I1,2)
          KPOL(3)  =IABS(KPOLH(I2,1))
          GPOL(3,1)=GPOLH(I2,1)
          GPOL(3,2)=GPOLH(I2,2)
          KPOL(4)  =IABS(KPOLH(I3,1))
          GPOL(4,1)=GPOLH(I3,1)
          GPOL(4,2)=GPOLH(I3,2)
          KPOLH(I2,1)=IRAY+1
          GPOLH(I2,1)=G1NEW
          GPOLH(I2,2)=G2NEW
          LNEWAR=.TRUE.
          IGOTO=2
          GOTO 100
        ENDIF
      ENDIF
C     A very strange situation,
C     no intersection, but ray is not in polygon or contains other rays:
      KPOLH(I2,1)=-IABS(KPOLH(I2,1))
      GOTO 10
C
  100 CONTINUE
      IF (LNEWAR) THEN
C       Trace the ray and go to 120 or to 150:
        RETURN
      ELSE
        GOTO 150
      ENDIF
C
C
  120 CONTINUE
C     New ray was actually computed, storing it to the array KBR:
      CALL RPKBR(KRAYI,KRAYJ,IRAY)
C
C
C     Converting divided part of the polygon into two triangles:
  150 CONTINUE
      G11POM=-999.
      CALL RPRAY(KPOL(1),LRAY,ITYPE,ISHEET,G1,G2,G11,G12,G22,X1,X2,
     *             G1X1,G2X1,G1X2,G2X2)
      IF (LRAY) THEN
        G11POM=G11
        G12POM=G12
        G22POM=G22
      ENDIF
      CALL RPRAY(KPOL(2),LRAY,ITYPE,ISHEET,G1,G2,G11,G12,G22,X1,X2,
     *             G1X1,G2X1,G1X2,G2X2)
      IF (LRAY) THEN
        IF (G11POM.EQ.-999.) THEN
          G11POM=G11
          G12POM=G12
          G22POM=G22
        ELSE
          G11POM=(G11POM+G11)*.5
          G12POM=(G12POM+G12)*.5
          G22POM=(G22POM+G22)*.5
        ENDIF
      ENDIF
      CALL RPRAY(KPOL(3),LRAY,ITYPE,ISHEET,G1,G2,G11,G12,G22,X1,X2,
     *             G1X1,G2X1,G1X2,G2X2)
      IF (LRAY) THEN
        G11POM=(G11POM+G11)*.5
        G12POM=(G12POM+G12)*.5
        G22POM=(G22POM+G22)*.5
      ENDIF
      CALL RPRAY(KPOL(4),LRAY,ITYPE,ISHEET,G1,G2,G11,G12,G22,X1,X2,
     *             G1X1,G2X1,G1X2,G2X2)
      IF (LRAY) THEN
        G11POM=(G11POM+G11)*.5
        G12POM=(G12POM+G12)*.5
        G22POM=(G22POM+G22)*.5
      ENDIF
      IF (RPDI2G(GPOL(1,1),GPOL(1,2),GPOL(3,1),GPOL(3,2),
     *    G11POM,G12POM,G22POM).GT.
     *    RPDI2G(GPOL(2,1),GPOL(2,2),GPOL(4,1),GPOL(4,2),
     *    G11POM,G12POM,G22POM)) THEN
C       The diagonal 2-4 is shorter, turning polygon:
        I1=KPOL(1)
        G1=GPOL(1,1)
        G2=GPOL(1,2)
        DO 160, I2=1,3
          I3=I2+1
          KPOL(I2)=KPOL(I3)
          GPOL(I2,1)=GPOL(I3,1)
          GPOL(I2,2)=GPOL(I3,2)
  160   CONTINUE
        KPOL(4)=I1
        GPOL(4,1)=G1
        GPOL(4,2)=G2
      ENDIF
      IF (RPLRIT(.FALSE.,GPOL(1,1),GPOL(1,2),GPOL(2,1),
     *    GPOL(2,2),GPOL(3,1),GPOL(3,2),G1A,G2A,AREA1).AND.
     *    RPLRIT(.FALSE.,GPOL(3,1),GPOL(3,2),GPOL(4,1),
     *    GPOL(4,2),GPOL(1,1),GPOL(1,2),G1A,G2A,AREA2)) THEN
        ITRI=ITRI+1
        KTRIN(1)=KPOL(1)
        KTRIN(2)=KPOL(2)
        KTRIN(3)=KPOL(3)
        KTRIN(4)=ITRI
        IF (KTRID(5).EQ.0) THEN
          KTRIN(5)=KTRID(4)
        ELSE
          KTRIN(5)=KTRID(5)
        ENDIF
        KTRIN(6)=3
        CALL RPTRI1(ITRI,KTRIN)
        CALL RPSTOR('T',IRAY,KTRIN)
        ITRI=ITRI+1
        KTRIN(1)=KPOL(3)
        KTRIN(2)=KPOL(4)
        KTRIN(3)=KPOL(1)
        KTRIN(4)=ITRI
        IF (KTRID(5).EQ.0) THEN
          KTRIN(5)=KTRID(4)
        ELSE
          KTRIN(5)=KTRID(5)
        ENDIF
        KTRIN(6)=3
        CALL RPTRI1(ITRI,KTRIN)
        CALL RPSTOR('T',IRAY,KTRIN)
        GOTO 200
      ENDIF
C     The triangles 123 and 341
C     are not both right-handed. Trying the diagonal 2-4:
      IF (RPLRIT(.FALSE.,GPOL(1,1),GPOL(1,2),GPOL(2,1),
     *    GPOL(2,2),GPOL(4,1),GPOL(4,2),G1A,G2A,AREA)) THEN
        ITRI=ITRI+1
        KTRIN(1)=KPOL(1)
        KTRIN(2)=KPOL(2)
        KTRIN(3)=KPOL(4)
        KTRIN(4)=ITRI
        IF (KTRID(5).EQ.0) THEN
          KTRIN(5)=KTRID(4)
        ELSE
          KTRIN(5)=KTRID(5)
        ENDIF
        KTRIN(6)=3
        CALL RPTRI1(ITRI,KTRIN)
        CALL RPSTOR('T',IRAY,KTRIN)
      ENDIF
      IF (RPLRIT(.FALSE.,GPOL(2,1),GPOL(2,2),GPOL(3,1),
     *    GPOL(3,2),GPOL(4,1),GPOL(4,2),G1A,G2A,AREA)) THEN
        ITRI=ITRI+1
        KTRIN(1)=KPOL(2)
        KTRIN(2)=KPOL(3)
        KTRIN(3)=KPOL(4)
        KTRIN(4)=ITRI
        IF (KTRID(5).EQ.0) THEN
          KTRIN(5)=KTRID(4)
        ELSE
          KTRIN(5)=KTRID(5)
        ENDIF
        KTRIN(6)=3
        CALL RPTRI1(ITRI,KTRIN)
        CALL RPSTOR('T',IRAY,KTRIN)
      ENDIF
C     Goto 200
C
C
C     Making homogeneous polygon positive:
  200 CONTINUE
      DO 201, I1=1,NPOLH
        KPOLH(I1,1)=IABS(KPOLH(I1,1))
  201 CONTINUE
      END
C
C=======================================================================
C
      LOGICAL FUNCTION RPLTCR(I1,I2,G1,G2,NPOLH,GPOLH)
C
C----------------------------------------------------------------------
      INTEGER I1,I2
      REAL G1,G2
      INTEGER MPOLH
      PARAMETER (MPOLH=500)
      INTEGER NPOLH
      REAL GPOLH(MPOLH,2)
C
C Subroutine designed to decide whether the triangle formed by rays
C I1, I2, of KPOLH and ray G1,G2 contains any ray of the homogeneous
C polygon KPOLH.
C
C Cartesian metric is used.
C
C Input:  NPOLH,GPOLH ... polygon.
C         I1,I2,G1,G2 ... sequence of first two rays and ray para-
C                         meters of third ray of examined triangle.
C
C Output: RPLTCR ... Indicates whether the triangle contains any ray.
C
C Coded by Petr Bulant
C
C.......................................................................
      INTEGER I4
      REAL AAA
      EXTERNAL RPLRIT
      LOGICAL RPLRIT
C-----------------------------------------------------------------------
C
      RPLTCR=.FALSE.
      DO 10, I4=1,NPOLH
        IF (I4.EQ.I1) GOTO 9
        IF (I4.EQ.I2) GOTO 9
        IF ((GPOLH(I4,1).EQ.G1).AND.(GPOLH(I4,2).EQ.G2)) GOTO 9
        IF (RPLRIT(.TRUE.,GPOLH(I1,1),GPOLH(I1,2),GPOLH(I2,1),
     *                    GPOLH(I2,2),G1         ,G2         ,
     *                    GPOLH(I4,1),GPOLH(I4,2),AAA)) THEN
C         The triangle contains ray I4 of homogeneous polygon:
          RPLTCR=.TRUE.
          RETURN
        ENDIF
   9    CONTINUE
  10  CONTINUE
      END
C
C=======================================================================
C
      SUBROUTINE RPMEGS(ISHA,ISHB,G1X1A,G2X1A,G1X2A,G2X2A,
     *                            G1X1B,G2X1B,G1X2B,G2X2B,B11,B12,B22)
C
C-----------------------------------------------------------------------
      INTEGER ISHA,ISHB
      REAL G1X1A,G2X1A,G1X2A,G2X2A,G1X1B,G2X1B,G1X2B,G2X2B
      REAL B11,B12,B22
C
C Subroutine designed to evaluate the metric tensor B, based on
C the geometrical spreading (i.e. On the derivatives dg/dx).
C           -1                 dg    dg
C    B   = A      where  A  = -- i  -- j  PRM0(1)**2.
C     ij    ij            ij   dx    dx
C                                k     k
C If ISHA.GT.0  and ISHB.GT.0, B is evaluated from both sets of
C    derivatives and the greater B is taken.
C
C Input:
C     ISHA,ISHB ... Values of the ray history for rays A and B.
C     GIXIA,B   ... Derivatives.
C Output:
C     B11,B12,B22 . Computed metric tensor.
C
C Subroutines and external functions required:
C
C Coded by Petr Bulant
C
C.......................................................................
C
C Common block /RPARD/:
      INCLUDE 'rpard.inc'
C     rpard.inc
C     PRM0(1) ... Maximum allowed distance of the boundary ray from the
C                 shadow zone (measured on the reference surface).
C.......................................................................
      REAL A11(3),A12(3),A22(3)
      REAL DETA
C     AII(1) ... Matrix based on point A. See the formula above.
C     AII(2) ... Matrix based on point B. See the formula above.
C     AII(3) ... Auxiliary matrix.
C     DETA   ... Determinant or other auxiliary variable.
C-----------------------------------------------------------------------
      IF (ISHA.GT.0) THEN
        A11(3)=G1X1A*G1X1A+G1X2A*G1X2A
        A12(3)=G1X1A*G2X1A+G1X2A*G2X2A
        A22(3)=G2X1A*G2X1A+G2X2A*G2X2A
        DETA=A11(3)*A22(3)-A12(3)*A12(3)
        IF (DETA.EQ.0.) THEN
          A11(1)=999999.
          A12(1)=0.
          A22(1)=999999.
        ELSE
          A11(1)= A22(3)/DETA
          A12(1)=-A12(3)/DETA
          A22(1)= A11(3)/DETA
        ENDIF
      ENDIF
      IF (ISHB.GT.0) THEN
        A11(3)=G1X1B*G1X1B+G1X2B*G1X2B
        A12(3)=G1X1B*G2X1B+G1X2B*G2X2B
        A22(3)=G2X1B*G2X1B+G2X2B*G2X2B
        DETA=A11(3)*A22(3)-A12(3)*A12(3)
        IF (DETA.EQ.0.) THEN
          A11(2)=999999.
          A12(2)=0.
          A22(2)=999999.
        ELSE
          A11(2)= A22(3)/DETA
          A12(2)=-A12(3)/DETA
          A22(2)= A11(3)/DETA
        ENDIF
      ENDIF
      IF ((ISHA.GT.0).AND.(ISHB.GT.0)) THEN
C       B=(A(1) + A(2) + ABS(A(1) - A(2))) / 2
        A11(3)=A11(1)-A11(2)
        A12(3)=A12(1)-A12(2)
        A22(3)=A22(1)-A22(2)
C
        DETA=ABS(A11(3)*A22(3)-A12(3)*A12(3))
        B11=A11(3)*A11(3)+A12(3)*A12(3)+DETA
        B22=A22(3)*A22(3)+A12(3)*A12(3)+DETA
        DETA=SQRT(B11+B22+0.000001*(A11(1)+A11(2))**2
     *                   +0.000001*(A22(1)+A22(2))**2)
        IF (DETA.EQ.0.) THEN
          B11=999999.
          B12=0.
          B22=999999.
        ELSE
          B11=B11/DETA
          B22=B22/DETA
          B12=A12(3)*(A11(3)+A22(3))/DETA
C
          DETA=PRM0(1)**2
          DETA=1./DETA
          B11=(B11+A11(1)+A11(2)) / 2.*DETA
          B12=(B12+A12(1)+A12(2)) / 2.*DETA
          B22=(B22+A22(1)+A22(2)) / 2.*DETA
        ENDIF
      ELSEIF (ISHA.GT.0) THEN
        DETA=PRM0(1)**2
        DETA=1./DETA
        B11=A11(1)*DETA
        B12=A12(1)*DETA
        B22=A22(1)*DETA
      ELSEIF (ISHB.GT.0) THEN
        DETA=PRM0(1)**2
        DETA=1./DETA
        B11=A11(2)*DETA
        B12=A12(2)*DETA
        B22=A22(2)*DETA
      ELSE
C       RP3D-028
        CALL ERROR('RP3D-028: Wrongly invoked RPMEGS.')
C       This error should not appear.
C       Please contact the author or try to
C       change the input data.
      ENDIF
      END
C
C=======================================================================
C
      SUBROUTINE RPERR(IERR)
C
C-----------------------------------------------------------------------
      INTEGER IERR
C
C Subroutine designed to print error messages of different
C RP* subroutines using command 'PAUSE'.
C
C Input:
C     IERR ... Index of the error.
C No output.
C Coded by Petr Bulant
C-----------------------------------------------------------------------
C
      IF         (IERR.EQ.001) THEN
C           RP3D-001
        CALL ERROR('RP3D-001: A ray was not found in the memory.')
C       A ray which should have been in the computer memory was not
C       found there. This error should not appear.
C       Please contact the author or try to
C       change the input data.
C
      ELSEIF     (IERR.EQ.002) THEN
C           RP3D-002
        CALL ERROR('RP3D-002: A triangle was not found in the memory.')
C       A triangle which should have been in the computer memory was not
C       found there. This error should not appear.
C       Please contact the author or try to
C       change the input data.
C
      ELSEIF     (IERR.EQ.003) THEN
C           RP3D-003
        CALL ERROR('RP3D-003: Impossible to find boundary rays.')
C       Rounding error does not allow for sufficiently fine division of
C       the basic step in the ray parameters.  Numerically, there is no
C       ray between the two rays, and it is thus impossible to find the
C       boundary rays.  It is recommended to decrease the allowed error
C       UEB of the
C       computation of the ray, or to increase the maximum distance
C       AERR between
C       the boundary rays.
C
      ELSEIF     (IERR.EQ.004) THEN
C           RP3D-004
        CALL ERROR('RP3D-004: Determinant is not positive.')
C       This error should not appear.
C       Please contact the author or try to
C       change the input data.
C
      ELSEIF     (IERR.EQ.005) THEN
C           RP3D-005
        CALL ERROR('RP3D-005: Insufficient memory for KPOL.')
C       This error may be caused by too small dimension of array
C       KPOL. Try to enlarge the parameter MPOL in subroutines
C       RPDIV and RPLRIP.
C
      ELSEIF     (IERR.EQ.006) THEN
C           RP3D-006
        CALL ERROR('RP3D-006: Insufficient memory for KPOLH.')
C       This error may be caused by too small dimension of array
C       KPOLH. Try to enlarge the parameter MPOLH in subroutines
C       RPDIV and RPLRIP.
C
      ELSEIF     (IERR.EQ.007) THEN
C           RP3D-007
        CALL ERROR('RP3D-007: Insufficient memory for KLINE.')
C       This error may be caused by too small dimension of array
C       KLINE. Try to enlarge the parameter MLINE in subroutine
C       RPDIV.
C
      ELSEIF     (IERR.EQ.008) THEN
C           RP3D-008
        CALL ERROR('RP3D-008: Insufficient memory for KBR.')
C       This error may be caused by too small dimension of array
C       KBR. Try to enlarge the parameter MBR in common block BOURA
C       in file rp3d.inc.
C
      ELSEIF     (IERR.EQ.010) THEN
C           RP3D-010
        CALL ERROR('RP3D-010: Insufficient memory for KPL.')
C       This error may be caused by too small dimension of array
C       KPL. Try to enlarge the parameter MPL in common block POLY
C       in file rp3d.inc.
C
      ELSE
C           RP3D-999
        CALL ERROR('RP3D-999: Wrong index of an error.')
C       The subroutine was invocated with wrong error index.
C       This error should not appear.
C       Please contact the author.
      ENDIF
      END
C
C=======================================================================
C
      SUBROUTINE RPKBR(KRAYA,KRAYB,KRAYN)
C
C-----------------------------------------------------------------------
      INTEGER KRAYA,KRAYB,KRAYN
C
C Subroutine designed to store the ray with index KRAYN to the array
C KBR, assuming that KRAYA and KRAYB are indices of the basic rays,
C forming the side on which the ray KRAYN lies, in the same consequence
C in which they are stored in KBR.
C
C Input:
C     KRAYA,KRAYB ... Indices of two basic rays. The rays are assumed
C           to form the side of a basic triangle on which the ray KRAYN
C           lies. The consequence of the rays KRAYA and KRAYB is assumed
C           to be the same as the consequence in which they are stored
C           in KBR.
C     KRAYN ... Index of a ray to be stored to array KBR.
C No output.
C
C Coded by Petr Bulant
C
C.......................................................................
C
C Common block /BOURA/:
      INCLUDE 'rp3d.inc'
C     rp3d.inc
C
C.......................................................................
C Auxiliary storage locations:
      INTEGER J1,J2,I1
      INTEGER ITYPEN,ISHN,ITYPE,ISH
      REAL G1N,G2N,G1,G2,G11,G12,G22,X1,X2,G1X1,G2X1,G1X2,G2X2
      LOGICAL LRAY
C-----------------------------------------------------------------------
      CALL RPRAY(KRAYN,LRAY,ITYPEN,ISHN,G1N,G2N,G11,G12,G22,
     *             X1,X2,G1X1,G2X1,G1X2,G2X2)
      IF (.NOT.LRAY) CALL RPERR(1)
      IF (NBR.GT.2) THEN
C       The side KRAYA,KRAYB may already be in KBR, rays might be
C       just added to it in KBR:
        J1=1
  11    CONTINUE
C       Loop for the rays in KBR:
          IF ((KBR(J1,1).EQ.KRAYA).AND.(KBR(J1+1,1).EQ.KRAYB)) THEN
            IF (KBR(J1+2,1).LE.0) THEN
              J2=J1+3
              GOTO 13
            ENDIF
            J2=0
            IF ((G1N.LE.GBR(J1,1).AND.G1N.GE.GBR(J1+3,1)).OR.
     *          (G1N.GE.GBR(J1,1).AND.G1N.LE.GBR(J1+3,1))) J2=J1+3
            DO 12, I1=J1+3,J1+1+KBR(J1+2,1)
              IF ((G1N.GE.GBR(I1,1).AND.G1N.LE.GBR(I1+1,1)).OR.
     *            (G1N.LE.GBR(I1,1).AND.G1N.GE.GBR(I1+1,1))) J2=I1+1
  12        CONTINUE
            I1=J1+2+KBR(J1+2,1)
            IF ((G1N.LE.GBR(I1,1).AND.G1N.GE.GBR(J1+1,1)).OR.
     *          (G1N.GE.GBR(I1,1).AND.G1N.LE.GBR(J1+1,1))) J2=I1+1
  13        CONTINUE
            IF (J2.NE.0) THEN
C             Now J2 points to the position in KBR,
C             where ray KRAYN is to be added:
              IF (NBR+1.GT.MBR) CALL RPERR(8)
              IF (NBR.GE.J2) NBR=NBR+1
              DO 15, I1=NBR,J2+1,-1
                KBR(I1,1)=KBR(I1-1,1)
                KBR(I1,2)=KBR(I1-1,2)
                KBR(I1,3)=KBR(I1-1,3)
                GBR(I1,1)=GBR(I1-1,1)
                GBR(I1,2)=GBR(I1-1,2)
   15         CONTINUE
              NBR=MAX0(NBR,J2)
              KBR(J2,1)=KRAYN
              KBR(J2,2)=ISHN
              KBR(J2,3)=ITYPEN
              GBR(J2,1)=G1N
              GBR(J2,2)=G2N
              KBR(J1+2,1)=KBR(J1+2,1)+1
            ENDIF
            RETURN
          ENDIF
          J1=J1+3+KBR(J1+2,1)
        IF (J1.LT.NBR) GOTO 11
C       End of the loop for the rays in KBR.
      ENDIF
C
C     The side KRAYA,KRAYB is not in KBR, rays will be stored to KBR:
      IF (NBR.GE.MBR) CALL RPERR(8)
      CALL RPRAY(KRAYA,LRAY,ITYPE,ISH,G1,G2,G11,G12,G22,
     *           X1,X2,G1X1,G2X1,G1X2,G2X2)
      IF (.NOT.LRAY) CALL RPERR(1)
      NBR=NBR+1
      KBR(NBR,1)=KRAYA
      KBR(NBR,2)=0
      KBR(NBR,3)=0
      GBR(NBR,1)=G1
      GBR(NBR,2)=G2
      IF (NBR.GE.MBR) CALL RPERR(8)
      CALL RPRAY(KRAYB,LRAY,ITYPE,ISH,G1,G2,G11,G12,G22,
     *           X1,X2,G1X1,G2X1,G1X2,G2X2)
      IF (.NOT.LRAY) CALL RPERR(1)
      NBR=NBR+1
      KBR(NBR,1)=KRAYB
      KBR(NBR,2)=0
      KBR(NBR,3)=0
      GBR(NBR,1)=G1
      GBR(NBR,2)=G2
      IF (NBR.GE.MBR) CALL RPERR(8)
      NBR=NBR+1
      KBR(NBR,1)=1
      KBR(NBR,2)=0
      KBR(NBR,3)=0
      GBR(NBR,1)=0
      GBR(NBR,2)=0
      IF (NBR.GE.MBR) CALL RPERR(8)
      NBR=NBR+1
      KBR(NBR,1)=KRAYN
      KBR(NBR,2)=ISHN
      KBR(NBR,3)=ITYPEN
      GBR(NBR,1)=G1N
      GBR(NBR,2)=G2N
      RETURN
      END
C
C=======================================================================
C
      REAL FUNCTION RPDI2L(IRAYB,IRAYA,IRAYC)
C
C----------------------------------------------------------------------
      INTEGER IRAYB,IRAYA,IRAYC
C Subroutine designed to compute the second power of the distance
C of the ray A from the line connecting rays B and C on the normalized
C ray domain.
C
C Input:
C     IRAYB,IRAYA,IRAYC ... Indices of the rays.
C
C Output:
C     RPDI2L            ... Second power of the distance.
C
C Coded by Petr Bulant
C
C......................................................................
      EXTERNAL RPDI2G
      REAL     RPDI2G
      INTEGER ITYPE,ISH
      REAL ZERO,AREA2,DIST2,DETG
      PARAMETER (ZERO=.0000001)
      REAL G11POM,G12POM,G22POM,X1,X2,G1X1,G2X1,G1X2,G2X2
      REAL G1A,G2A,G11A,G12A,G22A
      REAL G1B,G2B,G11B,G12B,G22B
      REAL G1C,G2C,G11C,G12C,G22C
      LOGICAL LRAY
C-----------------------------------------------------------------------
      CALL RPRAY(IRAYB,LRAY,ITYPE,ISH,G1B,G2B,G11B,G12B,G22B,
     *                   X1,X2,G1X1,G2X1,G1X2,G2X2)
      IF (.NOT.LRAY) CALL RPERR(1)
      CALL RPRAY(IRAYA,LRAY,ITYPE,ISH,G1A,G2A,G11A,G12A,G22A,
     *                   X1,X2,G1X1,G2X1,G1X2,G2X2)
      IF (.NOT.LRAY) CALL RPERR(1)
      CALL RPRAY(IRAYC,LRAY,ITYPE,ISH,G1C,G2C,G11C,G12C,G22C,
     *                   X1,X2,G1X1,G2X1,G1X2,G2X2)
      IF (.NOT.LRAY) CALL RPERR(1)
      G11POM=(G11A+G11C+G11B)/3.
      G12POM=(G12A+G12C+G12B)/3.
      G22POM=(G22A+G22C+G22B)/3.
      DIST2=RPDI2G(G1C,G2C,G1B,G2B,G11POM,G12POM,G22POM)
      IF (DIST2.GE.ZERO) THEN
        DETG=G11POM*G22POM - G12POM*G12POM
        IF (DETG.LT.ZERO) CALL RPERR(4)
        AREA2=DETG*(((G1C-G1B)*(G2A-G2B)-(G2C-G2B)*(G1A-G1B))**2)
C       Distance: (AREA2 is the area**2)
        RPDI2L=AREA2/DIST2
      ELSE
        RPDI2L=RPDI2G(G1A,G2A,G1B,G2B,G11POM,G12POM,G22POM)
      ENDIF
      RETURN
      END
C
C=======================================================================
C
C                                                  
      SUBROUTINE RPSTOR(CHAR,IRAY,KTRIS)
C
C-----------------------------------------------------------------------
      CHARACTER CHAR
      INTEGER IRAY,KTRIS(6)
C
C Subroutine designed to store the parameters of the ray IRAY or of the
C triangle KTRIS to the output files for plotting.
C
C Attention:  To enable this subroutine, turn the first RETURN statement
C     (i.e., first executable statement) of this subroutine into a
C     comment line.
C
C Input:
C     CHAR ...Indicates what is to be stored:
C       CHAR='R' ... The ray with sign IRAY.
C       CHAR='T' ... The triangle KTRIS.
C     IRAY ...Index of the ray to be stored.
C       IRAY= 0 when opening the output files,
C       IRAY=-1 when closing the output files.
C     KTRIS...Parameters of the triangle to be stored (one column of
C             array KTRI).
C No output
C
C Structure of the formatted output files:
C     Note that only the rays and triangles of the last computed
C     elementary wave are stored in the output files.
C     The file 'rp.out' with the parameters of the rays of the last
C     computed elementary wave:
C       The file is formed of same lines, each line containing the
C       information about one ray in the following form:
C       IRAY,ITYPE,ISH,G1R,G2R,G11,G12,G22,X1R,X2R;
C       see the description of these variables below.
C     The file 'rprt.out' with the parameters of the rays and triangles
C     of the last computed elementary wave:
C       The file is formed of odd lines containing a single character,
C       indicating the type of the information on the following (even)
C       line.
C       Odd line:
C         'R' indicates the ray on the following line.
C         'T' indicates the triangle on the following line.
C       Even line:
C         IRAY,ITYPE,ISH,G1R,G2R,X1R,X2R      for 'R' on previous line.
C         ISH,KTRIS,G1R,G2R,G1S,G2S,G1T,G2T,X1R,X2R,X1S,X2S,X1T,X2T
C                                             for 'T' on previous line.
C       See the description of these variables below.
C
C.......................................................................
      INTEGER ITYPE,ISH
      REAL G1R,G2R,G1S,G2S,G1T,G2T,G11,G12,G22,X1R,X2R,X1S,X2S,X1T,X2T
      REAL G1X1,G2X1,G1X2,G2X2
      LOGICAL LRAY
C     ITYPE    ...    Type of ray.
C     ISH      ...    Value of history function.
C     G1_,G2_  ...    Normalized parameters of rays.
C     G11,G12,G22 ... Ray-parameter metric tensor.
C     X1_,X2_  ...    Coordinates of the ray on the reference surface.
C     G1X1,G2X1,G1X2,G2X2 ... Derivations of ray parameters according to
C                             the surface coordinates.
C     LRAY ...Indicates whether the ray IRAY is in memory.
C-----------------------------------------------------------------------
C
      RETURN
C
      IF (CHAR.EQ.'R') THEN
        IF (IRAY.EQ.0) THEN
          OPEN (40,FILE='rp.out')
          OPEN (50,FILE='rprt.out')
        ELSEIF (IRAY.EQ.-1) THEN
          CLOSE (40)
          CLOSE (50)
        ELSE
          CALL RPRAY(IRAY,LRAY,ITYPE,ISH,G1R,G2R,G11,G12,G22,X1R,X2R,
     *             G1X1,G2X1,G1X2,G2X2)
          IF (.NOT.LRAY) CALL RPERR(1)
          WRITE(40,'(3I6,2F15.6,3F15.3,2F15.5)')
     *         IRAY,ITYPE,ISH,G1R,G2R,G11,G12,G22,X1R,X2R
          WRITE(50,*) 'R'
          WRITE(50,'(3I6,4F12.6)')
     *    IRAY,ITYPE,ISH,G1R,G2R,X1R,X2R
        ENDIF
      ELSEIF (CHAR.EQ.'T') THEN
        CALL RPRAY(KTRIS(1),LRAY,ITYPE,ISH,G1R,G2R,G11,G12,G22,X1R,X2R
     *            ,G1X1,G2X1,G1X2,G2X2)
        IF (.NOT.LRAY) CALL RPERR(1)
        CALL RPRAY(KTRIS(2),LRAY,ITYPE,ISH,G1S,G2S,G11,G12,G22,X1S,X2S,
     *             G1X1,G2X1,G1X2,G2X2)
        IF (.NOT.LRAY) CALL RPERR(1)
        CALL RPRAY(KTRIS(3),LRAY,ITYPE,ISH,G1T,G2T,G11,G12,G22,X1T,X2T,
     *             G1X1,G2X1,G1X2,G2X2)
        IF (.NOT.LRAY) CALL RPERR(1)
        IF ((KTRIS(6).NE.3).AND.(KTRIS(6).NE.4)) ISH=0
        WRITE(50,*) 'T'
        WRITE(50,'(7I6,12F12.6)') ISH,KTRIS,G1R,G2R,G1S,G2S,G1T,G2T
     *                            ,X1R,X2R,X1S,X2S,X1T,X2T
      ELSE
C       RP3D-029
        CALL ERROR('RP3D-029: Wrongly invoked storing.')
C       This error should not appear.
C       Please contact the author.
      ENDIF
      RETURN
      END
C
C=======================================================================
C