      SUBROUTINE SURF(V,A,XMIN,XMAX,M,YMIN,YMAX,N,ZMIN,ZMAX,
     1DX,DY,DZ)

*
*
*  This software was developed by the Thermal Modeling and Analysis
*  Project(TMAP) of the National Oceanographic and Atmospheric
*  Administration's (NOAA) Pacific Marine Environmental Lab(PMEL),
*  hereafter referred to as NOAA/PMEL/TMAP.
*
*  Access and use of this software shall impose the following
*  obligations and understandings on the user. The user is granted the
*  right, without any fee or cost, to use, copy, modify, alter, enhance
*  and distribute this software, and any derivative works thereof, and
*  its supporting documentation for any purpose whatsoever, provided
*  that this entire notice appears in all copies of the software,
*  derivative works and supporting documentation.  Further, the user
*  agrees to credit NOAA/PMEL/TMAP in any publications that result from
*  the use of this software or in any product that includes this
*  software. The names TMAP, NOAA and/or PMEL, however, may not be used
*  in any advertising or publicity to endorse or promote any products
*  or commercial entity unless specific written permission is obtained
*  from NOAA/PMEL/TMAP. The user also understands that NOAA/PMEL/TMAP
*  is not obligated to provide the user with any support, consulting,
*  training or assistance of any kind with regard to the use, operation
*  and performance of this software nor to provide the user with any
*  updates, revisions, new versions or "bug fixes".
*
*  THIS SOFTWARE IS PROVIDED BY NOAA/PMEL/TMAP "AS IS" AND ANY EXPRESS
*  OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
*  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
*  ARE DISCLAIMED. IN NO EVENT SHALL NOAA/PMEL/TMAP BE LIABLE FOR ANY SPECIAL,
*  INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
*  RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
*  CONTRACT, NEGLIGENCE OR OTHER TORTUOUS ACTION, ARISING OUT OF OR IN
*  CONNECTION WITH THE ACCESS, USE OR PERFORMANCE OF THIS SOFTWARE. 
*
*
* revised for TMAP
* from PPLUS :
*	Directory PMEL:[PLOT5.PPLV11.PLOTLIB]SURF.FOR

* search for "TMAP" to find all revisions
* *sh*  - 1/23/89 added interrupt detection
*		  ... no explicit declarations (too much trouble !) so it must
*		      be compiled with /WARNINGS=NODECLARATIONS
C**
C**    @(#)surf.F	1.1    3/10/88
C**
C**
C***********************************************************************
C**
C**                 PLOT+ Scientific Graphics System
C**
C***********************************************************************
C**
C**
C SURF IS A FRONT END ROUTINE FOR SURFCE TO EVALUATE A FUNCTION
C OF TWO VARIABLES AND STORE THE RESULTS IN AN ARRAY TO PASS TO
C SURFCE.  THE CALLING STRING IS:
C V    - THE FUNCTION NAME--MUST BE A FUNCTION OF (X,Y)
C A    - A SINGLE DIMENSIONED ARRAY OF LENGTH M*N
C XMIN - MINIMUM VALUE OF X.
C XMAX - MAXIMUM VALUE OF X.
C M    - THE NUMBER OF X VALUES I.E. THE NUMBER OF ROWS.
C YMIN - MINIMUM VALUE OF Y.
C YMAX - MAXIMUM VALUE OF Y.
C N    - THE NUMBER OF Y VALUES I.E. THE NUMBER OF COLUMNS.
C ZMIN - MINIMUM VALUE OF Z
C ZMAX - THE MAXIMUM VALUE OF Z
C DX   - THE X COORDINATE OF THE VIEW POINT.
C DY   - THE Y COORDINATE OF THE VIEW POINT.
C DZ   - THE Z COORDINATE OF THE VIEW POINT.
C
C THE FUNCTION IS EVALUATED AND STORED IN THE ARRAY A COLUMNWISE
C WITH THE FIRST LOCATION FILLED WITH F(XMIN,YMIN).  THE X VALUE INCREAS
C GOING DOWN A COLUMN AND THE Y VALUE INCREASES GOING ACROSS A ROW.
	external v
      DIMENSION A(1)

* Mod to specify external references for SCALE and RANGE * Linux *jd* 12.96
	external scale, size


      DLTAX=(XMAX-XMIN)/(M-1)
      DLTAY=(YMAX-YMIN)/(N-1)
      Y=YMIN
      IDX=1
      DO 20 J=1,N
      X=XMIN
      DO 10 I=1,M
      A(IDX)=V(X,Y)
      IDX=IDX+1
      X=X+DLTAX
   10 CONTINUE
      Y=Y+DLTAY
   20 CONTINUE
      CALL SURFCE(A,XMIN,XMAX,M,YMIN,YMAX,N,ZMIN,ZMAX,
     1DX,DY,DZ)
      RETURN
C**  THIS PROGRAM VALID ON FTN4 AND FTN5 **
      END
C*F45V1P0*
      SUBROUTINE SURFCE(F,XMIN,XMAX,M,YMIN,YMAX,N,
     1ZM,ZMX,DX,DY,DZ)
C SURFCE WILL PRODUCE A PERSPECTIVE DRAWING OF A FUNCTION OF
C 2 VARIABLES.  THE CALLING PARAMETERS ARE:
C
C  F   - A TWO DIMENSIONAL ARRAY OF DATA POINTS
C      - IT IS ASSUMED THAT THERE WILL BE M ROWS
C      - AND N COLUMNS.  IT IS ASSUMMED THAT THE ARRAY IS SET UP
C      - COLUMNWISE WITH F(1) CORRESPONDING TO FUN(XMIN,YMIN).
C      - THE COLUMNS MUST GO IN INCREASING X VALUES GOING DOWN
C      - AND INCREASING Y VALUES GOING ACROSS.
C  XM  - THE MINIMUM X VALUE
C  XMX - THE MAXIMUM X VALUE
C  M   - THE NUMBER OF INTERVALS IN THE X DIRECTION
C  YM  - THE MINIMUM Y VALUE
C  YMX - THE MAXIMUM Y VALUE
C  N   - THE NUMBER OF INTERVALS IN THE Y DIRECTION
C  ZM  - THE MINIMUM Z VALUE
C  ZMX - THE MAXIMUM Z VALUE
C  DX  - THE X COORDINATE OF THE VIEW POINT
C  DY  - THE Y COORDINATE OF THE VIEW POINT
C  DZ  - THE Z COORDINATE OF THE VIEW POINT
C
C  THE LABELED COMMON BLOCK USED IS FOR COMMUNICATION
C BETWEEN THE SUBROUTINES HIDE, TRANSF, AND INTERCEPT
C NONE OF THE VARIABLES NEED TO BE INITIALIZED BY
C THE CALLING PROGRAM.
C THIS SET OF SUBROUTINES WAS WRITTEN AT O.S.U. 10-1972
C BY JEFF BALLANCE.  THE FORMULAS WERE GOTTEN FROM THE REFERENCE:
C
C ^THE PERSPECTIVE REPRESENTATION OF FUNCTIONS OF TWO VARIABLES,^
C J.ACM (VOL. 15, NO. 2) APRIL 1968. PP. 193-204.
      DIMENSION F(1)
#ifdef unix
	include 'plt_inc.decl'
	include 'PLT.INC'
	include 'miss_inc.decl'
	include 'MISS.INC'
	include 'axis_inc.decl'
	include 'AXIS.INC'
#else
	INCLUDE 'TMAP_PPLV11INC:PLT_INC.DECL'
	INCLUDE 'PPLV11INC:PLT.INC'
	INCLUDE 'TMAP_PPLV11INC:MISS_INC.DECL'
	INCLUDE 'PPLV11INC:MISS.INC'
	INCLUDE 'TMAP_PPLV11INC:AXIS_INC.DECL'
	INCLUDE 'PPLV11INC:AXIS.INC'
#endif
	LOGICAL SKIP
      COMMON /LAB1/ CX,CY,CZ,QX,QY,QZ,DCQ,CALPHA,CBETA,CGAMMA,
     1DSAOB,IFLG,XTEST,YTEST,ZTEST,DLTAX1,DLTAY1,DLTAX,DLTAY
     2,ZMIN,ZMAX,XM,YM,DLTAXI,DLTAYI,MM,NN

* TMAP interrupt flag
#ifdef unix
	include 'xinterrupt.cmn'
#else
	INCLUDE 'tmap_pplv11inc:tmap_xinterrupt.cmn'
#endif

* Mod to specify external references for SCALE and RANGE * Linux *jd* 12.96
	external scale, size

C  INITIALIZE SOME THINGS IN THE COMMON BLOCK
      CX=DX
      CY=DY
      CZ=DZ
      ZMIN=ZM
      ZMAX=ZMX
      XM=XMIN
      YM=YMIN
      MM=M
      NN=N
C COMPUTE THE EDGES CLOSEST TO THE VIEW POINT.
      XTEST=CX
      IF(XMAX.LT.XTEST) XTEST=XMAX
      IF(XTEST.LT.XMIN) XTEST=XMIN
      YTEST=CY
      IF(YMAX.LT.YTEST) YTEST=YMAX
      IF(YTEST.LT.YMIN) YTEST=YMIN
      ZTEST=CZ
      IF(ZMAX.LT.ZTEST) ZTEST=ZMAX
      IF(ZTEST.LT.ZMIN) ZTEST=ZMIN
C COMPUTE THE CENTER OF THE CUBE--THIS WILL BE POINT
C ON THE LINE OF SIGHT THROUGH WHICH THE PERSPECTIVE
C PLANE IS DEVELOPED PERPENDICULAR TO THE LINE OF
C SIGHT.
      QX=0.5*(XMAX+XMIN)
      QY=0.5*(YMAX+YMIN)
      QZ=0.5*(ZMAX+ZMIN)
C COMPUTE THE LENGTH OF LINE CQ
      CXQ=QX-CX
      CYQ=QY-CY
      CZQ=QZ-CZ
      T=CXQ*CXQ+CYQ*CYQ+CZQ*CZQ
      DCQ=SQRT(T)
C COMPUTE COS(ALPHA),COS(BETA),COS(GAMMA) WHERE
C (ALPHA,BETA,GAMMA) ARE THE ANGLES MADE WITH
C X,Y,Z AXIS RESPECTIVELY BY CQ.
      CALPHA=CXQ/DCQ
      CBETA=CYQ/DCQ
      CGAMMA=CZQ/DCQ
C COMPUTE SIN(GAMMA)--IF ZERO USE DIFFERENT FORMULA
C TO CALCULATE TRANSFORMED X AND Y WHICH USE SIN(BETA)
      DSAOB=SQRT(T-CZQ*CZQ)/DCQ
      IFLG=1
      IF(DSAOB.NE.0.0) GO TO 10
      IFLG=2
      DSAOB=SQRT(T-CYQ*CYQ)/DCQ
   10 DSAOB=1.0/DSAOB
C DETERMINE MAX AND MIN OF PERSPECTIVE PLANE
	XM1=1.E30
	YM1=XM1
	XMX1=-XM1
	YMX1=XMX1
      X=XMIN
      DO 40 I=1,2
      Y=YMIN
      DO 30 J=1,2
      Z=ZMIN
      DO 20 K=1,2
      CALL TRANSF(X,Y,Z,XX,YY)
      IF(XX.LT.XM1) XM1=XX
      IF(XMX1.LT.XX) XMX1=XX
      IF(YY.LT.YM1) YM1=YY
      IF(YMX1.LT.YY) YMX1=YY
      Z=ZMAX
   20 CONTINUE
      Y=YMAX
   30 CONTINUE
      X=XMAX
   40 CONTINUE
      CALL SIZE(WIDTH,HEIGHT)
C      SCAL=(WIDTH-1.0)/(XMX1-XM1)
C THE SCALE FACTORS ARE CHOSEN TO BE THE SAME.
C      SCAL1=(HEIGHT-1.0)/(YMX1-YM1)
C      IF(SCAL1.LT.SCAL) SCAL=SCAL1
C      CALL SCALE(SCAL,SCAL,0.50,0.50,XM1,YM1)
	XF=XLEN/(XMX1-XM1)
	YF=YLEN/(YMX1-YM1)
	IF(YF.LT.XF)XF=YF
	CALL SCALE(XF,XF,XORG,YORG,XM1,YM1)
C DRAW LABEL FOR PLOT
C DETERMINE DLTAX AND DLTAY
      DLTAX=(XMAX-XMIN)/(M-1)
      DLTAY=(YMAX-YMIN)/(N-1)
      DLTAXI=1.0/DLTAX
      DLTAYI=1.0/DLTAY
C DO LINES PARALLEL TO X-AXIS FIRST
      DLTAX1=DLTAX
	DLTAX2=0.
	DLTAY1=DLTAX2
      DLTAY2=DLTAY
C DO HORIZONTAL AND THEN VERTICAL LINES
      M1=M-1
      N1=N
      IDXINC=M
	IDXINT=1
	INC=IDXINT
	IDX=INC
      DO 90 I=1,2
	XXM=XMIN
	X=XXM
	YYM=YMIN
	Y=YYM
C LOOP THROUGH OUTER LOOP
C MOVE TO THE FIRST POINT OF EACH LINE WITH THE PEN UP.
      DO 80 J=1,N1
      Z=F(IDX)
	IF(ZLE.AND.(Z.LE.CMZLE).OR.
     *	   ZEQ.AND.(Z.EQ.CMZEQ).OR.
     *	   ZGE.AND.(Z.GE.CMZGE))THEN
	    SKIP=.TRUE.
	ELSE
	    SKIP=.FALSE.
	    CALL HIDE(X,Y,Z,PHI,F)
	    CALL TRANSF(X,Y,Z,XX,YY)
	    CALL PLOT(XX,YY,0,0)
	ENDIF
C LOOP THROUGH INNER LOOP
      DO 70 K=1,M1
	IF ( interrupted ) RETURN		! TMAP interrupt
      PHIO=PHI
      ZOLD=Z
      X=X+DLTAX1
      Y=Y+DLTAY1
      IDX=IDX+INC
      Z=F(IDX)
	IF(ZLE.AND.(Z.LE.CMZLE).OR.
     *	   ZEQ.AND.(Z.EQ.CMZEQ).OR.
     *	   ZGE.AND.(Z.GE.CMZGE))THEN
	    SKIP=.TRUE.
	ELSE
	    IF(SKIP)THEN
C
C	MOVE WITH PEN UP
C
		SKIP=.FALSE.
		CALL HIDE(X,Y,Z,PHI,F)
		CALL TRANSF(X,Y,Z,XX,YY)
		CALL PLOT(XX,YY,0,0)
	    ELSE
		CALL MOVES(X,Y,Z,ZOLD,PHIO,PHI,F)
	    ENDIF
	ENDIF
   70 CONTINUE
	XXM=XXM+DLTAX2
	X=XXM
	YYM=YYM+DLTAY2
	Y=YYM
	IDXINT=IDXINT+IDXINC
	IDX=IDXINT
   80 CONTINUE
	DLTAY2=0.
	DLTAX1=DLTAY2
      DLTAY1=DLTAY
      DLTAX2=DLTAX
C SET UP FOR MOVING IN OTHER DIRECTION
      M1=N-1
      N1=M
	IDXINC=1
	IDXINT=IDXINC
	IDX=IDXINT
      INC=M
   90 CONTINUE
C DRAW BASE
	DLTAX2=DLTAX
	DLTAX1=DLTAX2
      DLTAY1=0.
      DLTAY2=DLTAY
      X=XMIN
      Y=YMIN
      Z=ZMIN
      CALL HIDE(X,Y,Z,PHI,F)
      CALL TRANSF(X,Y,Z,XX,YY)
      CALL PLOT(XX,YY,0,0)
C MOVE PEN TO XMIN,YMIN,ZMIN AND BEGIN
      M1=MM-1
      IDX=M
      TEMP=N*M
      DO 100 K=1,2
      DO 110 I=1,2
      DO 120 J=1,M1
      PHIO=PHI
      X=X+DLTAX1
      Y=Y+DLTAY1
      CALL MOVES(X,Y,Z,Z,PHIO,PHI,F)
120   CONTINUE
C DRAW VERT SEGMENT OF THE BASE
      PHIO=PHI
      ZOLD=Z
      Z=F(IDX)
	IF(ZLE.AND.(Z.LE.CMZLE).OR.
     *	   ZEQ.AND.(Z.EQ.CMZEQ).OR.
     *	   ZGE.AND.(Z.GE.CMZGE))Z=(ZMAX+ZMIN)*0.5
	DLTAY1=0.
	DLTAX1=DLTAY1
      CALL TRANSF(X,Y,ZOLD,XX,YY)
C MOVE PEN TO CORNER
      CALL PLOT(XX,YY,0,0)
C PLOT LINE
      CALL MOVES(X,Y,Z,ZOLD,PHIO,PHI,F)
C MOVE PEN BACK
      CALL PLOT(XX,YY,0,0)
C SET NEW VALUES
      PHI=PHIO
      DLTAX1=0.
      DLTAY1=DLTAY2
      M1=N-1
      IDX=TEMP
      Z=ZMIN
110   CONTINUE
	DLTAX1=-DLTAX
	DLTAX2=DLTAX1
      DLTAY2=-DLTAY
      DLTAY1=0.
      IDX=1+(N-1)*M
      TEMP=1
      M1=MM-1
100   CONTINUE
      RETURN
C**  THIS PROGRAM VALID ON FTN4 AND FTN5 **
      END
C*F45V1P0*
      SUBROUTINE MOVES(X,Y,Z,ZOLD,PHIO,PHI,F)
      DIMENSION F(1)

* Mod to specify external references for SCALE and RANGE * Linux *jd* 12.96
	external scale, size


C MOVES PEN TO NEW POINT ( X,Y,Z )
C SEE IF THE POINT IS HIDDEN
      CALL HIDE(X,Y,Z,PHI,F)
C TEST IF BOTH VIEWABLE OR NOT
      IF(PHI.EQ.PHIO) GO TO 60
C TEST FOR ONE VIEWABLE FROM TOP AND ONE FROM BOTTOM
      IF(ABS(PHI).EQ.ABS(PHIO)) GO TO 50
C O.K. ONE IS HIDEN AND OTHER NOT. FIND LEFT HAND
C INTERCEPT.
      CALL INTCEP(X,Y,Z,Z-ZOLD,F,X1,Y1,Z1,PHIO,-1.0)
      CALL TRANSF(X1,Y1,Z1,XX,YY)
      IPEN=ABS(PHIO)
      CALL PLOT(XX,YY,IPEN,0)
      GO TO 60
C WE HAVE HIDDEN PART IN MIDDLE--VIEWABLE FROM TOP
C ON ONE SIDE AND VIEWABLE FROM BOTTOM ON OTHER END
   50 CALL INTCEP(X,Y,Z,Z-ZOLD,F,X1,Y1,Z1,PHIO,-1.0)
      CALL TRANSF(X1,Y1,Z1,XX,YY)
      CALL PLOT(XX,YY,1,0)
C FIND RIGHT HAND INTERCEPT
      CALL INTCEP(X,Y,Z,Z-ZOLD,F,X1,Y1,Z1,PHI,1.0)
      CALL TRANSF(X1,Y1,Z1,XX,YY)
      CALL PLOT(XX,YY,0,0)
C MOVE TO POINT
   60 IF(PHI.EQ.0.0) GO TO 70
      CALL TRANSF(X,Y,Z,XX,YY)
      CALL PLOT(XX,YY,1,0)
70    RETURN
C**  THIS PROGRAM VALID ON FTN4 AND FTN5 **
      END
C*F45V1P0*
      SUBROUTINE HIDE(X,Y,Z,PHI,F)
C HIDE TESTS TO SEE IF THE POINT (XB,YB,ZB) IS HIDDEN
C FROM VIEW OF (CX,CY,CZ).  THIS IS DONE BY TRAVETSING
C THE LINE FROM (XB,YB,ZB) TO (CX,CY,CZ) TO SEE IF THE
C LINE INTERSECTS THE SURFCE.
C
C THE CALLING PARAMETERS ARE:
C  X   - THE X VALUE OF THE POINT
C  Y   - THE Y VALUE OF THE POINT
C  Z   - THE Z VALUE OF THE POINT
C  PHI - VARIABLE WITH THE FOLLOWING VALUES UPON RETURN
C         0 IF THE POINT IS HIDDEN
C        -1 IF THE POINT IS VIEWABLE FROM BELOW
C         1 IF THE POINT IS VIEWABLE FROM ABOVE
C  F   - THE ARRAY OF VALUES.
      DIMENSION F(1)
#ifdef unix
	include 'miss_inc.decl'
	include 'MISS.INC'
#else
	INCLUDE 'TMAP_PPLV11INC:MISS_INC.DECL'
	INCLUDE 'PPLV11INC:MISS.INC'
#endif
      COMMON/LAB1/CX,CY,CZ,QX,QY,QZ,DCQ,CALPHA,CBETA,CGAMMA,
     1DSAOB,IFLG,XTEST,YTEST,ZTEST,DLTAX1,DLTAY1,DLTAX,DLTAY
     2,ZMIN,ZMAX,XMIN,YMIN,DLTAXI,DLTAYI,M,N
      DIMENSION CVIEW(3),VLTEST(3),POINT(3),CVPDST(3),DIST(3)
      DIMENSION TEST(3)
      EQUIVALENCE (CX,CVIEW(1)),(XB,POINT(1)),(YB,POINT(2)),
     1(ZB,POINT(3)),(XDIST,DIST(1)),(YDIST,DIST(2)),(ZDIST,
     2DIST(3)),(CXXB,CVPDST(1)),(CYYB,CVPDST(2)),(CZZB,
     3CVPDST(3)),(XTEST,TEST(1))

* Mod to specify external references for SCALE and RANGE * Linux *jd* 12.96
	external scale, size

C COMPUTE DX,DY,DZ OF THE LINE OF VIEW
      XB=X
      YB=Y
      ZB=Z
      DO 5 J=1,3
	VLTEST(J)=TEST(J)-POINT(J)
	TEMP=VLTEST(J)
      IF(TEST(J).NE.0.0) TEMP=TEMP/TEST(J)
      IF(ABS(TEMP).LT.1.0E-6) VLTEST(J)=0.0
	CVPDST(J)=CVIEW(J)-POINT(J)
	TEMP=CVPDST(J)
      IF(CVIEW(J).NE.0.0) TEMP=TEMP/CVIEW(J)
      IF(ABS(TEMP).LT.1.0E-6) CVPDST(J)=0.0
    5 CONTINUE
C MUST FIND THE POINT AT WHICH THE LINE OF SIGHT INTERSECTS
C THE CUBE.
      DO 20 J=1,3
      DIST(J)=0.0
      IF(CVPDST(J).EQ.0.0) GO TO 20
      DIST(J)=VLTEST(J)
      RATIO=DIST(J)/CVPDST(J)
      DO 10 I=1,3
      IF(I.EQ.J) GO TO 10
	DIST(I)=RATIO*CVPDST(I)
	TEMP=DIST(I)
      IF(CVPDST(I).NE.0.0) TEMP=TEMP/CVPDST(I)
      IF(ABS(TEMP).LT.1.0E-6) DIST(I)=0.0
      IF(ABS(VLTEST(I)).LT.ABS(DIST(I))) GO TO 20
   10 CONTINUE
      GO TO 30
   20 CONTINUE
   30 IF(XDIST.EQ.0.0) GO TO 40
C WE ARE NOT VIEWING ALONG LINE PARALLEL TO Y-Z PLANE
	IDX=ABS(XDIST)/DLTAX+1.0
	INUM=IDX
      DX=XDIST/IDX
      DY=YDIST/XDIST*DX
      IF(ABS(DLTAY).LT.ABS(DY)) GO TO 50
      GO TO 60
C SEE IF ABOVE POINT
   40 IF(YDIST.NE.0.0) GO TO 50
C WE ARE RIGHT ABOVE OR BELOW POINT
      PHI=SIGN(1.,CZZB)
      RETURN
50	IDY=ABS(YDIST)/DLTAY+1.0
	INUM=IDY
      DY=YDIST/IDY
      DX=XDIST/YDIST*DY
C STEP ALONG THE LINE OF SIGHT IN HALF STEPS.
   60 DX=DX*0.5
      DY=DY*0.5
      INUM=INUM+INUM
      DZ=ZDIST*SQRT((DX*DX+DY*DY)/(XDIST*XDIST+YDIST*YDIST))
      XB=XB+DX
      YB=YB+DY
      ZB=ZB+DZ
C COMPUTE THE INDICES OF THE GRID POINTS CONTAINING THE POINT.
	FI=(XB-XMIN)*DLTAXI+1.0
	I=FI
	FJ=(YB-YMIN)*DLTAYI+1.0
	J=FJ
      I1=FI+0.995
      J1=FJ+0.995
C MAKE SURE THE INDICES DON"T GET TOO LARGE.
      IF(I1.GT.M) I1=M
      IF(J1.GT.N) J1=N
C COMPUTE THE LINEAR ARRAY INDICES.
      MI=(J-1)*M
      MI1=(J1-1)*M
      IDX=MI+I
      IDX1=MI+I1
      IDX2=MI1+I
      IDX3=MI1+I1
C USE A TWO STAGE LINEAR INTERPOLATION.
      XFACT=(XB-(XMIN+(I-1)*DLTAX))*DLTAXI
C
C**	ADD TEST FOR DATA TO BE IGNORED IN THE HIDE ALGORITHM
C
C	IF(ZLE.AND.(F(IDX).LE.CMZLE).OR.
C     *	   ZEQ.AND.(F(IDX).EQ.CMZEQ).OR.
C     *	   ZGE.AND.(F(IDX).GE.CMZGE))GOTO
C	IF(ZLE.AND.(F(IDX1).LE.CMZLE).OR.
C     *	   ZEQ.AND.(F(IDX1).EQ.CMZEQ).OR.
C     *	   ZGE.AND.(F(IDX1).GE.CMZGE))GOTO
C	IF(ZLE.AND.(F(IDX2).LE.CMZLE).OR.
C     *	   ZEQ.AND.(F(IDX2).EQ.CMZEQ).OR.
C     *	   ZGE.AND.(F(IDX2).GE.CMZGE))GOTO
C	IF(ZLE.AND.(F(IDX3).LE.CMZLE).OR.
C     *	   ZEQ.AND.(F(IDX3).EQ.CMZEQ).OR.
C     *	   ZGE.AND.(F(IDX3).GE.CMZGE))GOTO
      Z1=F(IDX)+(F(IDX1)-F(IDX))*XFACT
      Z2=F(IDX2)+(F(IDX3)-F(IDX2))*XFACT
      ZZ=Z1+(Z2-Z1)*(YB-(YMIN+(J-1)*DLTAY))*DLTAYI
C TEST THE FIRST DIFFERENCE TO MAKE SURE
C WE AREN"T JUST ON THE BOUNDARY.  IF SO WE WANT THE POINT TO BE VIEWABL
C BUT WITH THE SAME PHI VALUE AS THE LAST POINT I.E. + OR - 1.  BUT IF
C THE LAST POINT WAS HIDDEN WE WANT THE CURRENT POINT VIEWABLE, SO THE
C SIGN OF THE LAST PHI IS USED.  THIS CASE ONLY OCCURS WHEN
C WE ARE ON THE BOUNDARY CLOSEST TO THE VIEWING POINT.
      ARG=ZB-ZZ
      IF(ARG.EQ.0.0) GO TO 90
	PHIOLD=SIGN(1.,ARG)
	PHI=PHIOLD
C COMPUTE THE INDICES INCREMENT.
      DFI=DX*DLTAXI
      DFJ=DY*DLTAYI
      DO 70 K=2,INUM
C MOVE ALONG THE LINE OF SIGHT.
      XB=XB+DX
      YB=YB+DY
      ZB=ZB+DZ
C INCREMENT THE INDICES.
      FI=FI+DFI
      FJ=FJ+DFJ
C COMPUTE THE INDICES OF THE GRID ABOUT THE POINT.
      I=FI+0.005
      J=FJ+0.005
      I1=FI+0.995
      J1=FJ+0.995
C MAKE SURE THE INDICES DON"T GET TOO LARGE.
      IF(I1.GT.M) I1=M
      IF(J1.GT.N) J1=N
C COMPUTE THE LINEAR ARRAY INDICES
      MI=(J-1)*M
      MI1=(J1-1)*M
      IDX=MI+I
      IDX1=MI+I1
      IDX2=MI1+I
      IDX3=MI1+I1
C USE A TWO STAGE INTERPOLATION.
      XFACT=(XB-(XMIN+(I-1)*DLTAX))*DLTAXI
C
C**	ADD TEST FOR DATA TO BE IGNORED IN THE HIDE ALGORITHM
C
	IF(ZLE.AND.(F(IDX).LE.CMZLE).OR.
     *	   ZEQ.AND.(F(IDX).EQ.CMZEQ).OR.
     *	   ZGE.AND.(F(IDX).GE.CMZGE))GOTO 70
	IF(ZLE.AND.(F(IDX1).LE.CMZLE).OR.
     *	   ZEQ.AND.(F(IDX1).EQ.CMZEQ).OR.
     *	   ZGE.AND.(F(IDX1).GE.CMZGE))GOTO 70
	IF(ZLE.AND.(F(IDX2).LE.CMZLE).OR.
     *	   ZEQ.AND.(F(IDX2).EQ.CMZEQ).OR.
     *	   ZGE.AND.(F(IDX2).GE.CMZGE))GOTO 70
	IF(ZLE.AND.(F(IDX3).LE.CMZLE).OR.
     *	   ZEQ.AND.(F(IDX3).EQ.CMZEQ).OR.
     *	   ZGE.AND.(F(IDX3).GE.CMZGE))GOTO 70
      Z1=F(IDX)+(F(IDX1)-F(IDX))*XFACT
      Z2=F(IDX2)+(F(IDX3)-F(IDX2))*XFACT
      ZZ=Z1+(Z2-Z1)*(YB-(YMIN+(J-1)*DLTAY))*DLTAYI
      PHI=SIGN(1.,ZB-ZZ)
C TEST THE VIEWABLILITY OF THE POINT, IF THE PHI"S ARE DIFFERENT
C THE POINT IS NOT VIEWABLE.
      IF(PHI.NE.PHIOLD) GO TO 80
   70 CONTINUE
      RETURN
C THE POINT IS NOT VIEWABLE
   80 PHI=0.0
      RETURN
   90 PHI=SIGN(1.,PHIOLD)
      RETURN
C**  THIS PROGRAM VALID ON FTN4 AND FTN5 **
      END
C*F45V1P0*
      SUBROUTINE INTCEP(X,Y,Z,DLTAZ,F,X1,Y1,Z1,PHI,DIR)
C INTERCEPT COMPUTES THE INTERCEPT OF THE LINES OF
C SIGHT WITH THE FIRST VIEWABLE POINT ALONG THE LINE
C CONNECTING THE POINTS.  THE CALLING PARAMETERS ARE
C
C  X   - THE X VALUE OF NEXT POINT
C  Y   - THE Y VALUE OF NEXT POINT
C  F   - THE FUNCTION NAME
C  Z   - THE Z VALUE OF NEXT POINT
C  DLTAZ - THE DIFFERENCE IN THE TWO Z VALUES ALONG LINE OF
C      - INTERPOLATION.
C  X1  - THE X COORDINATE OF THE INTERCEPT POINT
C  Y1  - THE Y COORDINATE OF THE INTERCEPT POINT
C  Z1  - THE Z COORDINATE OF THE INTERCEPT POINT
C  PHI - THE VIEWABLE VALUE WE WISH THE INTERCEPT
C        POINT TO HAVE
C  DIR - THIS VARIABLE WILL HAVE THE VALUE -1.0 IF
C        PHI IS FROM LAST POINT AND 1.0 IF NEXT.
      DIMENSION F(1)
      COMMON/LAB1/CX,CY,CZ,QX,QY,QZ,DCQ,CALPHA,CBETA,CGAMMA,
     1DSAOB,IFLG,XTEST,YTEST,ZTEST,DLTAX1,DLTAY1,DLTAX,DLTAY
     2,ZMIN,ZMAX,XMIN,YMIN,DLTAXI,DLTAYI,M,N
      DELX=DLTAX1*0.5
      DELY=DLTAY1*0.5
      DELZ=DLTAZ*0.5
      X1=X-DELX
      Y1=Y-DELY
      Z1=Z-DELZ
      DO 20 I=1,5
      DELX=DELX*0.5
      DELY=DELY*0.5
      DELZ=DELZ*0.5
      CALL HIDE(X1,Y1,Z1,PHIN,F)
      IF(PHIN.EQ.PHI) GO TO 10
C MOVE IN DIRECTION OF PHI
      X1=X1+DIR*DELX
      Y1=Y1+DIR*DELY
      Z1=Z1+DIR*DELZ
      GO TO 20
C MOVE AWAY FROM PHI
   10 X1=X1-DIR*DELX
      Y1=Y1-DIR*DELY
      Z1=Z1-DIR*DELZ
   20 CONTINUE
      RETURN
C**  THIS PROGRAM VALID ON FTN4 AND FTN5 **
      END
C*F45V1P0*
      SUBROUTINE TRANSF(X,Y,Z,XX,YY)
C THE ROUTINE TRANSF TRANSFORMS THE (X,Y,Z) TRIPLE INTO (X,Y) PAIR IN
C THE VIEWING PLANE.  THE CALLING ARGUMENTS ARE:
C  X  - THE X COORDINATE OF THE TRIPLE
C  Y  - THE Y COORDINATE OF THE TRIPLE
C  Z  - THE Z COORDINATE OF THE TRIPLE
C  XX - THE X COORDINATE OF THE VIEWING PLANE POINT.
C  YY - THE Y COORDINATE OF THE VIEWING PLANE POINT.
      COMMON/LAB1/CX,CY,CZ,QX,QY,QZ,DCQ,CALPHA,CBETA,CGAMMA,DSAOB,IFLG
     1,XTEST,YTEST,ZTEST,DLTAX1,DLTAY1,DLTAX,DLTAY
     2,ZMIN,ZMAX,XMIN,YMIN,DLTAXI,DLTAYI,M,N

* Mod to specify external references for SCALE and RANGE * Linux *jd* 12.96
	external scale, size


 


      CXX=X-CX
      CYY=Y-CY
      CZZ=Z-CZ
      RK=DCQ/(CXX*CALPHA+CYY*CBETA+CZZ*CGAMMA)
      IF(IFLG.EQ.2) GO TO 10
      XX=((CX+RK*CXX-QX)*CBETA-(CY+RK*CYY-QY)*CALPHA)*DSAOB
      YY=(CZ+RK*CZZ-QZ)*DSAOB
      RETURN
   10 XX=((QX-CX-RK*CXX)*CGAMMA+(CZ+RK*CZZ-QZ)*CALPHA)*DSAOB
      YY=(CY+RK*CYY-QY)*DSAOB
      RETURN
C**  THIS PROGRAM VALID ON FTN4 AND FTN5 **
      END
