      SUBROUTINE SCALE (ARRAY,AXLEN,NPTS,INC)
C
C     NAME: SCALE
C
C    LANGUAGE:  FORTRAN
C
C    OPERATING SYSTEM:  UNIVERSAL
C
C    ORDER NUMBER:  5428-SE
C
C    PART NUMBER:  000-026366  NOVEMBER 1985
C
C    PRODUCT:  UNIVERSAL VERSAPLOT COLOR RANDOM 2.0
C
C    VERSATEC, INC., SANTA CLARA, CALIFORNIA 95051
C    A XEROX COMPANY
C
C    Copyright (C) 1985 by Xerox Corporation.  All rights reserved.
C
C    "NOTICE. THIS PROGRAM IS THE EXCLUSIVE PROPERTY OF VERSATEC,
C    INC. AND IS ISSUED IN STRICT CONFIDENCE UNDER A PREARRANGED
C    LICENSE AGREEMENT AND IS NOT TO BE DISCLOSED IN ANY MANNER TO
C    PERSONS OUTSIDE THE LICENSED ORGANIZATION AND SHALL NOT BE
C    REPRODUCED OR DISSEMINATED, IN WHOLE OR PART, TO ANYONE OUTSIDE
C    THE LICENSED ORGANIZATION WITHOUT THE PRIOR WRITTEN APPROVAL OF
C    VERSATEC, INC. UNLESS OTHERWISE PROVIDED FOR BY SUCH LICENSE
C    AGREEMENT.  THIS WORK IS PROTECTED AS AN UNPUBLISHED WORK UNDER
C    THE COPYRIGHT ACT OF 1976."
C
C     SCALE - SCALE DATA POINT VALUES
C
C     SUBROUTINE SCALE CONFORMS TO CONVENTIONAL PEN PLOTTER DESCRIP-
C     TIONS AND MAY BE USED TO COMPUTE SCALE FACTORS FOR PROCESSING
C     UNSCALED DATA WITH SUBROUTINES LINE AND AXIS.  THE STARTING
C     VALUE, FVAL, REPRESENTING THE STARTING UNSCALED DATA VALUE
C     (EITHER UNSCALED MINIMUM OR MAXIMUM), AND THE SCALING FACTOR,
C     DV, REPRESENTING THE NUMBER OF UNSCALED DATA UNITS PER UNIT,
C     ARE RETURNED TO THE NEXT TWO ELEMENTS (AS MODIFIED BY INC)
C     BEYOND THE STARTING ADDRESS OF ARRAY PLUS NPTS.
C
C     ENTRY: CALL SCALE(ARRAY,AXLEN,NPTS,INC)
C
C            ARRAY - ARRAY OF UNSCALED DATA POINTS TO BE EXAMINED
C                   (REAL)
C            AXLEN - THE AXIS LENGTH TO WHICH THE UNSCALED DATA IN
C                   ARRAY IS TO BE SCALED.  AXLEN MUST BE GREATER
C                   THAN 1.0 UNIT. (REAL)
C            NPTS - NUMBER OF DATA POINTS TO BE SCALED IN ARRAY.
C                   THIS VALUE SHOULD NOT INCLUDE VALUES SKIPPED BY
C                   INC OR THE LAST TWO ELEMENTS WHICH WILL BE SET TO
C                   THE SCALING FACTORS.  NOTE: IF INC IS NOT +-1,
C                   THE DIMENSION OF ARRAY MUST BE AT LEAST ABS(INC)*
C                   (NPTS+2). (INTEGER)
C            INC - IS THE INCREMENT (ABSOLUTE) USED IN GATHERING DATA
C                  FROM THE UNSCALED ARRAY(FOR EXAMPLE:
C                   INC=1 WILL INDEX EACH DATA ELEMENT,
C                   INC=2 WILL INDEX EVERY OTHER ELEMENT,
C                   INC=3 WILL INDEX EVERY THIRD DATA ELEMENT,
C                         AND SO FORTH).
C                 +INC - WHEN INC IS POSITIVE, THE FIRST UNSCALED
C                       VALUE(FVAL) APPPROXIMATES, A MINIMUM WITH A
C                       POSITIVE SCALE FACTOR(+DV).
C                 -INC - WHEN INC IS NEGATIVE, THE FIRST UNSCALED
C                       VALUE (FVAL) APPROXIMATES A MAXIMUM WITH A
C                       NEGATIVE SCALE FACTOR (-DV).
C
C     EXIT: RETURN
C
C     CALLED BY: USER
C
C     CALLS: NONE
C
C     COMMON USED:
C
C     /MSGCOM/
C            I INTARG()- ARRAY FOR PASSING INTEGER OUTPUT ARGUMENTS
C            R RELARG()- ARRAY FOR PASSING REAL OUTPUT ARGUMENTS
C
C
C     LOCAL:
C            R  AMIN - THE SMALLEST VALUE (ALGEBRAICALLY) IN THE DATA
C            R  AMAX - THE LARGEST VALUE (ALGEBRAICALLY) IN THE DATA
C            R  A    - A TEMPORARY FOR INITIAL SCAN OF DATA. A NORMAL-
C                    IZING FACTOR FOR DV DURING SCALING COMPUTATION.
C            R  DV   - THE DELTA VALUE PER AXIS VALUE
C            I  I    - LOOP PARAMETER AND SUBSCRIPT INTO UNITS ARRAY
C            I  J    - SUBSCRIPT OF LAST DATA POINT TO BE EXAMINED
C            I  K    - ABSOLUTE VALUE OF INC
C            R  SGNF - A ROUNDING FACTOR
C            R  TMIN - AXIS SCALED STARTING VALUE
C            RA UNITS- ARRAY OF DELTA VALUES
C
C
C
C
C...  COMMON /MSGCOM/ - MESSAGE OUTPUT VARIABLES
C
      COMMON /MSGCOM/ INTARG(8), RELARG(12)
C
C
C
      DIMENSION ARRAY(1)
C
      DIMENSION UNITS(7)
      DATA UNITS(1)/1./,UNITS(2)/2./,UNITS(3)/4./,UNITS(4)/5./
      DATA UNITS(5)/8./,UNITS(6)/10./,UNITS(7)/20./
C
C
C-D   DEBUG MESSAGE
C      RELARG(1)=ARRAY(1)
C      RELARG(2)=AXLEN
C      INTARG(1)=NPTS
C      INTARG(2)=INC
C      CALL MSGLG1(85)
C-D
C
C...  DETERMINE MIN AND MAX VALUES OF 'ARRAY'.
C     K IS SET TO THE ABSOLUTE VALUE OF THE INCREMENT BETWEEN POINTS
C     TO BE EXAMINED.  J IS SET TO SUBSCRIPT OF LAST POINT IN THE
C     ARRAY (NOT EXAMINED BY SCALE UNLESS ABS(INC)=1).  MINIMUM AND
C     MAXIMUM VALUES INITIALIZED TO FIRST VALUE.
      K = IABS (INC)
      J = NPTS*K
      AMIN = ARRAY(1)
      AMAX = AMIN
C
C...  DATA ARRAY IS SCANNED TO DETERMINE MAXIMUM AND MINIMUM VALUES.
      DO 10 I=1,J,K
      A = ARRAY(I)
C
C...  NEW MIN FOUND?
      IF (A.LT.AMIN) AMIN = A
C
C...  NEW MAX FOUND?
      IF (A.GT.AMAX) AMAX = A
   10 CONTINUE
C
C...  COMPUTE DELTA VALUE FOR UNSCALED UNIT INTERVAL
      DV = (AMAX - AMIN)/AXLEN
C
C...  DELTA OK?
C     THE DELTA CANNOT BE NEGATIVE, BUT IT CAN BE ZERO
C     IF ALL VALUES IN ARRAY WERE IDENTICAL.  IN THIS CASE A
C     NEW DELTA IS COMPUTED THAT IS POSITIVE AND NON-ZERO.
      IF (DV.GT.0.) GO TO 20
C
C...  ERROR - AMAX AND AMIN NOT IN CORRECT RANGE
      DV = ABS ((AMIN + AMIN)/AXLEN) + 1.
C
C...  COMPUTE TENS POWER OF 'DV' VALUE(NORMALIZED VALUE)
C     THE 1000 IS A LARGE, ARBITRARY CONSTANT WHICH FORCES THE
C     OPERATION TO ALWAYS HAVE A POSITIVE ARGUMENT.  NOTE THAT IFIX
C     NORMALLY WORKS WITH THE MAGNITUDE OF ITS ARGUMENT WHICH
C     TRUNCATES THE WRONG DIRECTION ON A NEGATIVE ARGUMENT.
   20 A = 10.0**(IFIX (ALOG10 (DV) + 1000.) - 1000)
C
C     COMPUTE NORMALIZED 'DV' VALUE (1. < DV < 10.)
      DV = DV/A - 0.01
C
C...  LOCATE CLOSEST "UNIT" DV VALUE (NORMALIZED).
C     THE SMALLEST VALUE GREATER THAN OR EQUAL TO DV IS FOUND IN THE
C     UNITS ARRAY (THE 1st 6 VALUES ARE 1.,2.,4.,5.,8. AND 10.)
      DO 30 I=1,6
C
C...  VALUE FOUND?
      IF (UNITS(I).GE.DV) GO TO 40
   30 CONTINUE
C
C...  SET NORMALIZED 'SIGNIFICANCE' DIRECTION.  SET ROUNDING FACTOR
   40 SGNF = 0.01
C
C...  WRONG SIGNIFICANCE DIRECTION?
      IF (AMIN.LT.0.) SGNF = -0.99
C
C...  EXPAND UNIT 'DV' TO FLOATING.
C...  COMPUTE DV BASED ON VALUE FROM UNITS ARRAY.
   50 DV = UNITS(I)*A
C
C...  A STARTING VALUE IS COMPUTED FROM THE MINIMUM DATA VALUE
C...  AND THE NEW DELTA VALUE.  NOTE THAT AINT RETURNS A REAL
C...  VALUE THAT IS THE INTEGER PORTION OF ITS ARGUMENT.
      TMIN = DV*AINT (AMIN/DV + SGNF)
C
C...  DOES ADJUSTED "UNIT" SCALE FIT AXIS LENGTH?
C     IF THE COMPUTED STARTING VALUE AND DELTA VALUE WILL ALLOW ALL
C     DATA TO FIT ON THE AXIS, JUMP TO 60.  OTHERWISE, A SLIGHTLY
C     DIFFERENT STARTING VALUE IS COMPUTED.
      IF ((TMIN + (AXLEN + 0.01)*DV).GE.AMAX) GO TO 60
      TMIN = AINT (AMIN/A + SGNF) *A
C
C...  DOES ADJUSTED "UNIT" SCALE FIT AXIS LENGTH?
C     IF THE RECOMPUTED STARTING VALUE ALLOWS ALL DATA TO FIT ON THE
C     AXIS, JUMP TO 60.  OTHERWISE, THE NEXT UNITS VALUE IS
C     SELECTED AND A NEW DELTA VALUE AND STARTING VALUE ARE COMPUTED
C     AT 50.
      IF ((TMIN + (AXLEN + 0.01)*DV).GE.AMAX) GO TO 60
      I = I + 1
      GO TO 50
C
C...  THE MINIMUM IS ADJUSTED DOWNWARD BY HALF THE DIFFERENCE
C...  BETWEEN THE AXIS LENGTH AND THE NUMBER OF UNITS IN THE RANGE.
   60 TMIN = TMIN - DV*AINT ((AXLEN + (TMIN - AMAX)/DV)/2.0)
C
C...  DOES TMIN NEED CORRECTION?  IF SO, FORCE TMIN TO BE
C     NON-NEGATIVE.
      IF (AMIN*TMIN.LE.0.0) TMIN = 0.0
C
C...  SCALE DIRECTION OK?
C     IF THE DATA IS TO BE PLOTTED NORMALLY, JUMP TO 70.
C     IF THE DATA IS TO BE PLOTTED "BACKWARD",
C     TMIN IS MADE A MAXIMUM VALUE AND DV IS
C     COMPLEMENTED.
      IF (INC.GT.0) GO TO 70
C
C...  REVERSE DIRECTION OF SCALE
      TMIN = TMIN + DV*AINT (AXLEN + 0.5)
      DV = -DV
C
C...  THE STARTING VALUE AND DELTA VALUE ARE SET INTO THE DATA ARRAY.
   70 J = J + 1
      ARRAY(J) = TMIN
      K = J + K
      ARRAY(K) = DV
C
      RETURN
C
      END
