Chapter 10: Drawing lines and curves

Previous Chapter          LLUs Home          Next Chapter          Index
There are several methods for drawing lines and curves (polylines) on a plot and controlling line characteristics, like the dash pattern, color, width, and smoothness. The following modules demonstrate how to draw curves and set their characteristics using GKS, SPPS, and higher level routines.

NCAR Graphics lines and curves

Table of line and curve-drawing user entry points

There are three levels of user entry points for drawing lines and curves. This module organizes the routines according to their level (GKS, SPPS, and higher level NCAR Graphics routines).

GKS routines

GPL
Draws a connected set of line segments specified by X and Y coordinate arrays.

GSLN
Sets the line type to either a solid, dashed, dotted, or dashed-dotted line.

GSLWSC
Sets the line width scale factor (thickness) of a polyline.

GSCR
Sets up a color table and associates a red-green-blue color value with an index.

GSPLCI
Sets the polyline color index.

GQLN
Retrieves the current setting for the line type.

GQLWSC
Retrieves the current setting for the line width scale factor (thickness).

GQPLCI
Retrieves the current polyline color index setting.

SPPS routines

LINE
Draws a line between two points when given two user endpoint coordinates.

CURVE
Draws a curve defined by X and Y user coordinate arrays.

PLOTIF
Moves the plotter pen to a fractional coordinate position, or flushes the SPPS polyline buffer.

VECTOR
Draws a line segment from the current plotter pen position to the given X and Y user coordinates. This works in conjunction with the FRSTPT routine.

FRSTPT
Sets the current plotter pen position when given user coordinates and is used in conjunction with the VECTOR routine.

Higher level routines

LINED
Draws a single line between two points in world coordinates. Crowded-line removal is possible with this routine.

CURVED
Draws a curve defined by X and Y world coordinate arrays. Curve smoothing and crowded-line removal is possible with this routine.

VECTD
Draws a line from the current plotter pen coordinates to the given world coordinates. Curve smoothing and crowded-line removal is possible with this routine. VECTD works in conjunction with FRSTD and LASTD.

FRSTD
Sets the current plotter pen position when given world coordinates. FRSTD works in conjunction with VECTD and LASTD.

LASTD
Flushes buffers and finishes drawing a line after calling FRSTD, VECTD, or LINED.

DASHDC
Chooses a dash pattern with labels.

DASHDB
Chooses a dash pattern without labels.

Table of line and curve-drawing parameters

For a complete description of SPPS parameters, see the next module and the spps_params man page.

SPPS parameters

------------------------------------------------------------------
Parameter  Brief description     Fortran type    Routines affected  
------------------------------------------------------------------
PB         Polyline Buffer size  Integer (2-50)  PLOTIF             
------------------------------------------------------------------

Internal parameters*

-------------------------------------------------------------------------
Parameter  Brief description              Fortran type  Routines affected  
-------------------------------------------------------------------------
IPAU       Line and gap size              Integer       DASHDC, DASHDB     
FPART      First solid segment factor     Real          DASHDC             
IGP        Character GaP flag             Integer       DASHDC             
ICLOSE     Pen-up parameter               Integer       DASHDC, DASHDB     
IOFFS      Smoothing flag                 Integer       DASHDC             
TENSN      TENSioN factor                 Real          DASHDC             
NP         Point-interpolation parameter  Integer       DASHDC             
SMALL      Saved points min. distance     Real          DASHDC             
L1         Max. number of points saved    Integer       DASHDC             
ADDLR      Number of free space units     Real          DASHDC             
ADDTB      Number of free space units     Real          DASHDC             
MLLINE     Max. crowded-LINE length       Integer       DASHDC             
-------------------------------------------------------------------------
* These parameters are not accessible via parameter retrieving and setting routines at this time. They are available in common blocks. Please see the man pages for the routines affected.

Line and curve-drawing parameters: What they do and how to use them

The line and curve drawing routines have a single parameter for controlling line characteristics. SPPS parameters are controlled using the SETUSV routine. GKS polyline attributes will affect curves drawn using any NCAR Graphics routine. Please see the spps_params man page for more information on setting SPPS parameters.

Synopsis

      CALL SETUSV (PNAM, IVAL)

Routines

SETUSV
Sets the value of one of the SPPS parameters.

SETUSV is a general purpose routine for setting several SPPS parameters; however, this module will only focus on setting the parameter that affects the curve and line drawing routines. For a complete description of all the SETUSV supported parameters, see the online man page documentation.

Arguments

PNAM
Character, Input---Consists of a two-letter name contained within single quotation marks (').

PB Sets the polyline buffer size used in the PLOTIF routine. The buffer is an efficiency mechanism for storing several polyline segments and then executing them together. The default size is 50. Setting the size to 2 effectively turns buffering off. Valid values range from 2 to 50, inclusive.
IVAL
Integer, Input---An integer value.

Discussion

Currently, the internal parameters listed on the previous page for controlling the line characteristics can only be accessed through common blocks. There are no access routines for these parameters at the time of this printing. For more information on accessing these parameters, see the dashline_params man page.

Drawing lines and curves with GKS routines

GPL is used to draw a series of connected line segments when given X and Y input arrays of world coordinates.

This module demonstrates how to set the line type and how to draw lines using GKS routines.

Drawing lines and curves with GKS routines

Code segment from fgkgpl.f

1       REAL    XCD(1500), YCD(1500)
2       CALL GSPLCI (2)
3       DO 40 ING=1,1500
4          RAD=REAL(ING)/1000.
5          ANG=DTR*REAL(ING-1)
6          XCD(ING)=.25+.5*RAD*COS(ANG)
7          YCD(ING)=.25+.5*RAD*SIN(ANG)
8  40   CONTINUE
9       CALL SET (.24,.37,.48,.61,-1.,1.,-1.,1.,1)
10      CALL GPL(1500, XCD, YCD)
11      CALL SET (.03,.10,.43,.50,-1.,1.,-1.,1.,1)
12      CALL GPL(1500, XCD, YCD)

Synopsis

      CALL GPL (NPTS, XCD, YCD)

Arguments

NPTS
Integer, Input---The number of points defining the line to be drawn. NPTS>1.

XCD(NPTS), YCD(NPTS)
Real arrays, Input---The X and Y world coordinates of the points that define the curve to be drawn.

Discussion

The fgkgpl.f code segment demonstrates how spiral lines are drawn off the east coast of Africa and Southeast Asia using the GKS GPL routine.

Line 1 defines the X and Y input coordinate arrays.

Line 2 sets the current polyline color index to 2. The color table and associated indices were set up prior to entering this code segment.

Lines 3 through 8 compute the X and Y input coordinates for a spiral line.

Line 9 calls the SET routine to define the mapping from the fractional coordinate system of the plotter to the user coordinate system. This effectively positions the spiral on the frame off the coast of Southeast Asia.

Line 10 calls GPL to draw the spiral. The first argument specifies that there are 1,500 coordinates in the line. The second and third arguments are the arrays of coordinates defining the spiral.

Line 11 defines a new mapping and effectively positions the second spiral off the east coast of Africa.

Line 12 draws the second spiral.

Drawing lines and curves with SPPS routines

The SPPS routine LINE can be used to draw a single line on a plot when given the line's endpoint coordinates.

This module demonstrates how to draw lines using the LINE routine.

Drawing a flow chart with the LINE routine

Code segment from fspline.f

1       CALL GSPLCI(2)
2       CALL SET (0.,1.,0.,1.,0.,20., 0.,20.,1)
3       CALL GSLWSC(4.)
4       CALL LINE(2.,8.,2.,10.)
5       CALL LINE(2.,10.,5.,10.)
6       CALL LINE(5.,10.,5.,8.)
7       CALL LINE(5.,8.,2.,8.)
8       CALL PLCHLQ(3.5,9.,'Read I',15.,0.,0.)

Synopsis

      CALL LINE (X1, Y1, X2, Y2)

Arguments

X1, Y1
Real, Input---The X and Y user coordinates of the starting point of the line segment.

X2, Y2
Real, Input---The X and Y user coordinates of the endpoint of the line segment.

Discussion

The SPPS routine LINE is used to draw a line between two points. Line characteristics like polyline type, line width, and color can be set by calling the GKS routines GSLN (set line type), GSLWSC (set line width), GSCR (create color table), and GSPLCI (set color index) before calling LINE.

The fspline.f code segment draws a single box and places the text "Read I" in its center.

Line 1 sets the current polyline color index. A color table was set up previously in the code using the GKS GSCR routine. Line 2 sets up a mapping between the plotter coordinates and the user coordinate system. Line 3 sets the line width to 4. Lines 4 through 7 make four calls to the LINE routine to draw the four sides of a box. Line 8 draws the text, "Read I", in the center of the box that was just drawn.

Drawing lines and curves with SPPS routines

The SPPS routine CURVE draws a line through a set of X and Y user coordinates.

This module demonstrates how to draw curves using CURVE and compares it with the GKS routine GPL.

Drawing curves with the CURVE routine

Code segment from fspcurve.f

1  DATA XCOORD/1.,2.,3.,5.,7.,9.,13.,16.,19.,23./
2  DATA YCOORD/1.,3.,5.,6.,7.,10.,13.,16.,14.,17./
3
4  CALL SET (0.,1., 0., 1., 25., 0., 0., 20., 1)
5  CALL GSLN(2)
6  CALL GPL(10,XCOORD,YCOORD)
7  CALL GSLN(1)
8  CALL CURVE(XCOORD,YCOORD,10)
9  CALL FRAME

Synopsis

      CALL CURVE (XCD, YCD, NPTS)

Arguments

XCD, YCD
Real arrays, Input---The X and Y user coordinates of the points that define the curve to be drawn.

NPTS
Integer, Input---The number of points defining the curve.

Discussion

The SPPS routine CURVE draws a curve defined by the input X and Y user coordinates. The plotter pen is left at the location of the last point in the curve.

The code segment and graphic demonstrate how to use the CURVE routine and how it differs from the GKS curve-drawing routine, GPL.

If the routine SET is called to reverse the axes or use logarithmic mappings, then you should use the CURVE routine instead of GPL, since GPL does not recognize axis reversal or logarithmic mappings.

In the fspcurve example, CURVE and GPL plot the same data points. However, since the SET call reversed the X axis, GPL does not draw the curve correctly.

Lines 1 and 2 of the fspcurve.f code segment initialize the X and Y coordinates of the line to be drawn.

Line 4 sets up the mapping from plotter space to user coordinates. Notice that we have reversed the X axis to map from 25 to 0.

Line 5 sets the line type to "dashed" using the GKS GSLN routine. GSLN takes a single integer argument, which specifies the type of line to be drawn. The argument may be one of the following:

1 Solid line (default)
2 Dashed line
3 Dotted line
4 Dashed-dotted line
Until the line type is reset, all line-drawing routines will draw lines with the type specified by GSLN.

Line 6 calls the GKS routine GPL to draw a dashed line. GPL will ignore the axis reversal specified with the SET call.

Line 7 sets the line type to "solid."

Line 8 calls the SPPS routine CURVE to draw a solid line. CURVE recognizes the axis reversal and therefore mirrors the curve drawn by the GPL routine.

Line 9 advances the frame.

Drawing lines and curves with high level routines

The high level routine CURVED draws curves in the same manner as the SPPS routine, CURVE. CURVED, however, has more functionality, which is discussed in later modules.

This module demonstrates how to draw curves using CURVED and set line characteristics such as color and width.

Drawing circles with the CURVED routine

Code segment from fdlcurvd.f

1       REAL XCOOR2(120), YCOOR2(120)
2
3       CALL SET(.01,.99,0.01,.99,0.,1.,0.,1.,1)
4       CALL GNCRCL(.5,.5,.333,30,XCOOR2, YCOOR2)
5       CALL GSLWSC(5.)
6       CALL GSPLCI(2)
7       CALL CURVED(XCOOR2,YCOOR2,30)
8       CALL PLCHLQ(.5,.7,'Circles',.03,0.,0.)
9       CALL PLCHLQ(.5,.6,'of',.03,0.,0.)
10      CALL PLCHLQ(.5,.5,'Circles',.03,0.,0.)
11      CALL PLCHLQ(.5,.4,'of',.03,0.,0.)
12      CALL PLCHLQ(.5,.3,'Circles',.03,0.,0.)

Synopsis

      CALL CURVED (XCD, YCD, NPTS)

Arguments

XCD, YCD
Real arrays, Input---The X and Y user coordinates of the points that define the curve to be drawn.

NPTS
Integer, Input---The number of points defining the curve.

Discussion

The high level CURVED routine draws a curve defined by the input X and Y user coordinates.

The fdlcurvd.f code segment and graphic demonstrate how to use the CURVED routine and set line characteristics like color and line width. Every circle in the graphic was drawn with a call to CURVED. The code segment draws the large circle in which the text "Circles of Circles of Circles" is centered. Although CURVED was used only to draw circles in this example, it can be used to draw curves of any shape.

Line 1 declares the array of user coordinates. Line 3 sets up the mapping between the plotter and user coordinates. In this example, the user coordinates range from 0. to 1. in both the X and Y directions. Line 4 calls a routine that initializes the XCOOR2 and YCOOR2 arrays with the coordinates of a circle centered at (.5,.5), a radius of .333, and 30 points, which define it. Line 5 sets the line width to 5 (1 is the default). Line 6 sets the color of the line. The color table was set up prior to entering this code segment with the GKS GSCR routine. The argument (2) passed to the GSPLCI routine represents an index in the color table. Line 7 draws the large circle in the center of the graphic. Lines 8 through 12 draw text in the center of the large circle.

Setting the dash pattern of lines and curves

When using the higher level routines like CURVED, LINED, and VECTD, you can represent lines with any dash pattern. Whereas the GKS GSLN utility only lets you set four line types (solid, dashed, dotted, and dotted-dashed), the DASHDC and DASHDB routines let you set any line type, including lines with labels. This module demonstrates how to set any dash pattern for your lines.

Setting line dash patterns

Code segment from fdldashd.f

1       STR = '$''$''Line''drawn''with''VECTD$''$''$''$'''
2       CALL DASHDC(STR,15,20)
3       CALL FRSTD(0.,.60)
4       DO 22 I=1,360
5              Y = (SIN(REAL(I)*(TWOPI/360.)) * .25) + .60
6              CALL VECTD(REAL(I)/360.,Y)
7   22  CONTINUE
8       STR = '$$$$$$Line''drawn''with''CURVED$$$$$$$$$$$$'
9       CALL DASHDC(STR,15,20)
10      DO 23 I=1,360
11              XCOORD(I) = REAL(I)/360.
12              YCOORD(I) = (SIN(REAL(I)*(TWOPI/360.)) * .25) + .45
13  23  CONTINUE
14      CALL CURVED(XCOORD, YCOORD, 360)
15      CALL DASHDB(63903)
16      CALL LINED(0.1,.15, .9,.15)
17      CALL PLCHLQ (0.5,0.10,'Line drawn with LINED' ,20.,0.,0.)

Synopsis

      CALL DASHDC (CPAT, JCRT, JSIZE)
      CALL DASHDB (IPAT)

Arguments

CPAT
Character string, Input---CPAT is a string of arbitrary length. However, 60 characters is a practical limit. The string specifies the dash pattern for lines drawn with CURVED, VECTD, and LINED. A dollar sign ($) indicates a solid, a single quotation mark (') indicates a gap, and blanks are ignored. Any other character is considered to be part of the line label. For example, if CPAT were set to $$$'A'Label'$$$, lines would be drawn similar to this: --- A Label ------ A Label ---. The pattern is repeated for the entire length of the line.

JCRT
Integer, Input---Specifies the length, in plotter address units, of the line or space represented by the dollar sign ($) or single quotation mark (') in the CPAT argument.

JSIZE
Integer, Input---Specifies the size of the plotted characters. If JSIZE is between 0 and 3, then the size represents 1., 1.5, 2., and 3. times an 8-plotter address unit width. Otherwise, it represents the character width in plotter address units.

IPAT
Integer, Input---IPAT is a 16-bit dash pattern (1=solid, 0=blank). For example, the binary number 1111000011110000, when converted to base 10, will give dashes of medium length.

Discussion

Either the DASHDB or the DASHDC routines can be used to set the dash pattern of a line. However, the DASHDC routine provides more flexibility by allowing the user to specify a label and character sizes along with the dash pattern.

The fdldashd.f code segment and graphic demonstrate how to set the dash pattern and line label of a line using DASHDC and DASHDB.

Line 1 initializes a string that specifies a dash pattern. Dollar signs ($) represent solid portions and single quotation marks (') represent spaces. Note that since FORTRAN77 string constants are enclosed in single quotation marks ('), a single quotation mark (') is represented by two adjacent single quotation marks, (''). Line 2 sets the dash pattern and specifies that the length of a line or space represented by the dollar sign ($) or single quotation mark (') is 15 plotter address units. The last argument specifies the character width in the line label to be 20 plotter address units.

Line 3 calls the FRSTD routine to put the plotter pen down at a point specified in world coordinates. FRSTD must be called prior to calling VECTD to position the plotter pen. This represents the starting point of a line segment drawn by the VECTD routine.

Lines 4 through 7 draw a dashed sine curve using the VECTD routine. VECTD takes two arguments, the X and Y world coordinates of the new plotter pen position. Line 8 initializes a string with a new dash pattern. Line 9 sets the dash pattern. Lines 10 through 13 specify the coordinates for the second sine curve. Line 14 draws the second curve using CURVED.

Line 15 sets a new dash pattern using DASHDB. 63903 (decimal) = 1111100110011111 (binary); therefore, line 15 specifies a dashed line with unequal lengths of solid portions and gaps. Line 16 draws a straight line with the LINED routine. LINED takes four arguments. The first two are the X and Y world coordinates of the starting point of the line, and the second two are the X and Y world coordinates of the ending point of the line. Line 17 draws a label under the last line.

Smoothing curves and removing crowded lines

You can smooth curves and remove crowded lines by loading special libraries when you link your NCAR Graphics program. This module demonstrates the effect of smoothing and crowded-line removal and how to load the libraries that control this.

The effect of curve smoothing and crowded line removal

Code segment from fdlsmth.f

1       REAL XCOORD(10), YCOORD(10)
2
3       CALL RESET
4       DO 10 I=1,50
5              CALL GNCRCL(REAL(I)/50.,.5,.333,10,XCOORD, YCOORD)
6              CALL CURVED(XCOORD,YCOORD,10)
7   10  CONTINUE
8       CALL PLCHLQ(.5,.95,'Smoothing and Crowded Line Removal',.02,0.,0.)
9       CALL FRAME

Synopsis

      CALL RESET

Arguments

None.

Discussion

The RESET routine only needs to be called when you want to remove crowded lines; it is not needed for line smoothing. The RESET routine initializes a special buffer that is used in crowded-line removal. It should be called every time you begin to draw into a new frame.

The three graphics on the opposite page demonstrate the effect of smoothing and crowded-line removal. The effects of curve smoothing are obvious in this example. However, the effects of crowded-line removal are harder to detect. The lines are most crowded along the top and bottom of the plot. If you look closely at the third image, you will notice some of the crowded lines that are present in the two previous images have been removed, especially near the top and bottom of the plot.

Smoothing is turned on by loading the libdashsmth.o library when you link your program. This is done by adding the -smooth option to your ncargf77 command line:

ncargf77 -smooth file.f
or by explicitly loading libdashsmth.o when you compile:

f77 file.f $NCARG_ROOT/lib/ncarg/robj/libdashsmth.o ...
Crowded-line removal and smoothing are turned on by loading the libdashsupr.o library when you link your program. This is done by adding the -super option to your ncargf77 command line:

ncargf77 -super file.f
or by explicitly loading libdashsupr.o when you compile your program:

f77 file.f $NCARG_ROOT/lib/ncarg/robj/libdashsupr.o ...
Each of the three example graphics was generated from the same source code, but the last two graphics were compiled with the -smooth and -super options, respectively. The first graphic was created without using any options.

Line 1 of the fdlsmth.f code segment declares the X and Y coordinate arrays that will contain the user coordinates for drawing the curves. Line 3 calls RESET to initialize the plot buffer. This call was only needed for the last graphic, which used crowded-line removal. If we only wanted to do curve smoothing, the RESET routine could have been omitted. Lines 4 through 7 draw 50 circles across the frame. In this example, we call CURVED. However, line smoothing and crowded-line removal work with the VECTD routine also. Smoothing does not effect the output of the LINED routine, but crowded-line removal does. Line 8 labels the plot. Line 9 advances the frame.

Changing line color

The color of curves and lines are changed by calling the GKS routine GSPLCI. This module demonstrates how to change the color of lines.

Changing line color

Code segment from fgklnclr.f

1       CALL GSCR (1,0,1.,1.,1.)
2       CALL GSCR (1,1,0.,0.,0.)
3       CALL GSCR (1,2,1.,0.,0.)
4       CALL GSCR (1,3,0.,1.,0.)
5       CALL GSCR (1,4,0.,0.,1.)
6       DTHETA = TWOPI/NPTP
7       DO 10 I=1,16
8          ANG = DTHETA*REAL(I) + .19625
9          XC = RP*COS(ANG)
10         YC = RP*SIN(ANG)
11         CALL GSPLCI (MOD(I,4)+1)
12         CALL GSLWSC(6.) 
13         CALL LINED(X0P,Y0P,X0P+XC,Y0P+YC)
14  10  CONTINUE

Synopsis

      CALL GSCR (WKID, CI, CR, CG, CB)
      CALL GSPLCI (INDEX)

Arguments

WKID
Integer, Input---The workstation identifier.

CI
Integer, Input---A color index to be assigned a color of CR, CG, CB (red, green, blue). Color index 0 defines the background color.

CR
Real, Input---An intensity of red between a minimum of 0. and a maximum of 1.

CG
Real, Input---A green intensity between 0. and 1.

CB
Real, Input---A blue intensity between 0. and 1.

INDEX
Integer, Input---An index into the color table, which was created with previous GSCR calls.

Discussion

The GSCR and GSPLCI routines are used in combination to first create a color table and then pick a line color.

Lines 1 through 5 in the fgklnclr.f code segment call the GSCR routine to create a color table with five entries (indices 0 through 4). Line 1 defines the background color white (CR=1., CG=1., CB=1.) Lines 2, 3, 4, and 5 define the colors black, red, green, and blue, respectively. Line 6 initializes a constant. Line 7 enters a loop that draws 16 lines. Line 8 computes the line angle. Lines 9 and 10 compute the endpoint of a line. Line 11 sets the line color by specifying an index into the color table created by GSCR. Line 12 sets the line width. Line 13 draws the line. Line 14 ends the loop.

More information on color tables appears in Chapter 7 "Color tables and color mapping systems."

Changing line width

The line width of polylines is set using the GKS routine GSLWSC. This module demonstrates how to set the line width of curves and lines.

Setting line widths

Code segment from fgklnwth.f

1       DO 10 I=1,16
2          ANG = DTHETA*REAL(I) + .19625
3          XC = RP*COS(ANG)
4          YC = RP*SIN(ANG)
5          CALL GSPLCI (1)
6          CALL GSLWSC(REAL(I)) 
7          CALL LINED(X0P,Y0P,X0P+XC,Y0P+YC)
8   10  CONTINUE

Synopsis

      CALL GSLWSC (WIDTH) 

Arguments

WIDTH
Real, Input ---The scale factor to control the line width of the polyline to be drawn. It must be greater than or equal to 0. WIDTH is applied to the nominal line width on a given device, and the line widths are mapped to the nearest available line width representable on that device.

Discussion

The GSLWSC routine is used to set the width of polylines drawn on a plot. The lines in the example graphic were each drawn after setting the line width to a new value with the GSLWSC routine.

The fgklnwth.f code segment shows how the lines were drawn by increasing the line width on every iteration of the loop.

Line 1 begins the loop. Line 2 computes the line angle. DTHETA is a constant used to space the lines equally around a circle, and it is defined before entering the loop. Lines 3 and 4 compute the endpoint of a line. Line 5 sets the line color. Line 6 sets the line width. Line 7 draws a single line, and line 8 completes the loop.

Previous Chapter          LLUs Home          Next Chapter          Index