!++
!
! ---------------------- DEMO OF GPLOT SURFACE ROUTINES -----------------------
!
! FUNCTIONAL DESCRIPTION
!   
!    This program constructs a 2-dimensional array of values and then uses 
!    the GPlot surface routines to produce views of the three-D surface 
!    represented by those values.
!
!-----------------------------------------------------------------------------
!
! DECLARATION SECTION
!
!
      PARAMETER Nx = 41        ! Number of data values in x direction (#rows)
      PARAMETER Ny = 51        ! Number of data values in y direction (#columns)

      PARAMETER xRange =  3.0  ! x Varies between -xRange and +xRange
      PARAMETER yRange =  4.0  ! y Varies between -yRange and +yRange
      PARAMETER zRange = 20.0  ! z Varies between -zRange and +zRange

      DIMENSION DataArray(Nx,Ny)              ! The array of values to contour
!
!  First construct the array of data values determining the surface.
!
      call BuildArray( DataArray, nx, ny, xRange, yRange )
!
!  Now start up GPlot and select the desired output device
!  
	CALL ORIENT('PORTRAIT')
      call gstart
!
!  Set up the page and surface display area, together with a frame and heading
!
C      call page(11.0,8.5)
C      call area2d(9.0,6.5)
	CALL PAGE(8.5,11.0)
	CALL PHYSOR(1.0,0.2)
	CALL AREA2D(6.5,4.0)
      call headin('GPLOT Example 14A, 3D Surface$', 100, 1.5, 2)
      call headin('VUABS(10.0,9.0,8.0)$', 100, 1.5, 2)
      call frame
!
!  Set up a three dimensional work box into which the surface is to be plotted.
!  The work box is specified in "Absolute Coordinates" and will range from 
!  0 to 5 in the x direction, 0 to 5 in the y direction, and 0 to 3 in the z 
!  direction.  These values are specified in the call to Axes3d.  The axes 
!  will be also be labeled with the character strings passed in to Axes3D.
!
      call Axes3d( 'X AXIS$',100,'Y AXIS$',100,'Z AXIS$',100,
     :                5.0, 5.0, 3.0 )
!
!  Next specify the observers position in "Absolute Coordinates".
!  NOTE: VuAbs must be called BEFORE Graf3D
!
      Vx = 10.0
      Vy =  9.0
      Vz =  8.0

      call VuAbs( Vx,Vy,Vz)
!
!  The next call to Graf3D provides a "Relative Coordinate" system for the
!  workbox.  The values passed in to Graf3D provide the range for the numeric
!  scales along the x, y and z axes.
! 
      call Graf3D( -xRange, 'SCALE', xRange, 
     :             -xRange, 'SCALE', yRange, 
     :             -zRange, 'SCALE', zRange )
!
!  Now Display the surface using a call to SurMat.  The paramters to SurMat
!  are:
!      DataArray  --  The array of z values to graph.
!      IxPts      --  If some of the data values are to be omitted in the
!                     x direction, this value is > 1.  That is, if only every
!                     third row of the array was to be used, IxPts would be
!                     set to 3.
!      nx         --  The number of rows in DataArray
!      IyPts      --  If some of the data values are to be omitted in the
!                     y direction, this value is > 1.  That is, if only 
!                     odd numbered columns of the array were to be used, IyPts 
!                     would be set to 2.
!      ny         --  The number of columns in DataArray
!
        call SurMat( DataArray, 1, nx, 1, ny, 0 )
!
!  Now end the current plot
!
C        call endpl(0)
	CALL ENDGR(0)
!
!  Next repeat the process from a different viewpoint, using some of the axis
!  attributes.
!
      CALL xIntAx
      CALL zIntAx                    ! Integer valued labels on x, z

      CALL XTICKS( 3 )               ! Intermediate tick marks on x, y
      CALL YTICKS( 2 )

      CALL xRevTk
      CALL zRevTk                    ! Reversed tick marks on x, z

      CALL xAxEnd('NOENDS')          ! Suppressed end labels on x, y and z
      CALL yAxEnd('NOLAST')
      CALL zAxEnd('NOFIRST')

      CALL yaxang( 90.0)             ! Angled labels on y and z
      CALL zaxang(-90.0)
!
! Now construct the surface again from a different viewpoint
!
C      call page(11.0,8.5)
C      call area2d(9.0,6.5)
	CALL OREL(0.0,5.3)
	CALL AREA2D(6.5,4.0)
      call headin('GPLOT Example 14B, 3D Surface$', 100, 1.5, 2)
      call headin('VUABS(-10.0,-8.0,3.0)$', 100, 1.5, 2)
      call frame
      call Axes3d( 'X AXIS$',100,'Y AXIS$',100,'Z AXIS$',100,
     :                5.0, 5.0, 3.0 )
      Vx = -10.0
      Vy =  -8.0
      Vz =   3.0
 
      call VuAbs( Vx,Vy,Vz)
      call Graf3D( -xRange, 'SCALE', xRange, 
     :             -xRange, 'SCALE', yRange, 
     :             -zRange, 'SCALE', zRange )
      call SurMat( DataArray, 1, nx, 1, ny, 0 )
      call endpl(0)
!
!  Shut down GPlot
!
      call GSTOP
      end


!++
!
! -------------------------- SUBROUTINE BuildArray ---------------------------
!
!  FUNCTIONAL DESCRIPTION
!
!    This routine constructs a sample data set for use with contouring and 
!    surface routines.
!
!  FORMAL ARGUMENTS
!
!    DataArray       OUTPUT     Real Array(Nx,Ny) that will contain the sample
!                               data set.
!
!    Nx, Ny          INPUT      The dimensions of DataArray
!
!    xRange,         INPUT      Range of x and y values to be used when 
!    yRange                     fabricating the sample data set.
!
!  IMPLICIT INPUTS
!
!    NONE
!
!  IMPLICIT OUTPUTS
!
!    NONE
!
!  SIDE EFFECTS
!
!    NONE
!
!--
      SUBROUTINE BuildArray( DataArray, Nx, Ny, xRange, yRange )
      REAL DataArray( Nx, Ny )
      xstep = 2.0 * xRange/(Nx-1)
      ystep = 2.0 * yRange/(Ny-1)
      xi = -xRange
      do 10 i = 1,Nx
        yj = -yRange
        do 5 j = 1,Ny
          temp1 = max(xi+yj-2 , .2)
          temp2 = max( (xi+3.)**2 + (yj+2.)**2, .2)
          DataArray(i,j) = xi**2 - yj**2 + 1./temp1 + 1./temp2
          yj = yj + ystep
5       continue
        xi = xi + xstep
10    continue

!
!  Now put in a "peak"
!
      iPeak = Nx/3 + 1
      jPeak = Ny/5 + 1

      DataArray( iPeak-1 , jPeak-1 ) =  4.0
      DataArray( iPeak-1 , jPeak   ) =  6.0
      DataArray( iPeak-1 , jPeak+1 ) =  4.0
      DataArray( iPeak   , jPeak-1 ) =  6.0
      DataArray( iPeak   , jPeak   ) = 10.0
      DataArray( iPeak   , jPeak+1 ) =  6.0
      DataArray( iPeak+1 , jPeak-1 ) =  4.0
      DataArray( iPeak+1 , jPeak   ) =  6.0
      DataArray( iPeak+1 , jPeak+1 ) =  4.0

      END
