C  SUBROUTINE VECTOR:	BY DR. J.A.FIELD
C			   DEPT. OF ELECTRICAL ENGINEERING
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,BEGIN)' AND ENDS AT
C          ARRAY(1,END). 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.
C          THE FIRST POINT IS AT 'ARRAY(1,BEGIN),ARRAY(2,BEGIN)
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,PICT,FIRST,LAST,IVECT,II,JJ,INT,ISPACE
          1,LTPEN)
          LOGICAL LTPEN,SWITCH,POINT
          INTEGER FIRST,OLDX,OLDY,PREV
          DIMENSION PICT (2,10),IVECT(100)
          COMMON /LIMITS/XMIN,XMAX,YMIN,YMAX
          COMMON /FRAME/ A,B,C,D
          COMMON/LINEND/XBEGIN,YBEGIN,XFINAL,YFINAL
          L = 1
          SWITCH = .FALSE.
          IF (MODE.LT.1) STOP 123456
          IF (MODE.GT.6) STOP 123456
          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,XBEGIN)
          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
C
C
C
C
C
C
C
C
C
C
C
C
C
          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
C
C
C
C
C
C
C
C
C
C
          SUBROUTINE SWAP
          COMMON/LINEND/ XFIRST,YFIRST,XLAST,YLAST
          TEMP = XFIRST
          XFIRST = XLAST
          XLAST = TEMP
          TEMP = YFIRST
          YFIRST = YLAST
          YLAST = TEMP
          RETURN
          END
