*------------- Telecommunications & Signal Processing Lab --------------
*                          McGill University
*
*
* Module:
*     SUBROUTINE PSXY (IX, IY, LINEWD)
*
*
* Purpose:
*     Generate a Postscript plot file vector
*
*
* Description:
*     This routine writes a plot vector to a Postscript plot file.  The
*     plot commands written to the file make use of Postscript macros
*     defined by routine PSHEAD.  Subroutine PSHEAD also initializes
*     variables in common area PSBBOX which tally bounding box
*     information.
*
*     This routine must be initialized with a call which has LINEWD=0
*     to establish the initial plotting position.  Redundant calls with
*     LINEWD=0 do not generate Postscript vectors.  Collinear vectors
*     are collapsed.  In order to accomplish this, Postscript vectors
*     lag by at least one call to this routine.  A final call with
*     LINEWD=0 must be used to push out any remaining vectors.
*
*     This routine updates the bounding box information which reflects
*     the extent of visible vectors, i.e. those with non-zero line
*     width.
*
*
* Parameters:
* I ->  IX     - X coordinate in plotting units (0 to 4095)
* I ->  IY     - Y coordinate in plotting units (0 to 4095)
* I ->  LINEWD - Line width in plotting units
*                0 - no plot vector is generated
*                negative - a white vector of width -LINEWD is
*                           generated
*                positive - a black vector of width LINEWD is
*                           generated
*
*
* Author / revision:
*     P. Kabal
*     $Revision: 1.5 $  $Date: 1995/03/08 15:29:36 $
*
*
*-----------------------------------------------------------------------

      SUBROUTINE PSXY (IX, IY, LINEWD)


      INTEGER IX,IY,LINEWD
      INTEGER IDX1,IDY1,IDX2,IDY2

      INTEGER IXP,IYP,LWP,IXS,IYS
      SAVE IXP,IYP,LWP,IXS,IYS

      INTEGER LUNPS,IPRTPS
      CHARACTER*255 FNAMPS
      COMMON /PSCOM/ LUNPS,IPRTPS,FNAMPS

      DATA IXP,IYP,LWP/0,0,0/


      IF (LINEWD.EQ.0) THEN

* Pen up, check if previously down
        IF (LWP.NE.0) CALL PSVECT(LUNPS,IXP,IYP,LWP)

      ELSE IF (LWP.EQ.0) THEN

* Pen down, previously up
* Set the start position of a collinear segment
        CALL PSVECT(LUNPS,IXP,IYP,LWP)
        IXS=IXP
        IYS=IYP

      ELSE

* Pen down, previously down
* Bypass collinear segments (including segments of zero length)
* The test for collinearity involves a check of slopes and a check
* that the two vectors are in the same direction.
        IDX1=IXP-IXS
        IDY1=IYP-IYS
        IDX2=IX-IXP
        IDY2=IY-IYP

* Each of IDX1, IDY1, IDX2, and IDY2 can be negative, zero or positive.
* Tests: S: (IDX2*IDY1==IDY2*IDX1)  slope check
*        X: (IDX1*IDX2>=0)          X-direction check
*        Y: (IDY1*IDY2>=0)          Y-direction check
* (1) For non-zero increments, if the slopes match, then IDX1*IDX2 and
*     IDY1*IDY2 are either both positive or both negative.  Then X=Y.
*     A full test for collinearity is (S .AND. X).
* (2) Zero length segments can be considered to be collinear with any
*     other segment.  Consider a zero length segment, IDX1=IDY1=0.  The
*     slope check works.  The direction checks also work since they
*     include a check against zero.  Note that X=Y.  The same argument
*     shows that if IDX2=IY2=0, the checks also work.  The full test
*     for collinearity is (S .AND. X).
* (3) Horizontal lines, IDY1=IDY2=0.  The slope check and the
*     Y-direction checks are automatically satisfied.  The X-direction
*     check must also be satisfied.  A full test for collinearity is X.
* (4) Vertical lines, IDX1=IDX2=0.  The slope check and the X-direction
*     checks are automatically satisfied.  The Y-direction check must
*     also be satisfied.  A full test for collinearity is Y.
* (5) A single zero increment will fail the slope check.
* (6) Two zero increments such as IDX1=IDY2=0 or IDX2=IDY1=0 will fail
*     the slope check.  The other cases of two zero increments are
*     covered above.
* (7) The cases of three or four zero increments involve zero length
*     segments and revert to the tests as covered above.
* Summarizing, a full check for collinearity that will cover all cases
* is (S .AND. X .AND. Y).
        IF ((IDX2*IDY1.NE.IDY2*IDX1) .OR.
     -      (IDX1*IDX2.LT.0) .OR.
     -      (IDY1*IDY2.LT.0)) THEN
          IXS=IXP
          IYS=IYP
          CALL PSVECT(LUNPS,IXP,IYP,LWP)
        END IF

      END IF

* Save the present coordinates for the next time
      IXP=IX
      IYP=IY
      LWP=LINEWD


      RETURN

      END
