                   Chapter 12: 3-D Graphics

This chapter describes routines for  3-D coordinate systems.
Axis systems, curves and surfaces  can be drawn from various
angular perspectives.  All 2-D plotting routines can be used
in a 3-D axis system.

12.1 Introduction

Three-dimensional objects must be plotted in a 3-D box which
is projected onto a two-dimensional region on the page.  The
3-D box contains an X-,  Y- and Z-axis with the Z-axis lying
in the vertical direction.  The units of the axes are called
absolute 3-D coordinates. They are abstract and have  no re-
lation  to any  physical units.  An axis system  is used  to
scale the  3-D box  with user coordinates  and to plot  axis
ticks, labels and names.

The position  and size of a  projected 3-D box  depends upon
the position  and size  of the region onto which  the box is
projected,  and the point from which the box is viewed.  The
region is determined by the routines AXSPOS and AXSLEN where
the centre of the 3-D box will be projected onto  the centre
of the region. The box itself will be cut off at the borders
of the region unless suppressed with the routine NOCLIP.

                         A X I S 3 D

The routine  AXIS3D defines the lengths of the 3-D box.  For
the lengths,  any positive values  can be specified;  DISLIN
uses only  the ratio  of the  values  to calculate  the axis
lengths.

The call is:  CALL AXIS3D (X3AXIS, Y3AXIS, Z3AXIS)
                                               level 1, 2, 3

X3AXIS        is the length  of the  X-axis  in absolute 3-D
              coordinates (> 0).
Y3AXIS        is the length  of the  Y-axis  in absolute 3-D
              coordinates (> 0).
Z3AXIS        is the length  of the  Z-axis  in absolute 3-D
              coordinates (> 0).
                                       Default: (2., 2., 2.)

Note:         The lower  left corner  of the  3-D box is the
              point   (-X3AXIS/2, -Y3AXIS/2, -Z3AXIS/2);
              the upper right corner is the point
                      (X3AXIS/2 ,  Y3AXIS/2,  Z3AXIS/2).
              The centre point is (0., 0., 0.).

12.2 Defining View Properties

The following routines  define view properties such as view-
point, target point, view angle and view orientation.

                         V I E W 3 D

The routine VIEW3D defines the viewpoint. The viewpoint is a
point in space from which the 3-D box is observed and deter-
mines  how objects  are projected  onto a 2-D plane. Objects
will appear small if the viewpoint is far away. As the view-
point is moved closer  to the 3-D box,  the objects will ap-
pear larger.

The call is:  CALL VIEW3D (XVU, YVU, ZVU, CVU) level 1, 2, 3

XVU, YVU, ZVU define the position of the viewpoint. If CVU =
              'ABS',  the parameters  must contain  absolute
              3-D coordinates,  if  CVU = 'USER',  they must
              contain user coordinates and if CVU = 'ANGLE',
              the viewpoint  must be specified by two angles
              and a radius. In the latter case, XVU is a ro-
              tation angle,  YVU  is the angle  between  the
              line from  the viewpoint to the  centre of the
              3-D box  and the horizontal direction  and ZVU
              is the distance of the viewpoint from the cen-
              tre of the 3-D box. XVU and YVU must be speci-
              fied in degrees  and ZVU in absolute 3-D coor-
              dinates.
CVU           is a character string  defining the meaning of
              XVU, YVU and ZVU.
              Def: (2*X3AXIS, -2.5*Y3AXIS, 2*Z3AXIS, 'ABS').

Note:         The viewpoint must be placed  outside the  3-D
              box.  If the point  lies inside,  DISLIN  will
              print a warning and use the default viewpoint.

                         V F O C 3 D

The routine VFOC3D defines the focus point. It specifies the
location in the 3-D box that the camera points to.

The call is:  CALL VFOC3D (XFC, YFC, ZFC, CVU) level 1, 2, 3

XFC, YFC, ZFC define the position of the focus point. If CVU
              = 'ABS', the parameters must contain  absolute
              3-D coordinates,  if CVU = 'USER',  they  must
              contain user coordinates.
CVU           is a character string  defining the meaning of
              XFC, YFC and ZFC.
                               Default: (0., 0., 0., 'ABS').

                          V U P 3 D

The rotation  of the camera  around the  viewing axis is de-
fined by an angle.

The call is:  CALL VUP3D (ANG)                 level 1, 2, 3

ANG           defines the rotation angle in degrees. The ca-
              mera is rotated in a clockwise direction.
                                           Default: ANG = 0.

                           V A N G 3 D

VANG3D  defines  the  view angle.  It specifies the field of
view of the lens.

The call is:  CALL VANG3D (ANG)                level 1, 2, 3

ANG           defines the view angle in degrees.
                                          Default: ANG = 28.

12.3 Plotting Axis Systems

                         G R A F 3 D

The routine  GRAF3D  plots a three-dimensional  axis system.
This routine  must be called before any objects can be plot-
ted in the 3-D box.

The call is:  CALL GRAF3D (XA, XE, XOR, XSTEP, YA, YE, YOR,
                                  YSTEP, ZA, ZE, ZOR, ZSTEP)

XA, XE        are the lower and upper limits of the X-axis.
XOR, XSTEP    are the first  X-axis  label  and the step be-
              tween labels.
YA, YE        are the lower and upper limits of the Y-axis.
YOR, YSTEP    are the first  Z-axis  label  and the step be-
              tween labels.
ZA, ZE        are the lower and upper limits of the Z-axis.
ZOR, ZSTEP    are the first  Z-axis  label  and the step be-
              tween labels.

Notes:     -  GRAF3D  must be called  from level 1  and sets
              the level to 3.
           -  To avoid overwriting labels, GRAF3D suppresses
              the plotting of certain start labels. This op-
              tion  can be disabled  with the statement CALL
              FLAB3D.
           -  The user is referred  to the notes on  GRAF in
              chapter 4.

12.4 Plotting a Border around the 3-D Box

                          B O X 3 D

The routine BOX3D plots a border around the 3-D box.

The call is:  CALL BOX3D                             level 3

12.5 Plotting Grids

                         G R I D 3 D

The routine GRID3D plots a grid in the 3-D box.

The call is:  CALL GRID3D (IGRID, JGRID, COPT)       level 3

IGRID         is the number of grid lines between  labels in
              the X-direction  (or  Y-direction  for the YZ-
              plane).
JGRID         is the number of grid lines between  labels in
              the Z-direction  (or  Y-direction  for the XY-
              plane).
COPT          is a character string which defines  where the
              grid will be plotted.
  = 'ALL'     will plot a grid in the XY-, XZ- and YZ-plane.
  = 'BACK'    will plot a grid in the XZ- and YZ-plane.
  = 'BOTTOM'  will plot a grid in the XY-plane.


12.6 Plotting Curves

                         C U R V 3 D

The routine  CURV3D  is similar to  CURVE  and connects data
points with lines or marks them with symbols.

The call is:  CALL CURV3D (XRAY, YRAY, ZRAY, N)      level 3

XRAY          is an  array  containing  the X-coordinates of
              data points.
YRAY          is an  array  containing  the Y-coordinates of
              data points.
ZRAY          is an  array  containing  the Z-coordinates of
              data points.
N             is the number of data points.

Note:         Data points will be interpolated linearly. The
              user  is referred  to the  notes  on  CURVE in
              chapter 5.

12.7 Plotting a Surface Grid from a Function

                         S U R F U N

The routine  SURFUN  plots  a  surface grid  of  the  three-
dimensional function Z = F(X,Y).

The calls is:  CALL SURFUN (ZFUN, IXP, XDEL, IYP, YDEL) 
                                                     level 3

ZFUN            is the name  of a  FUNCTION  subroutine that
                returns the function  value  for a given  X-
                and Y-coordinate.  ZFUN must be declared EX-
                TERNAL in the calling program.
XDEL, YDEL      are the distances between grid lines in user
                coordinates.  XDEL  and YDEL  determine  the
                density of  the surface plotted by SURFUN.
IXP, IYP        are the number  of points between grid lines
                interpolated by  SURFUN (>= 0).  If IXP = 0,
                surface  lines  in the  X-direction  will be
                suppressed; if IYP = 0, surface lines in the
                Y-direction will be suppressed.

12.8 Plotting a Surface Grid from a Matrix

The routines  SURMAT  and SURFCE  plot surface grids  of the
three-dimensional function Z = F(X,Y) where the function va-
lues are given in the form of a matrix.  SURMAT assumes that
the function values  correspond to a linear grid in the  XY-
plane while SURFCE can be used with non linear grids. 

The calls are:  CALL SURMAT (ZMAT, IXDIM, IYDIM, IXP, IYP)
                CALL SURFCE (XRAY, IXDIM, YRAY, IYDIM, ZMAT)
                                                     level 3

XRAY, YRAY      are arrays containing the  X- and Y-user co-
                ordinates.
ZMAT            is a matrix with the dimension (IXDIM,IYDIM)
                containing the function values.
IXDIM, IYDIM    are the  dimensions of  ZMAT,  XRAY and YRAY
                (>= 2).
IXP, IYP        are  the number  of points  interpolated be-
                tween grid lines in the X- and  Y-direction.
                These  parameters  determine  the density of
                surfaces plotted by SURMAT. For positive va-
                lues, the surface will be interpolated line-
                arly. For a negative value, the absolute va-
                lue will be used as a step for  plotted sur-
                face lines. If IXP = 0, surface lines in the
                Y-direction will be suppressed;  if IYP = 0,
                surface  lines  in the  X-direction  will be
                suppressed.

Notes:       -  The suppression  of hidden lines can be dis-
                abled with CALL NOHIDE.
             -  Surfaces can be protected  from  overwriting
                with  CALL SHLSUR  if the  hidden-line algo-
                rithm is not disabled.
             -  The limits  of the base grid  are determined
                by the parameters in  GRAF3D or can be alte-
                red with SURSZE (XA, XE, YA, YE). If XA, XE,
                YA and YE are the axis limits in  GRAF3D  or
                defined with SURSZE,  the connection of grid
                points and matrix elements  can be described
                by the formula:

                ZMAT(I,J) = F(X,Y)  where
                X = XA + (I - 1) * (XE - XA) / (IXDIM - 1),
                                              I = 1,..,IXDIM
                Y = YA + (J - 1) * (YE - YA) / (IYDIM - 1),
                                              J = 1,..,IYDIM

             -  SURVIS (CVIS) determines the visible part of
                a surface  where  CVIS  can have  the values
                'TOP', 'BOTTOM' and 'BOTH'.  The default va-
                lue is 'BOTH'.
             -  The  statement  CALL SURCLR  (ICTOP,  ICBOT)
                defines the colours  of the upper and  lower
                side of a surface. The parameters must be in
                the range  -1 to 255 where the default value
                -1 means that the current colour is used.

12.9 Plotting a Shaded Surface from a Matrix

                          S U R S H D

The routine  SURSHD  plots a  shaded surface  from a  matrix
where colour values are calculated from the Z-scaling in the
routine GRAF3D or from the parameters of the routine ZSCALE.

The call is:    CALL SURSHD (XRAY, IXDIM, YRAY, IYDIM, ZMAT)
                                                     level 3

XRAY, YRAY      are arrays containing the  X- and Y-user co-
                ordinates.
ZMAT            is a matrix with the dimension (IXDIM,IYDIM)
                containing the function values.
IXDIM, IYDIM    are the  dimensions of  ZMAT,  XRAY and YRAY
                (>= 2).

Notes:       -  The statement  CALL ZSCALE  (ZMIN, ZMAX) de-
                fines an alternate  Z-scaling  that  will be
                used to calculate  colour values in  SURSHD.
                Normally, the Z-scaling in GRAF3D is used.
             -  A flat shading or  a smooth shading  can  be
                selected  with  the routine  SHDMOD. The de-
                fault is flat shading.  If smooth shading is
                selected, a Z-buffer is used for hidden-sur-
                face  elimination.  In this case,  a  raster
                format  is needed  for the  graphics  output
                format       (for example METAFL ('XWIN') or
                METAFL ('TIFF')).
              - Additional  grid lines  can be  enabled with
                the routine SURMSH.

12.10 Plotting a Shaded Surface from a Parametric Function

                         S U R F C P

A three-dimensional parametric function is a function of the
form  (x(t,u), y(t,u), z(t,u)) where  tmin <= t <= tmax  and
umin <= u <= umax. The routine SURFCP plots a shaded surface
from a parametric function.  The colours  of the surface are
calculated from the Z-scaling in the routine  GRAF3D or from
the parameters of the routine ZSCALE.

The call is:  CALL SURFCP (ZFUN, TMIN, TMAX, TSTEP, 
                                 UMIN, UMAX, USTEP)  level 3

ZFUN          is the name of a  FUNCTION subroutine with the
              formal parameters  X, Y and IOPT. If IOPT = 1,
              ZFUN  should  return  the  X-coordinate of the
              parametric function,  if IOPT = 2, ZFUN should
              return the Y-coordinate and  if IOPT = 3, ZFUN
              should return the Z-coordinate.
TMIN, TMAX,   define  the  range  and step size of the first
       TSTEP  parameter. 
UMIN, UMAX,   define the  range  and step size of the second
       USTEP  parameter.

Notes:     -  A flat shading or a smooth shading can  be se-
              lected with the routine SHDMOD. The default is
              flat shading.  If smooth shading is  selected,
              a Z-buffer  is used for hidden-surface  elimi-
              nation.  In  this  case,  a  raster  format is
              needed  for the  graphics  output format  (for
              example METAFL ('XWIN') or  METAFL ('TIFF')).
            - Additional  grid lines can be enabled with the
              routine SURMSH.


12.11 Parameter Setting Routines

                         N O H I D E

The suppression of hidden lines in the routines SURFUN, SUR-
MAT and SURFCE can be disabled with a call to NOHIDE.

The call is:  CALL NOHIDE                      level 1, 2, 3 

                         S H L S U R

The  surfaces  plotted by the routines  SURFUN,  SURMAT  and
SURFCE can be protected  from  overwriting  with the routine
SHLSUR.

The call is:  CALL SHLSUR                      level 1, 2, 3

                         S U R V I S

The routine SURVIS determines the visible part of the surfa-
ces plotted by the routines SURFUN, SURMAT and SURFCE.

The call is:  CALL SURVIS (CVIS)               level 1, 2, 3

CVIS          is a character string that can have the values
              'TOP', 'BOTTOM' and 'BOTH'.
                                     Default: CVIS = 'BOTH'.

                          S U R C L R

The routine  SURCLR  defines  the  colours  of the upper and 
lower side of surfaces plotted by the routines SURFUN,  SUR-
MAT and SURFCE.

The call is:  CALL SURCLR (ICTOP, ICBOT)       level 1, 2, 3

ICTOP, ICBOT  are the colour values  in the range  -1 to 255
              where the value -1 means that the current  co-
              lour is used.
                                          Default: (-1, -1).

                          S H D M O D

The routine  SHDMOD  defines flat  or smooth shading for the
routine SURSHD. If smooth shading is selected, DISLIN uses a
Z-buffer for hidden-surface elimination. This means that the
graphics output format must be set to a raster format   (for
example: METAFL ('XWIN') or METAFL ('TIFF').

The call is:  CALL SHDMOD (COPT, 'SURFACE')    level 1, 2, 3

COPT          is a character string that can have the values
              'FLAT' and 'SMOOTH'.
                                     Default: COPT = 'FLAT'.

                          S U R M S H

The routine  SURMSH can enable additional grid lines for the
routines SURSHD and SURFCP.

The call is:  CALL SURMSH (COPT)               level 1, 2, 3

COPT          is a character string that can have the values
              'ON' and 'OFF'.
                                      Default: COPT = 'OFF'.

                        Z S C A L E

The routine  ZSCALE defines an alternate Z-scaling that will
be used to calculate colour  values  in the routines  SURSHD
and SURFCP.

The call is:  CALL ZSCALE (ZMIN, ZMAX)         level 1, 2, 3

ZMIN,ZMAX     define  the range  of the Z-scaling. For loga-
              rithmic scaling of the Z-axis,  ZMIN  and ZMAX
              must be exponents of base 10.

                           C L I P 3 D

The routine CLIP3D defines 3-D clipping in the world coordi-
nate system or in the eye coordinate system.

The call is:  CALL CLIP3D (COPT)               level 1, 2, 3

COPT          is a character string that can have the values
              'WORLD' and 'EYE'.
                                    Default: COPT = 'WORLD'.

                           V C L P 3 D

If 3-D clipping is done in the eye coordinate system,  front
and back  clipping  planes can be defined  with  the routine
VCLP3D.

The call is:   CALL VCLP3D (XFRONT, XBACK)     level 1, 2, 3

XFRONT, XBACK  are  the distances  from the viewpoint in ab-
               solute  3-D  coordinates.  A  negative  value
               means infinity.
                                         Default: (1., -1.).

12.12 Surfaces from Randomly Distributed Points

The routine SURMAT assumes that  function values  are in the
form of a matrix  and  correspond  to a  linear grid  in the
XY-plane. If three-dimensional data points are given as ran-
domly distributed points of the form  X(N),  Y(N) and  Z(N),
the routine  GETMAT  can be used to calculate a function ma-
trix.

                         G E T M A T

The routine GETMAT calculates a function matrix for randomly
distributed data points.

The call is:  CALL GETMAT (XRAY, YRAY, ZRAY, N, ZMAT, NX,
                           NY, ZVAL, IMAT, WMAT)  level 2, 3

XRAY, YRAY,   are arrays containing the randomly distributed
   ZRAY       data points.
N             is the number of points.
ZMAT          is the function matrix  of the dimension  (NX,
              NY) calculated by GETMAT.  The matrix elements
              correspond to a linear  grid in  the  XY-plane
              whose limits are determined by the scaling va-
              lues in GRAF3D or SURSZE.
NX, NY        are the dimensions of ZMAT, IMAT and WMAT.
ZVAL          will be used  as a value  for matrix  elements
              when no data points  can be  found in  an area
              around the corresponding grid points. In gene-
              ral, the start scaling of the  Z-axis  will be
              used for ZVAL.
IMAT          is a  working matrix of the dimension (NX,NY).
              After a call to  GETMAT,  IMAT(I, J)  contains
              the number of random  data points  found in an
              area  around  the grid points.  The  value  -1
              means that a random data value lies  at a grid
              point.
WMAT          is a working matrix of the dimension (NX, NY).

If Pi is a data point,  the routine  GETMAT  finds  the grid
rectangle in the  XY-plane  in which the point lies.  By de-
fault,  Pi affects  all grid points  which lie up  to 2 grid
lines from Pi.  A problem can arise  when  creating a  large
matrix from sparse data points  because certain  grid points
may not lie near the actual random data points.

An simple method to smooth surfaces  from sparse data points
is to  enlarge  the region  around the randomly  distributed
data points where grid points are searched. This can be done
using the routine MDFMAT.

                         M D F M A T

The routine MDFMAT modifies the algorithm in GETMAT.

The call is:  CALL MDFMAT (IX, IY, W)          level 1, 2, 3

IX, IY        are the number of grid lines in the X- and  Y-
              direction which determine the size  of the re-
              gion around data points.
W             is a weighting number.
                                       Default: (2, 2, 2.0).

12.13 Projection of 2-D-Graphics into 3-D Space

Two-dimensional  graphics  in the  XY-plane can be projected
onto a plane in 3-D space.  Therefore, all 2-D plot routines
can be used in 3-D space.

                         G R F I N I

The routine GRFINI defines a plane in the 3-D box onto which
all plot vectors will be projected. The plane in the 3-D box
corresponds to a region in the  XY-plane which is determined
by AXSPOS and AXSLEN. GRFINI sets the level to 1.

The call is:  CALL GRFINI (X1, Y1, Z1, X2, Y2, Z2,
                                       X3, Y3, Z3)   level 3

X1, Y1, Z1    are the absolute 3-D coordinates  of the lower
              left corner of the 3-D plane.
X2, Y2, Z2    are the absolute 3-D coordinates  of the lower
              right corner of the 3-D plane.
X3, Y3, Z3    are the absolute 3-D coordinates  of the upper
              right corner of the 3-D plane.

Note:         If (NXA,NYA) is the lower left corner, NXL the
              width and NYL the height of the region  deter-
              mined by the routines AXSPOS and  AXSLEN,  the
              point  (X1,Y1,Z1)  corresponds  to  (NXA,NYA),
              (X2,Y2,Z2) to (NXA+NXL-1,NYA)  and  (X3,Y3,Z3)
              to (NXA+NXL-1,NYA-NYL+1), respectively.

                         G R F F I N

The routine  GRFFIN  terminates a projection into 3-D space.
The level will be set back to 3.

The call is:  CALL GRFFIN

12.14 Using the Z-Buffer

The DISLIN routines SURSHD and SURFCP use for smooth shading
a 32-bit floating point Z-buffer for hidden-surface elimina-
tion.  This Z-buffer  can also be used  by a  programmer for
creating shaded surfaces with elementary triangle routines. 

                       Z B F I N I

The routine  ZBFINI  creates a Z-buffer. The graphics output
format must be set to a raster format    (for example METAFL
('XWIN') or METAFL ('TIFF')).

The call is:  CALL ZBFINI (IRET)                 level 1,2,3

IRET          is the returned status (0: no errors).

                       Z B F F I N

The routine  ZBFFIN  terminates  writing  to a Z-buffer  and
frees the allocated space.

The call is:  CALL ZBFFIN                        level 1,2,3

                       Z B F T R I

The routine ZBFTRI plots a smooth triangle where hidden-sur-
face elimination is done with the Z-buffer.

The call is:  CALL ZBFTRI (XRAY, YRAY, ZRAY, IRAY)   level 3

XRAY, YRAY,   are the X-, Y-, and Z-coordinates of the three
       ZRAY   corners of the triangle in user coordinates.
IRAY          is an integer  array containing  the three co-
              lour values of the triangle corners.          

                       Z B F L I N

The routine  ZBFLIN plots a line in the current colour where
the  Z-buffer is used for hiddenline elimination.  This rou-
tine is used by SURSHD and SURFCP for drawing surface grids.

The call is:  CALL ZBFLIN (X1, Y1, Z1, X2, Y2, Z2)   level 3

X1, Y1, Z1    are the user coordinates of the start point.
X2, Y2, Z2    are the user coordinates of the end point.

12.15 Elementary Plot Routines

                         S T R T 3 D

The routine  STRT3D  moves the  pen  to a  three-dimensional
point.

The call is:  CALL STRT3D (X, Y, Z)                  level 3

X, Y, Z       are the absolute 3-D coordinates of the point.

                         C O N N 3 D

The routine CONN3D plots a line from the current pen positi-
on to a three-dimensional point. The line will be cut off at
the sides of the 3-D box. Different line styles can be used.

The call is:  CALL CONN3D (X, Y, Z)                  level 3

X, Y, Z       are the absolute 3-D coordinates of the point.

                         V E C T R 3

The routine VECTR3 plots a vector in the 3-D box.

The call is:  CALL VECTR3 (X1, Y1 ,Z1, X2, Y2, Z2, IVEC)
                                                     level 3

X1, Y1, Z1    are the absolute  3-D coordinates of the start
              point.
X2, Y2, Z2    are the absolute  3-D coordinates of  the  end
              point.
IVEC          defines the arrow head (see VECTOR).

12.16 Transformation of Coordinates

                         P O S 3 P T

The routine POS3PT converts three-dimensional user coordina-
tes to absolute 3-D coordinates.

The call is:  CALL POS3PT (X, Y, Z, XP, YP, ZP)      level 3

X, Y, Z       are the user coordinates.
XP, YP, ZP    are the absolute 3-D coordinates calculated by
              POS3PT.

The absolute 3-D coordinates can also be calculated with the
following functions:

              XP = X3DPOS (X, Y, Z)
              YP = Y3DPOS (X, Y, Z)
              ZP = Z3DPOS (X, Y, Z)

                         R E L 3 P T

The routine REL3PT converts user coordinates to plot coordi-
nates.

The call is:  CALL REL3PT (X, Y, Z, XP, YP)          level 3

X, Y, Z       are the user coordinates.
XP, YP        are the plot coordinates calculated by REL3PT.

The corresponding functions are:

              XP = X3DREL (X, Y, Z)
              YP = Y3DREL (X, Y, Z)

                         A B S 3 P T

The routine ABS3PT converts absolute 3-D coordinates to plot
coordinates.

The call is:  CALL ABS3PT (X, Y, Z, XP, YP)          level 3

X, Y, Z       are the absolute 3-D coordinates.
XP, YP        are the plot coordinates calculated by ABS3PT.

The corresponding functions are:

              XP = X3DABS (X, Y, Z)
              YP = Y3DABS (X, Y, Z)

12.17 Examples

            PROGRAM EXA12_1
            DIMENSION IXP(4),IYP(4)
            DATA IXP/200,1999,1999,200/
           *     IYP/2600,2600,801,801/
            EXTERNAL ZFUN  

            CALL SETPAG('DA4P')
            CALL DISINI
            CALL PAGERA
            CALL COMPLX

            CALL AXSPOS(200,2600)
            CALL AXSLEN(1800,1800)
            CALL NAME('X-axis','X')
            CALL NAME('Y-axis','Y')
            CALL NAME('Z-axis','Z')
            CALL TITLIN('Surface Plot (SURFUN)',2)
            CALL TITLIN('F(X,Y) = 2*SIN(X)*SIN(Y)',4)

            CALL GRAF3D(0.,360.,0.,90.,0.,360.,0.,90.,
           *            -3.,3.,-3.,1.)
            CALL HEIGHT(50)
            CALL TITLE
            CALL SHLSUR
            CALL SURFUN(ZFUN,1,10.,1,10.)

      C     Grid in the XY plane
            CALL GRFINI(-1.,-1.,-1.,1.,-1.,-1.,1.,1.,-1.)
            CALL NOGRAF
            CALL GRAF(0.,360.,0.,90.,0.,360.,0.,90.)
            CALL DASHL
            CALL GRID(1,1)
            CALL GRFFIN
      C     Grid in the YZ plane
            CALL GRFINI(-1.,-1.,-1.,-1.,1.,-1.,-1.,1.,1.)
            CALL GRAF(0.,360.,0.,90.,-3.,3.,-3.,1.)
            CALL GRID(1,1)
            CALL GRFFIN
      C     Shading in the XZ plane
            CALL GRFINI(-1.,1.,-1.,1.,1.,-1.,1.,1.,1.)
            CALL SHDPAT(7)
            CALL SOLID
            CALL AREAF(IXP,IYP,4)
            CALL GRFFIN
            CALL DISFIN
            END     

            FUNCTION ZFUN(X,Y)
            FPI=3.14159/180.
            ZFUN=2*SIN(X*FPI)*SIN(Y*FPI)
            END


            PROGRAM EXA12_2
            CHARACTER*60 CTIT1,CTIT2
            EXTERNAL ZFUN

            CTIT1='Surface Plot of the Parametric Function'
            CTIT2='[COS(t)*(3+COS(u)),
           *              SIN(t)*(3+COS(u)), SIN(u)]'
            PI=3.14159

            CALL SETPAG('DA4P')
            CALL METAFL('POST')
            CALL DISINI
            CALL HWFONT
            CALL PAGERA
            CALL AXSPOS(200,2400)
            CALL AXSLEN(1800,1800)
            CALL INTAX

            CALL TITLIN(CTIT1,2)
            CALL TITLIN(CTIT2,4)

            CALL NAME('X-axis','X')
            CALL NAME('Y-axis','Y')
            CALL NAME('Z-axis','Z')

            CALL VKYTIT(-300)
            CALL GRAF3D(-4.,4.,-4.,1.,-4.,4.,-4.,1.,
           *                          -3.,3.,-3.,1.)

            CALL HEIGHT(40)
            CALL TITLE

            CALL SURMSH('ON')
            STEP=2*PI/30.
            CALL SURFCP(ZFUN,0.,2*PI,STEP,0.,2*PI,STEP)
            CALL DISFIN
            END

            FUNCTION ZFUN(X,Y,IOPT)
            FPI=3.14159/180.

            IF(IOPT.EQ.1) THEN
              ZFUN=COS(X)*(3+COS(Y))
            ELSE IF(IOPT.EQ.2) THEN
              ZFUN=SIN(X)*(3+COS(Y))
            ELSE
              ZFUN=SIN(Y)
            END IF
            END

