	SUBROUTINE SCALE (ARRAY,AXLEN,NPTS,INC)
C
C	NAME: SCALE
C
C	LANGUAGE:  FORTRAN
C
C	OPERATING SYSTEM:  DEC VAX/VMS
C
C	ORDER NUMBER:  5448-SE
C
C	PART NUMBER:  000-025522-001  OCTOBER 1985
C
C	PRODUCT:  DEC VAX/VMS 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
	INCLUDE 'MSGCOM.CMN'
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
