C  SUBROUTINE VECTOR:
C
C  2 SEPT 71
C
C
C        THIS SUBROUTINE WILL PLOT POINTS, STRAIGHT LINES,
C        OR CURVES. IT PREVENTS LINES  BEING DRAWN OUTSIDE
C        THE SCREEN LIMITS, AND AS AN OPTION IT WILL TRIM
C        LINES TO FIT WITHIN A GIVEN WINDOW.
C
C
C        THE CALLING SEQUENCE IS:
C
C
C  CALL VECTOR(MODE,ARRAY,BEGIN,END,IVECT,FIRST,LAST,INT,ISPACE,LTPEN)
C
C        WHERE: ARRAY IS REAL
C               LTPEN IS LOGICAL
C               ALL OTHERS ARE INTEGER
C
C
C
C
C
C
C        THE DISPLAY FILE IS GENERATED STARTING AT IVECT(FIRST)
C        AND AFTER GENERATION , THE PROGRAM SETS 'LAST' SUCH
C        THAT 'IVECT(LAST)' IS THE LAST ELEMENT IN THE DISPLAY
C        FILE. 'INT' SPECIFIES THE DISPLAY INTENSITY (0 - 7),
C        'ISPACE' SPECIFIES POINT SPACING ON THE SCREEN (1,2,4,8)
C        RASTER UNIT. IF 'LTPEN=.TRUE.' THEN LIGHT PEN INTERRUPTS
C        ARE IGNORED.
C
C
C
C        WHEN (MODE=1) OR (MODE=2), 'ARRAY' IS A (4 BY N)
C        ARRAY SPECIFYING A SET AT LINES (X1,Y1,  X2,Y2),
C        AND ALL LINES BETWEEN.
C
C        'ARRAY(1,BEGIN)' AND 'ARRAY(1,END)' WILL BE PLOTTED
C        FOR (MODE=2) ONLY THAT PART OF A LINE INSIDE A
C        WINDOW IS PLOTTED.
C
C
C
C
C        WHEN (MODE=3) OR (MODE=4) 'ARRAY' IS A (2 BY N)
C        ARRAY SPECIFYING THE (X,Y) PAIRS OF A CURVE. THE
C        CURVE BEGINS AT 'ARRAY(1,FIRST)' AND ENDS AT
C        ARRAY(1,LAST). FOR MODE=4, ONLY THAT PART OF THE
C        CURVE INSIDE THE WINDOW IS PLOTTED.
C
C
C
C
C
C
C
C
C
C
C
C
C
C
C
C        WHEN (MODE=5) OR (MODE=6) ,    'ARRAY' IS A (2 BY N)
C        ARRAY SPECIFYING (X,Y) POINTS TO BE PLOTTED.
CC        THE FIRST POINT IS AT 'ARRAY(1,FIRST),ARRAY(2,FIRST)
C        AND THE LAST IS AT 'ARRAY(1,END),ARRAY(2,END).
C         FOR MODE =6, ONLY THOSE POINTS INSIDE THE WINDOW
C        ARE PLOTTED.
C
C
C
C
C
C
C  WINDOW:
C
C        TO SPECIFY A WINDOW REQUIRES THE STATEMENT;
C
C        COMMON/FRAME/A,B,C,D
C
C        IN THE MAIN PROGRAM. THE WINDOW KEEPS-
C                                        A.LE.X.LE.B
C                                        C.LE.Y.LE.D
C
C        NOTE: THESE LIMITS ARE INDEPENDENT OF 'XMAX' ETC.,
C              THAT SPECIFY THE SCREEN SIZE. THERE IS NO NEED
C              FOR THE WINDOW TO BE COMPLETELY ON THE SCREEN.
C
C
C
C
C
C
C
C
        SUBROUTINE VECTOR (MODE,IVECT,II,JJ,INT,ISPACE,LTPEN)
        LOGICAL LTPEN,SWITCH,POINT
        INTEGER FIRST,OLDX,OLDY,PREV
        DIMENSION IVECT(500)
        COMMON /LIMITS/XMIN,XMAX,YMIN,YMAX
        COMMON /FRAME/ A,B,C,D
      COMMON/PAINT/FIRST,LAST,PICT(2,200)
        COMMON/LINEND/XBEGIN,YBEGIN,XFINAL,YFINAL
        L = 1
        SWITCH = .FALSE.
        IF (MODE.LT.1) STOP 12345
        IF (MODE.GT.6) STOP 12345
        GO TO (101,102,103,104,105,106), MODE
101     SWITCH = .TRUE.
102     IFIRST = FIRST*2-1
        ILAST = LAST*2
        INCRE = 2
        GO TO 11
105     SWITCH = .TRUE.
106     L = 0
        ILAST = LAST
        GO TO 200
103     SWITCH = .TRUE.
104     ILAST = LAST - 1
200     IFIRST = FIRST
        INCRE = 1
11      OLDX = -1
        PREV = -1
        J = II
        JOG = 4168
        IF (LTPEN) JOG = JOG+2048
        ISP = ISPACE/2
        IF (ISP.LT.0) ISP = 0
        IF (ISP.GT.3) ISP = 3
        INTX = INT
        IF (INT.LT.0) INTX = 7
        IF (INT.GT.7) INTX = 7
        JOG = JOG + ISP*16 + INT
        ISCALE = 2**ISP
        XLOW = AMIN1 (XMIN,XMAX)
        XHIGH = AMAX1(XMIN,XMAX)
        YLOW = AMIN1(YMIN,YMAX)
        YHIGH = AMAX1(YMIN,YMAX)
        IF (SWITCH) GO TO 20
        XLOW = AMAX1(XLOW,AMIN1(AMIN1(A,B),XHIGH))
        XHIGH = AMIN1(XHIGH,AMAX1(AMAX1(A,B),XLOW))
        YLOW = AMAX1(YLOW,AMIN1(AMIN1(C,D),YHIGH))
        YHIGH = AMIN1(YHIGH,AMAX1(AMAX1(C,D),YLOW))
20      IF (XLOW.EQ.XHIGH.OR.YLOW.EQ.YHIGH) GO TO 65
        XDIFF = 1023./(XMAX-XMIN)
        YDIFF = 1023./(YMAX-YMIN)
        DO 9 I = IFIRST,ILAST,INCRE
C
C  GET END POINTS OF LINE
C
        XBEGIN = PICT (1,I)
        YBEGIN = PICT (2,I)
        K = I+L
        XFINAL = PICT (1,K)
        YFINAL = PICT (2,K)
C
C  TRIM LINE SO THAT IT WILL FIT ON THE SCREEN
C
        SWITCH = ABS(XFINAL-XBEGIN).GT.ABS(YFINAL-YBEGIN)
        IF (SWITCH) GO TO 50
60      IF (XBEGIN.GT.XFINAL) CALL SWAP
        IF (XBEGIN.GT.XHIGH.OR.XFINAL.LT.XLOW) GO TO 9
        IF (XBEGIN.LT.XLOW) CALL TRIM(XBEGIN,YBEGIN,XLOW,XFINAL,YFINAL)
        IF (XFINAL.GT.XHIGH) CALL TRIM(XFINAL,YFINAL,XHIGH,XBEGIN
     1,YBEGIN)
        IF (SWITCH) GO TO 70
50      IF (YBEGIN.GT.YFINAL) CALL SWAP
        IF (YBEGIN.GT.YHIGH.OR.YFINAL.LT.YLOW) GO TO 9
        IF (YBEGIN.LT.YLOW) CALL TRIM(YBEGIN,XBEGIN,YLOW,YFINAL
     2,XFINAL)
        IF (YFINAL.GT.YHIGH) CALL TRIM(YFINAL,XFINAL,YHIGH,YBEGIN
     3,XBEGIN)
        IF (SWITCH) GO TO 60
C
C  CONVERT END POINTS TO SCREEN COORDINATES
C
70      IXX1 = (XBEGIN - XMIN)*XDIFF + 0.5
        IYY1 = (YBEGIN - YMIN)*YDIFF + 0.5
        IXX2 = (XFINAL - XMIN)*XDIFF + 0.5
        IYY2 = (YFINAL - YMIN)*YDIFF + 0.5
C
C  CHECK IF BEAM REPOSITIONING REQUIRED
C
        IF (IXX1.NE.OLDX) GO TO 1111
        IF (IYY1.EQ.OLDY) GO TO 2
1111    IF (IXX2.NE.OLDX) GO TO 1
        IF (IYY2.NE.OLDY) GO TO 1
        IXX2 = IXX1
        IYY2 = IYY1
        IXX1 = OLDX
        IYY1 = OLDY
        GO TO 2
C
C  BEAM REPOSITIONING IS REQUIRED.  THREE POSSIBLE CASES EXIST.
C
C  PREV = -1     , INITIAL POINT
C  PREV = 0      , LAST ITEM WAS A VECTOR
C  PREV - +1     , LAST ITEM WAS A POINT
C
1       POINT = .FALSE.
17      IF (PREV) 1001,1002,1003
C
C  ADJUST PREVIOUS POINT WORD
C
1003    IVECT(J) = IVECT(J) - 24576
        GO TO 1004
C
C  INSERT ESCAPE BIT IN PREVIOUS VECTOR, AND ADD PARAMETER WORD
C
1002    IVECT(J) = IVECT(J) - 65536 - 65536
1001    J = J+1
        IVECT(J) = 8192 + JOG
C
C  ADD POINT WORDS
C
1004    J = J+1
        IVECT(J) = IYY1 + 73728
        J = J+1
        IVECT(J) = IXX1 + 33792
C
C  INDICATE THAT POINT OPERATION HAS OCCURRED
C
        PREV = 1
        IF (POINT) GO TO 9
C
C  REMEMBER WHERE END OF LINE NOW IS
C
2       OLDX = IXX2
        OLDY = IYY2
C
C  START GENERATION OF THE REQUIRED VECTOR
C
        IWORD = 65536
C
C GET SIGN OF DELTA X
C
        IXINC = IXX2 - IXX1
        IF (IXINC.GE.0) GO TO 3
        IWORD = IWORD + 128
        IXINC = -IXINC
C
C  GET SIGN OF DELTA Y
C
3       IYINC = IYY2 - IYY1
        IF (IYINC.GE.0) GO TO 4
        IWORD = IWORD + 32768
        IYINC = -IYINC
C
C  IF SCALE NOT UNITY THEN MUST ADJUST FOR SCALE FACTOR
C
4       IF (ISCALE.EQ.1) GO TO 5
        IX = IXINC/ISCALE
        IY = IYINC/ISCALE
        IXJUST = IXINC - IX*ISCALE
        IYJUST = IYINC - IY*ISCALE
        IXINC = IX
        IYINC = IY
C
C  CALCULATE NUMBER OF LINE SEGMENTS REQUIRED
C
5       IF (IXINC + IYINC.EQ.0) GO TO 6
        ISEGMT = (MAX0(IYINC,IXINC)-1)/127 + 1
        IROUND = ISEGMT/2
        IX = 0
        IY = 0
C
C  GENERATE VECTOR ELEMENTS
        DO 100 M = 1,ISEGMT
        IXVEC = (IXINC*M+IROUND)/ISEGMT - IX
        IYVEC = (IYINC*M+IROUND)/ISEGMT - IY
        IX = IX + IXVEC
        IY = IY + IYVEC
        J = J+1
100     IVECT (J) = IWORD + IYVEC*256 + IXVEC
C
C  INDICATE VECTOR GENERATION HAS OCCURRED
C
        PREV = 0
C
C  CHECK IF MUST ADJUST FOR NON-UNITY SCALE FACTOR
C
6       IF (ISCALE.EQ.1) GO TO 9
        POINT = .TRUE.
        IXX1 = OLDX
        IYY1 = OLDY
        IF (IXJUST+IYJUST.GT.0) GO TO 17
C
9       CONTINUE
C
C  CHECK IF ENDED ON A POINT OR VECTOR, OR NEVER GOT STARTED
C
65      IF (PREV) 13,14,12
C
C  IT'S A VECTOR
C
14      IVECT(J) = IVECT(J) - 65536 - 65536
        GO TO 13
12      IVECT(J) = IVECT(J) - 32768
13      J = J+1
        IVECT(J) = 57344
        JJ = J+1
        RETURN
        END
        SUBROUTINE TRIM(XOUT,YOUT,XBOUND,XOK,YOK)
C
C  IN ORDER TO RETAIN AS MUCH ACCURACY AS POSSIBLE WHEN ONE OF
C  THE END POINTS IS CLOSE TO THE MACHINE BOUND, WE WILL ALWAYS
C  CALCULATE THE Y INTERCEPT BY SUBTRACTION FROM THE POINT
C  NEAREST THE XBOUND
C
        BASE = (YOUT-YOK)/(XOUT-XOK)
        DELTA1 = XBOUND-XOUT
        DELTA2 = XBOUND - XOK
        IF (ABS(DELTA1).GT.ABS(DELTA2)) GO TO 1
        YOUT = YOUT + DELTA1*BASE
        GO TO 2
1       YOUT = YOK + DELTA2*BASE
2       XOUT = XBOUND
        RETURN
        END
        SUBROUTINE SWAP
        COMMON/LINEND/ XFIRST,YFIRST,XLAST,YLAST
        TEMP = XFIRST
        XFIRST = XLAST
        XLAST = TEMP
        TEMP = YFIRST
        YFIRST = YLAST
        YLAST = TEMP
        RETURN
        END
