A group of FORTRAN curve-fitting routines has been added to the Graphics Algorithms Library. There are three main user routines each using the method of Splines Under Tension ('Scalar and Planar-Valued Curve Fitting Using Splines Under Tension' - A K Cline, Comm. ACM, April 1974, Vol 17, No 4 p128).
The three main routines are each used for curve-fitting in differing circumstances:
The first, FVCURV, is intended to plot a single-valued function that assumes values y. at abscissae xi. (ie FVCURV fits a curve through Functional Values).
The second, OPCURV, is used in the more general situation, where it is required to pass a curve through a sequence of points (xi, yi) in the plane. (ie OPCURV is used for Open Planar curves).
In practice, the main difference between FVCURV and OPCURV is that OPCURV is capable of handling a multi-valued function.
The third, CPCURV, solves the same problem as does OPCURV, but for a solution curve that is closed. (ie CPCURV is for Closed Planar curves).
The purpose of using the method of splines under tension, is to imitate cubic splines, but to avoid the spurious points of inflection that may occur.
All three routines are capable of producing a solution curve composed of either dots or dashes, as well as a continuous curve.
FVCURV(N,X,Y,SIGMA,WORKA,WORKB) OPCURV(N,X,Y,SIGMA,WORKA,WORKB,WORKC,WORKD) CPCURV(N,X,Y,SIGMA,WORKA,WORKB,WORK2C,WORKD)
Each routine interpolates on the N data points, (X(I),Y(I)), and draws the curve from (X(1)),Y(1)) to (X(N),Y(N)).
Note: In the case of FVCURV, X must be monotonically increasing, ie X(I-1) < X(I).
In the case of CPCURV, the curve is extended from (X(N),Y(N)) to (X(1),Y(1)) to complete the closed curve.
SIGMA is the tension factor. The idea behind the method is that, where a cubic spline would produce a point of inflection, the use of a relatively large tension factor will straighten out the curve just sufficiently to produce a smooth curve. A reasonable range for SIGMA is from 0.05 to 50.0. An error will be given if SIGMA is less than 0.05. The smallest values of SIGMA will produce a curve that is approximately a cubic spline. The largest values of SIGMA will produce a curve consisting of straight line segments between consecutive data points.
WORKA, WORKB, WORKC, WORKD, and WORK2C are real arrays which are used for internal workspace. Except for WORK2C, they must all be declared to be of dimension N. WORK2C must be of dimension 2N.
A call to any of these three subroutines is sufficient to produce a curve. However, the user may wish to have more control over the curve which is drawn. Routines are available to set certain parameters which will have an effect on the solution curve, but which are normally set internally.
Parameters which the user may wish to set are:
(a) either or both of the slopes of the curve at its endpoints. (Obviously this is applicable only when FVCURV or OPCURV is being used, since a closed curve has no endpoints.)
The user routines to set values for the slopes are:
SETSL1(SSLP1) SETSLN(SSLPN) SETSLS(SSLP1,SSLPN)
where SSLP1 is to be the slope of the solution curve at (X(1),Y(1)) and SSLPN is to be the slope of the solution curve at (X(N),Y(N)).
SSLP1/SSLPN must be given as the angle (in degrees) made by the positive x-axis and the curve in its positive sense at the endpoint. (The positive sense of the curve is assumed to be that moving from point 1 to point N.). The angles must be measured anticlockwise from the positive x-axis to the positive sense of the curve.
(b) the number of subintervals to be used in each interval between the pairs of data points. That is, the number of intermediate points to be interpolated between data points, in order to plot the curve, will be the number of subintervals less one.
The user routine to set the number of subintervals to be used is:
SETNI(NNI)where NNI is the number of subintervals required.
If the user does not call SETNI, the number of subintervals will be calculated internally from the value of SIGMA chosen by the user.
As SIGMA increases, the curve becomes closer to a straight line between data points, and so fewer interpolated points are necessary. Hence, the number of subintervals calculated internally decreases as the value of SIGMA increases. As an indication to the user who wishes to use SETNI, the range of NNI used internally is from 60 (for SIGMA 0.05) to 1 (for SIGMA = 50.0).
As was stated in the introduction, any of the routines FVCURV, OPCURV, CPCURV, can be used to produce dotted/dashed solution curves, rather than continuous curves. This added facility need only involve the user in one further statement to be included in his program. This statement is the call to subroutine:
DOTSET(ON1,ON2,OFF1,OFF2)
as specified in SMOG Manual Amendments.
DOTSET may be called any number of times, and on each occasion must precede the call to the curve-fitting routine to which it refers. Subsequent calls to the curve-fitting routines will produce continuous lines unless DOTSET is called again.
Note: The user should be aware of the 'squashing' effect on the dot/dash configurations, if using a drawing region whose units are not in a 1:1 ratio.
(1) The routines can be used with either SMOG or SPROGS.
(2) None of the routines sets up a co-ordinate system. The user must set up his own before calling any of these routines. Should the user then require co-ordinate axes, he should make a call to GRAFRC ad GRAFT (as defined in the SMOG Manual) with the parameter N set to zero so that no graph is produced. This usage will cause an error message to be output, but will not halt the program. (see Example 1).
(3) The routines are accessible from the 1906A library file :GRAFLIB.GRAFLIB and this name must be included in a LIB parameter in a macro call.
On the 360/195 the routines are on autocall in SYS1.SMOG and so the JCL for running a SMOG job should be used.
(4) The routines use the following names which should be avoided by the user:
Routines names: FVCURV, OPCURV, CPCURV, FVCRVI, OPCRV1, CPCRV1, SETNI, CALCNT, SETSLI, SETSLN, SETSLS, CALCSL, CRVDAT, DSICRV Common Block names: CRVPAR, DOTCRV, DOTCOM, CLIBOP.
The two examples below illustrate uses of the three routines. The first example was run on the 1906A and the second on the 360/J95. However, either example may be run on either machine (with an appropriate SMOG call or JCL).
Example 1 draws curves through selections of data points using FVCURV and OPCURV showing various options. It uses the SMOG routines GRAFRG and GRAFT to set up and draw the axes and, in the first curve, to plot asterisks at the data points. (Note that if this example is run on the 360/195 then the 26.0 in the call to GRAFT in line 30 should be replaced by a 92.0 as the character codes are different on the two machines). A non-fatal error message will be output for each of the three calls to GRAFT which plot zero points. This is because the graph drawing routine is only used to draw the axes and the messages can be ignored.
If the program of the example is in a file EXAMPLE1 then the following SMOG call can be used to run it on the 1906A.
SMOG *CR EXAMPLE1,LIB :GRAFLIB.GRAFLIB, JT25
Example 2 draws curves through the same points using CPCURV with different values of SIGMA. In each case the routine CPCURV calculates the number of line segments used in each interval.
The example may be run on the 360/195 by EXECing a file containing the JCL and program listed below.
The FR8O output from the examples is shown.
Program Source
LIST C MASTER EXAMPLE1 C C EXAMPLES OF ROUTINES FVCURV AND OPCURV. C DIMENSION XPTS(31),YPTS(31),WORKA(31),WORKB(31),WORKC(31), X WORKD(31) C C INITIALISE FR80 CALL FRHCM CALL CINE C SET UP DATA FOR CURVE ONE, DO 5 I=1,11 XPTS(I)=FL0AT(I-1) 5 YPTS(I)=0.0 YPTS(3)=1.0 C C SET LIMITS, DRAW AXES AND TITLE, MARK DATA POINTS. C CALL LIMITS(0.0,-5.0,10.0,5.0,1.0,1.0) CALL GRAFRG(1.0) C C USE CENTRED CHARACTER (ASTERISK) FOR MARKING THE DATA POINTS. RESET C NORMAL CHARACTERS AFTERWARDS CALL BCENON CALL GRAFT(4,11,XPTS,YPTS,1.0,0.0,26.0) CALL BCENOF CALL TITLAB(34,34HGRAPH OF SPEC POINTS USING FVCURV ,6, 1 6HX-AXIS,6,6HY-AXIS) C C CALCULATE AND DRAW CURVE ONE CALL DOTSET(0,0,0.0,0.15,0.125) CALL FVCURV(11,XPTS,YPTS,1.0,WORKA,WORKB) CALL ADVFLM C SET UP DATA FOR CURVE TWO, C DO 10 I = 1,25 XPTS(I) = -4.0 + 0.5*(I-1) 10 YPTS(I) = SIN(XPTS(I)) C C RESET LIMITS, DRAW AXES AND TITLE CALL CINE CALL LIMITS(-4.0,-2.0,8.0,3.0.5.0.2.0) CALL GRAFRG(1.0) CALL GRAFT(4,0,XPTS,YPTS,1.0,0.0,0.0) CALL TITLAB(26,26HGRAPH OF SINX USING FVCURV,6,6HX-AXIS, X 6,6HY-AXIS) C C CALCULATE AND DRAW CURVE TWO. C CALL FVCURV(25,XPTS,YPTS,1.0,WORKA,WORKB) CALL ADVFLM C C SET UP DATA FOR CURVE THREE, C DO 20 I - 1,30 XPTS(I) = FLOAT(I) 20 YPTS(I) = ALOG(XPTS(I)) C C RESET LIMITS, DRAW AXES AND TITLE C CALL CINE CALL LIMITS(0.0,0.0,30.0,5.0,7.0,3.0) CALL GRAFRG(1.0) CALL GRAFT(4,0,XPTS,YPTS,1.0,0.0,0.0) CALL TITLAB(26,26HGRAPH OF LOGX USING OPCURV,6,6HX-AXIS, X 6,6HY-AXIS) C C CALCULATE AND DRAW CURVE THREE. C CALL OPCURV(30,XPTS,YPTS,1.0,WORKA,WORKB,WORKC,WORKD) CALL ADVFLM C C SET UP DATA FOR CURVE FOUR, C DO 30 I=1,19 XPTS(I) = 0.25*(I-1) + 0.75 30 YPTS(I) = 7.0*XPTS(I)**4)/12.0- 7.0*XPTS(I)**3 X + (359.0+XPTS(I)**2.)/12.- 107*XPTS(I)1/2. + 35. C C RESET LIMTS, DRAW AXES AND TITLE C CALL CINE CALL LIMITS (0.0,0.0,6.0,9.0,2.0,3.0) CALL GRAFRG(1.0) CALL GRAFT(4.0,XPTS,YPTS,1.0,0,0,0,0) CALL TITLAB(29,29HGRAPH OF QUARTIC USING OPCURV,;6HX-AXIS, X 6,6HY-AXIS) C C CALCULATE AND DRAW CURVE FOUR. C CALL DOTSET(0.2,0.1,0.25,0.15) CALL OPCURV(19,XPTS,YPTS,1.0,WORKA,WORKB,WORKC,WORKD) C C END PLOTTING C CALL ENDSPR STOP END
FR80 Output
Program Source and JCL
// JOBNAME JOB (ACCT,ID),EXAMPLE // EXEC FHCLG,CPRINT=YES,REGION=210K, // SYSLIB='SYS.SMOG' //C.SYSIN DD * C C EXAMPLE OF USE OF CPCURV, USING VARIOUS VALUES OF SIGMA. C DIMENSION X(8),Y(8),WORKA(8),WORKB(8),WORK2C(16),WORKD(8) DATA X / 1., 0.7071, 0.,-0.7071,-1., -0.7071, 0., .7071/, 1 Y / 0., .7071, 1 ., .7071, 0., -0.7071,-1., -0.7071/ REAL SIG(6) / 50.0, 25.0, 10.0, 1.0, 0.1,0.0 5/ C C INITIALISE FR80 C CALL FRHCM CALL APER C C SET LIMITS C CALL LIMITS(-1.5,-1.5,1.5,1.5,1.0,1.0) C C DRAW CURVE USING SIX VALUES OF SIGMA AND DIFFERENT DOT/DASH C COMBINATIONS C DO 20 KT = 1,6 C C IF APPLICABLE, SET LENGTHS/GAPS FOR DOTTED/DASHED LINES. C IF (KT.EQ.3.OR.KT.EQ.4) CALL DOTSET( 0.05, 0.03, 0.025, 0.025) IF (KT.EQ.5.OR.KT.EQ.6) CALL DOTSET(0.0, 0.0, 0.025, 0.025) C C CALCULATE AND DRAW CURVE C CALL CPCURV(8,X,Y,SIG(KT),WORKA,WORKB,WORK2C,WORKD) 20 CALL ADVFLM C C END PLOTTING C CALL ENDSPR STOP END /* //G.GRAPHICS DD SYSOUT=(G,,HCM) //G.GT12F001 DD SYSOUT=A,DCB=PRINTER
FR80 Output