home *** CD-ROM | disk | FTP | other *** search
- /*
- ** g r a p h . r e x x
- **
- ** This is a simple graphing function that plots functions passed to it.
- ** It determines upper and lower limits for the function in the range to
- ** be plotted, and scales the graph accordingly. It determines a reasonable
- ** scale division to use and draws a grid. Wait till it's done plotting and
- ** then fiddle the sizing gadget! Click on the close gadget to quit.
- **
- ** Calling sequence:
- **
- ** call graph(title, bins, xmin, xmax, function)
- **
- ** Arguments:
- **
- ** title The string to put at the bottom of the graph
- ** bins The number of horizontal samples to compute
- ** xmin The starting X value
- ** xmax The ending X value
- ** function The function to compute. The function must be of
- ** a single variable, x, and can otherwise only include
- ** math functions and numerical constants. Be careful
- ** and avoid specifying functions with singularities in
- ** the plotting range.
- **
- ** Examples:
- ** title bins xmin xmax function
- **
- ** call graph("exp(-x2)" , 50, -2.5, 2.5, "30. * exp(-(x**2))")
- ** call graph("x3 + 2x - 13", 25, -2.5, 2.5, "x**3 + 2*x - 13" )
- ** call graph("sin(x)" , 25, 0.0, 6.3, "45. * sin(x)" )
- ** call graph("log(x)" , 25, 0.01, 5.0, "45. * log(x)" )
- **
- ** By W.G.J. Langeveld, march 1989.
- */
-
- /* trace r */
- parse arg tt, nn, xx, yy, ff
-
- if ~show('l', "rexxarplib.library") then do
- check = addlib('rexxsupport.library',0,-30,0)
- check = addlib('rexxmathlib.library',0,-30,0)
- check = addlib('rexxarplib.library',0,-30,0)
- end
-
- plot.bins = nn
- plot.xmin = xx
- plot.xmax = yy
- plot.title = tt
-
- delta = (plot.xmax - plot.xmin)/plot.bins
- x = plot.xmin
- do i = 0 to plot.bins
- interpret "plot.i = "||ff
- x = x + delta
- end
-
- /*
- * Determine the max and min of the curve
- */
- minval = plot.0
- maxval = plot.0
- do i = 1 to plot.bins
- maxval = max(plot.i,maxval)
- minval = min(plot.i,minval)
- end
-
- /*
- * Initial window sizes
- */
- window.leftedge = 50
- window.topedge = 25
- window.width = 300
- window.height = 150
-
- /*
- * Set up a host.
- */
- address command runwsh "'call CreateHost(GRAPHHOST, GRAPHPORT)'"
- /*
- * Wait for a while until host is ready.
- */
- do 50 while ~show('Ports','GRAPHHOST')
- call delay 10 /* 200 ms */
- end
-
- /*
- * Open the window
- */
- idcmp = 'CLOSEWINDOW+NEWSIZE'
- flags = 'WINDOWCLOSE+WINDOWDRAG+WINDOWDEPTH+WINDOWSIZING'
- call OpenWindow(GRAPHHOST, window.leftedge, window.topedge, window.width, ,
- window.height, idcmp, flags)
- /*
- * Set NEWSIZE message to something useful
- */
- call ModifyHost(GRAPHHOST, NEWSIZE, "%w %h")
-
- /* Open our host port */
- call openport(GRAPHPORT)
-
- start:
- /*
- * Make a drawing area
- */
- area.topedge = min(0.1, 20/window.height)
- area.leftedge = min(0.2, 60/window.width)
- area.width = 1.0 - 2 * area.leftedge
- area.height = 1.0 - 3 * area.topedge
- /*
- * Draw the box outline of the plot
- */
- call SetAPen(GRAPHHOST, 3)
- call Move(GRAPHHOST, area.leftedge * window.width - 2, ,
- area.topedge * window.height - 1)
- call Draw(GRAPHHOST, area.leftedge * window.width - 2, ,
- (area.topedge + area.height) * window.height + 1)
- call Draw(GRAPHHOST, (area.leftedge + area.width) * window.width + 2, ,
- (area.topedge + area.height) * window.height + 1)
- call Draw(GRAPHHOST, (area.leftedge + area.width) * window.width + 2, ,
- area.topedge * window.height - 1)
- call Draw(GRAPHHOST, area.leftedge * window.width - 2, ,
- area.topedge * window.height - 1)
-
- /*
- * Determine a nice grid to use. Try for 15 pixels heigh.
- */
- vticks = (window.height * area.height) % 15
- vscale = (maxval - minval) / vticks
- if vscale < 1 then
- do
- do imults = 1 until vscale > 1
- vscale = vscale * 10
- end
- vscale = nint(vscale * 2) / 2
- /* do i = 1 to imults
- vscale = vscale / 10
- end */
- vscale = vscale / 10**imults
- end
- else
- do
- do imults = 1 until vscale < 1
- vscale = vscale / 10
- end
- vscale = vscale * 10
- vscale = nint(vscale * 2) / 2
- /* do i = 1 to imults - 1
- vscale = vscale * 10
- end */
- vscale = vscale * 10**(imults-1)
- end
-
- /*
- * ...and for 50 pixels wide
- */
- hticks = (window.width * area.width) % 50
- hscale = (plot.xmax - plot.xmin)/hticks
- if hscale < 1 then
- do
- do imults = 1 until hscale > 1
- hscale = hscale * 10
- end
- hscale = nint(hscale * 2) / 2
- /* do i = 1 to imults
- hscale = hscale / 10
- end */
- hscale = hscale * 10**(-imults)
- end
- else
- do
- do imults = 1 until hscale < 1
- hscale = hscale / 10
- end
- hscale = hscale * 10
- hscale = nint(hscale * 2) / 2
- /* do i = 1 to imults - 1
- hscale = hscale * 10
- end */
- hscale = hscale * 10**(imults-1)
- end
-
- /*
- * Draw the grid and add scale text
- */
- ys = (minval % vscale) * vscale
- if ys < minval then ys = ys + vscale
- do while ys <= maxval
- level = (area.topedge + area.height * ,
- (1.0 - (ys - minval) / (maxval - minval))) * window.height
- call SetAPen(GRAPHHOST, 3)
- call SetDrPt(GRAPHHOST, c2d('C3C3C3C3'x))
- call Move(GRAPHHOST, area.leftedge * window.width, level)
- call Draw(GRAPHHOST, (area.leftedge + area.width) * window.width, level)
-
- call SetAPen(GRAPHHOST, 1)
- call SetDrPt(GRAPHHOST, c2d('FFFFFFFF'x))
- call Move(GRAPHHOST, area.leftedge * window.width - 8 * length(ys) - 8, ,
- level + 4)
- call Text(GRAPHHOST, ys)
- ys = ys + vscale
- /* if ys > maxval then leave */
- end
-
- /* trace off */
- xs = (plot.xmin % hscale) * hscale
- if xs < plot.xmin then xs = xs + hscale
- do while xs < plot.xmax
- level = (area.leftedge + area.width * /* */ ,
- ((xs - plot.xmin) / (plot.xmax - plot.xmin))) * window.width
- call SetAPen(GRAPHHOST, 3)
- call SetDrPt(GRAPHHOST, c2d('C3C3C3C3'x))
- call Move(GRAPHHOST, level, area.topedge * window.height)
- call Draw(GRAPHHOST, level, (area.topedge + area.height) * window.height)
-
- call SetAPen(GRAPHHOST, 1)
- call SetDrPt(GRAPHHOST, c2d('FFFFFFFF'x))
- call Move(GRAPHHOST, level - length(xs) * 4, /* */ ,
- (area.topedge + area.height) * window.height + 10)
- call Text(GRAPHHOST, xs)
- xs = xs + hscale
- /* if xs > plot.xmax then leave */
- end
-
- /*
- * Draw the zero lines (if exist)
- */
- if minval <= 0 & maxval > 0 then do
- zerolevel = (area.topedge + area.height * ,
- (1.0 + minval / (maxval - minval))) * window.height
- call SetAPen(GRAPHHOST, 2)
- call Move(GRAPHHOST, area.leftedge * window.width, zerolevel)
- call Draw(GRAPHHOST, (area.leftedge + area.width) * window.width, zerolevel)
- end
-
- if plot.xmin <= 0 & plot.xmax > 0 then
- do
- zerolevel = (area.leftedge - area.width * /* */ ,
- (plot.xmin / (plot.xmax - plot.xmin))) * window.width
- call SetAPen(GRAPHHOST, 2)
- call Move(GRAPHHOST, zerolevel, area.topedge * window.height)
- call Draw(GRAPHHOST, zerolevel, /* */ ,
- (area.topedge + area.height) * window.height)
- end
-
- /*
- * Plot the title
- */
- call SetAPen(GRAPHHOST, 1)
- call Move(GRAPHHOST, /* */ ,
- (area.leftedge + area.width / 2) * window.width - length(plot.title) * 4, ,
- 0.5 * (1.0 + area.topedge + area.height) * window.height + 10)
- call Text(GRAPHHOST, plot.title)
-
- /*
- * Draw the plot
- */
- call SetAPen(GRAPHHOST, 1)
- call Move(GRAPHHOST, area.leftedge * window.width, ,
- (area.topedge + area.height * (1.0 - ,
- (plot.0 - minval) / (maxval - minval))) * window.height)
- do i = 0 to plot.bins
- call Draw(GRAPHHOST, /* */ ,
- (area.width * i / plot.bins + area.leftedge) * window.width, /* */ ,
- (area.topedge + area.height * /* */ ,
- (1.0 - (plot.i - minval) / (maxval - minval))) * window.height)
- end
-
- /*
- * Wait for messages at GRAPHPORT
- */
- quitflag = 0
- do forever until quitflag
- call waitpkt(GRAPHPORT)
- p = getpkt(GRAPHPORT)
- if p ~== NULL() then
- do
-
- thisarg = getarg(p)
- t = reply(p, 0)
- /*
- * Messages are either CLOSEWINDOW
- */
- if thisarg == 'CLOSEWINDOW' then do
- call CloseWindow(GRAPHHOST)
- quitflag = 1
- end
- /*
- * ...or NEWSIZE
- */
- else do
- parse var thisarg xwidth xheight
- window.width = (xwidth % 10) * 10
- window.height = (xheight % 10) * 10
- call SetReqColor(GRAPHHOST, BACK, 0L)
- call BackFill(GRAPHHOST)
- signal start /* start over */
- end
- end
- end
-
- exit
-
-