!=====================================================================
! NGPP: Polypack, A Package of Routines to Manipulate Polygons
!=====================================================================
!
! Polypack is a small package of NCAR Graphics routines that allow a
! user to manipulate polygons in various ways.
!
! Each of the six principal routines is given a "clip" polygon, a
! "subject" polygon, and a workspace; it operates on the two polygons
! in some way to create either a derivative polygon or a set of
! trapezoids representing the interior of that derivative polygon and
! then passes these on to a user-specified processing routine.
!
! The six basic routines provided by POLYPACK are as follows:
!
!   NG_PPDIPO generates and returns the boundary of the "difference"
!             polygon, which consists of all points that are inside
!             the subject polygon but not inside the clip polygon.
!
!   NG_PPINPO generates and returns the boundary of the "intersection"
!             polygon, which consists of all points that are inside
!             both the clip polygon and the subject polygon.
!
!   NG_PPUNPO generates and returns the boundary of the "union" polygon,
!             which consists of all points that are inside either or
!             both of the clip polygon and the subject polygon.
!
!   NG_PPDITR generates the difference polygon but returns a set of
!             trapezoids representing its interior.
!
!   NG_PPINTR generates the intersection polygon but returns a set of
!             trapezoids representing its interior.
!
!   NG_PPUNTR generates the union polygon but returns a set of
!             trapezoids representing its interior.
!
! Other POLYPACK routines are as follows:
!
!   NG_PPPPAP can be called to preprocess a polygon in such a way as to
!             remove certain peculiarities that can cause minor cosmetic
!             errors in the output from the routines that return
!             trapezoids.
!
!   NG_PPPLCL will clip a polyline against a clipping rectangle. It is
!             intended that, eventuallly, there should be a better routine
!             that will clip a polyline against an arbitrary polygon, but
!             that routine has not yet been written.
!
!---------------------------------------------------------------------
!
! SUBROUTINE NG_PPDIPO( XCCP, YCCP, NCCP, XCSP, YCSP, NCSP, RWRK, IWRK, &
!                       NWRK, URPP, IERR )
!
!   INTEGER, INTENT(IN   ) :: NCCP
!   REAL,    INTENT(IN   ) :: XCCP(NCCP), YCCP(NCCP)
!   INTEGER, INTENT(IN   ) :: NCSP
!   REAL,    INTENT(IN   ) :: XCSP(NCSP), YCSP(NCSP)
!   INTEGER, INTENT(IN   ) :: NWRK
!   REAL                   :: RWRK(NWRK)
!   INTEGER                :: IWRK(NWRK)
!   INTEGER, INTENT(  OUT) :: IERR
!
!   INTERFACE
!     SUBROUTINE URPP (XCRA,YCRA,NCRA)
!       IMPLICIT NONE
!       INTEGER :: NCRA
!       REAL    :: XCRA(NCRA), YCRA(NCRA)
!       ! ...(code to process polygon boundary piece defined by arguments)...
!     END SUBROUTINE URPP
!   END INTERFACE
!
! The subroutine PPDIPO, given X/Y coordinates defining the vertices
! of a "clip polygon" in (XCCP(I),I=1,NCCP) and (YCCP(I),I=1,NCCP),
! X/Y coordinates defining the vertices of a "subject polygon" in
! (XCSP(I),I=1,NCSP) and (YCSP(I),I=1,NCSP), and the real and integer
! workspaces RWRK and IWRK, each of which is of length NWRK, generates
! the set of polygons representing pieces of the subject polygon lying
! outside the clip polygon and delivers each of them to a user-defined
! polygon-processing routine called URPP.  Errors, in general, result
! in an immediate RETURN with IERR non-zero; on a normal return, IERR
! is zero.
!
! For most efficient use of memory, IWRK and RWRK should be EQUIVALENCEd
! to each other.
!
!---------------------------------------------------------------------
!
! SUBROUTINE NG_PPINPO( XCCP, YCCP, NCCP, XCSP, YCSP, NCSP, RWRK, IWRK, &
!                       NWRK, URPP, IERR )
!
!   INTEGER, INTENT(IN   ) :: NCCP
!   REAL,    INTENT(IN   ) :: XCCP(NCCP), YCCP(NCCP)
!   INTEGER, INTENT(IN   ) :: NCSP
!   REAL,    INTENT(IN   ) :: XCSP(NCSP), YCSP(NCSP)
!   INTEGER, INTENT(IN   ) :: NWRK
!   REAL                   :: RWRK(NWRK)
!   INTEGER                :: IWRK(NWRK)
!   INTEGER, INTENT(  OUT) :: IERR
!
!   INTERFACE
!     SUBROUTINE URPP (XCRA,YCRA,NCRA)
!       IMPLICIT NONE
!       INTEGER :: NCRA
!       REAL    :: XCRA(NCRA), YCRA(NCRA)
!       ! ...(code to process polygon boundary piece defined by arguments)...
!     END SUBROUTINE URPP
!   END INTERFACE
!
! The subroutine PPINPO, given X/Y coordinates defining the vertices
! of a "clip polygon" in (XCCP(I),I=1,NCCP) and (YCCP(I),I=1,NCCP),
! X/Y coordinates defining the vertices of a "subject polygon" in
! (XCSP(I),I=1,NCSP) and (YCSP(I),I=1,NCSP), and the real and integer
! workspaces RWRK and IWRK, each of which is of length NWRK, generates
! the set of polygons representing pieces of the subject polygon lying
! inside the clip polygon and delivers each of them to a user-defined
! polygon-processing routine called URPP.  Errors, in general, result
! in an immediate RETURN with IERR non-zero; on a normal return, IERR
! is zero.
!
! For most efficient use of memory, IWRK and RWRK should be EQUIVALENCEd
! to each other.
!
!---------------------------------------------------------------------
!
! SUBROUTINE NG_PPUNPO( XCCP, YCCP, NCCP, XCSP, YCSP, NCSP, RWRK, IWRK, &
!                       NWRK, URPP, IERR )
!
!   INTEGER, INTENT(IN   ) :: NCCP
!   REAL,    INTENT(IN   ) :: XCCP(NCCP), YCCP(NCCP)
!   INTEGER, INTENT(IN   ) :: NCSP
!   REAL,    INTENT(IN   ) :: XCSP(NCSP), YCSP(NCSP)
!   INTEGER, INTENT(IN   ) :: NWRK
!   REAL                   :: RWRK(NWRK)
!   INTEGER                :: IWRK(NWRK)
!   INTEGER, INTENT(  OUT) :: IERR
!
!   INTERFACE
!     SUBROUTINE URPP (XCRA,YCRA,NCRA)
!       IMPLICIT NONE
!       INTEGER :: NCRA
!       REAL    :: XCRA(NCRA), YCRA(NCRA)
!       ! ...(code to process polygon boundary piece defined by arguments)...
!     END SUBROUTINE URPP
!   END INTERFACE
!
! The subroutine PPUNPO, given X/Y coordinates defining the vertices
! of a "clip polygon" in (XCCP(I),I=1,NCCP) and (YCCP(I),I=1,NCCP),
! X/Y coordinates defining the vertices of a "subject polygon" in
! (XCSP(I),I=1,NCSP) and (YCSP(I),I=1,NCSP), and the real and integer
! workspaces RWRK and IWRK, each of which is of length NWRK, generates
! a set of polygons representing the union of the two input polygons and
! delivers each of them to a user-defined polygon-processing routine
! called URPP.  Errors, in general, result in an immediate RETURN with
! IERR non-zero; on a normal return, IERR is zero.
!
! For most efficient use of memory, IWRK and RWRK should be EQUIVALENCEd
! to each other.
!
!---------------------------------------------------------------------
!
! SUBROUTINE NG_PPDITR( XCCP, YCCP, NCCP, XCSP, YCSP, NCSP, RWRK, IWRK, &
!                       NWRK, URPT, IERR )
!
!   INTEGER, INTENT(IN   ) :: NCCP
!   REAL,    INTENT(IN   ) :: XCCP(NCCP), YCCP(NCCP)
!   INTEGER, INTENT(IN   ) :: NCSP
!   REAL,    INTENT(IN   ) :: XCSP(NCSP), YCSP(NCSP)
!   INTEGER, INTENT(IN   ) :: NWRK
!   REAL                   :: RWRK(NWRK)
!   INTEGER                :: IWRK(NWRK)
!   INTEGER, INTENT(  OUT) :: IERR
!
!   INTERFACE
!     SUBROUTINE URPT (XCBL,XCBR,YCOB,DXLE,DXRE,YCOT)
!       IMPLICIT NONE
!       REAL :: XCBL, XCBR, YCOB, DXLE, DXRE, YCOT
!       ! ...(code to process the trapezoid defined by the arguments)...
!     END SUBROUTINE URPT
!   END INTERFACE
!
! The subroutine PPDITR, given X/Y coordinates defining the vertices
! of a "clip polygon" in (XCCP(I),I=1,NCCP) and (YCCP(I),I=1,NCCP),
! X/Y coordinates defining the vertices of a "subject polygon" in
! (XCSP(I),I=1,NCSP) and (YCSP(I),I=1,NCSP), and the real and integer
! workspaces RWRK and IWRK, each of which is of length NWRK, generates
! a set of trapezoids representing pieces of the subject polygon lying
! outside the clip polygon and delivers each of them to a user-defined
! trapezoid-processing routine called URPT.  Errors, in general, result
! in an immediate RETURN with IERR non-zero; on a normal return, IERR
! is zero.
!
! For most efficient use of memory, IWRK and RWRK should be EQUIVALENCEd
! to each other.
!
!---------------------------------------------------------------------
!
! SUBROUTINE NG_PPINTR( XCCP, YCCP, NCCP, XCSP, YCSP, NCSP, RWRK, IWRK, &
!                       NWRK, URPT, IERR )
!
!   INTEGER, INTENT(IN   ) :: NCCP
!   REAL,    INTENT(IN   ) :: XCCP(NCCP), YCCP(NCCP)
!   INTEGER, INTENT(IN   ) :: NCSP
!   REAL,    INTENT(IN   ) :: XCSP(NCSP), YCSP(NCSP)
!   INTEGER, INTENT(IN   ) :: NWRK
!   REAL                   :: RWRK(NWRK)
!   INTEGER                :: IWRK(NWRK)
!   INTEGER, INTENT(  OUT) :: IERR
!
!   INTERFACE
!     SUBROUTINE URPT (XCBL,XCBR,YCOB,DXLE,DXRE,YCOT)
!       IMPLICIT NONE
!       REAL :: XCBL, XCBR, YCOB, DXLE, DXRE, YCOT
!       ! ...(code to process the trapezoid defined by the arguments)...
!     END SUBROUTINE URPT
!   END INTERFACE
!
! The subroutine PPINTR, given X/Y coordinates defining the vertices
! of a "clip polygon" in (XCCP(I),I=1,NCCP) and (YCCP(I),I=1,NCCP),
! X/Y coordinates defining the vertices of a "subject polygon" in
! (XCSP(I),I=1,NCSP) and (YCSP(I),I=1,NCSP), and the real and integer
! workspaces RWRK and IWRK, each of which is of length NWRK, generates
! a set of trapezoids representing pieces of the subject polygon lying
! inside the clip polygon and delivers each of them to a user-defined
! trapezoid-processing routine called URPT.  Errors, in general, result
! in an immediate RETURN with IERR non-zero; on a normal return, IERR
! is zero.
!
! For most efficient use of memory, IWRK and RWRK should be EQUIVALENCEd
! to each other.
!
!---------------------------------------------------------------------
!
! SUBROUTINE NG_PPUNTR( XCCP, YCCP, NCCP, XCSP, YCSP, NCSP, RWRK, IWRK, &
!                       NWRK, URPT, IERR )
!
!   INTEGER, INTENT(IN   ) :: NCCP
!   REAL,    INTENT(IN   ) :: XCCP(NCCP), YCCP(NCCP)
!   INTEGER, INTENT(IN   ) :: NCSP
!   REAL,    INTENT(IN   ) :: XCSP(NCSP), YCSP(NCSP)
!   INTEGER, INTENT(IN   ) :: NWRK
!   REAL                   :: RWRK(NWRK)
!   INTEGER                :: IWRK(NWRK)
!   INTEGER, INTENT(  OUT) :: IERR
!
!   INTERFACE
!     SUBROUTINE URPT (XCBL,XCBR,YCOB,DXLE,DXRE,YCOT)
!       IMPLICIT NONE
!       REAL :: XCBL, XCBR, YCOB, DXLE, DXRE, YCOT
!       ! ...(code to process the trapezoid defined by the arguments)...
!     END SUBROUTINE URPT
!   END INTERFACE
!
! The subroutine PPUNTR, given X/Y coordinates defining the vertices
! of a "clip polygon" in (XCCP(I),I=1,NCCP) and (YCCP(I),I=1,NCCP),
! X/Y coordinates defining the vertices of a "subject polygon" in
! (XCSP(I),I=1,NCSP) and (YCSP(I),I=1,NCSP), and the real and integer
! workspaces RWRK and IWRK, each of which is of length NWRK, generates
! a set of trapezoids representing the union of the two polygons and
! delivers each of them to a user-defined trapezoid-processing routine
! called URPT.  Errors, in general, result in an immediate RETURN with
! IERR non-zero; on a normal return, IERR is zero.
!
! For most efficient use of memory, IWRK and RWRK should be EQUIVALENCEd
! to each other.
!
!---------------------------------------------------------------------
!
! SUBROUTINE NG_PPPPAP( XCOP, YCOP, NCOP, NBTS )
!
!   INTEGER, INTENT(INOUT) :: NCOP
!   REAL,    INTENT(INOUT) :: XCOP(NCOP), YCOP(NCOP)
!   INTEGER, INTENT(IN   ) :: NBTS
!
! This routine may be called to pre-process a polygon that is to be
! used as input to one of the polygon-manipulation routines.  The
! polygon is defined by the points (XCOP(I),YCOP(I)), for I = 1 to
! NCOP.  NBTS is the number of significant bits to be left in the
! fractional parts of the point coordinates; you should probably not
! use a value less than about 10 (?) nor one greater than 24 on a
! machine with 32-bit reals or greater than 48 on a machine with
! 64-bit reals.  For most purposes, NBTS = 18 is probably okay.
!
!---------------------------------------------------------------------
!
! SUBROUTINE NG_PPPLCL( XMIN, XMAX, YMIN, YMAX, XCPL, YCPL, NCPL, &
!                       RWRK, LRWK, URPF, IERR )
!
!   REAL,    INTENT(IN   ) :: XMIN, XMAX, YMIN, YMAX
!   INTEGER, INTENT(IN   ) :: NCPL, LRWK
!   REAL,    INTENT(IN   ) :: XCPL(NCPL), YCPL(NCPL)
!   REAL                   :: RWRK(LRWK)
!   INTEGER, INTENT(  OUT) :: IERR
!
!   INTERFACE
!     SUBROUTINE URPF (XCRA,YCRA,NCRA)
!       IMPLICIT NONE
!       INTEGER :: NCRA
!       REAL    :: XCRA(NCRA), YCRA(NCRA)
!       ! ... code to process polyline fragment defined by arguments ...
!     END SUBROUTINE URPF
!   END INTERFACE
!
! This is a polyline clipping routine.  XMIN, XMAX, YMIN, and YMAX
! define a clipping rectangle.  The points (XCPL(I),YCPL(I)), for I
! from 1 to NCPL, define the polyline to be clipped.  The array RWRK,
! which is of length LRWK, is a real workspace array to be used for
! the fragments of the polyline that result from the clipping process.
! The user routine URPF will be called to process each such fragment.
! The value of LRWK must be at least 4; using a small value will have
! the effect of chopping up the polyline into pieces of length LRWK/2.
! IERR is an error flag: its value on return will be non-zero if and
! only if an error occurred; currently, the only errors detected are
! when NCPL is less than or equal to zero (IERR = 1) and when LRWK is
! less than than 4 (IERR = 2).
!
!=====================================================================
! Refer "NCAR menu" for interfacing POLYPACK in detail
!=====================================================================