This package
is a complete "redo from scratch" of scaling and output routines
previously published at the Euphoria web site as the package "Graphics
Scaling" for use with EuWinGUI. The earlier package had grown organically
from routines originally developed for DOS programs and as a result contained a
lot of unnecessary anachronisms and complexities.
Excluding
the demo programs, the package consists of 3 include files,
"SScale.e", "SPlotDOS.e" and "Bustout.e". I have segregated
a lot of the stuff having to do with scaling into a single include file,
"SScale.e", the idea being that the routines in this file should be
independent of platform (platform here meaning DOS32, Win32Lib, or EuWinGUI).
The file "SPlotDOS.e" (which includes "SScale.e")
contains the platform-specific routines for DOS32 and your DOS32 graphics
program would transact mostly with the global routines in this file. This
arrangement makes the package more portable from platform to platform, each
platform having its own version of "SPlotDOS.e".
As a result,
this package is a lot cleaner and more versatile than the earlier one. No
attempt has been made to keep "backward-compatibility" with
"Graphics Scaling", all include files and routines have new names and
parameter lists. The overall effect of what the package does, however, is
much the
same.
POLYLINE:
A sequence
of the form { {x1,y1}, {x2,y2}, {x3,y3}, ... }, where each {x[i],y[i]},
{x[i+1],y[i+1]} represents a straight line-segment contributing to overall
figure described by the sequence.
POLYGON:
A polyline
defining the boundary of a closed area.
WORLD
COORDINATE:
A coordinate
regarded as a Cartesian coordinate, being used relative to a "window on
the world" (next).
WINDOW ON
WORLD:
If you are
drawing objects in the Cartesian geometry world, there will be a minimum {x,y}
coordinate and a maximum {x,y} coordinate which are sufficient to define the
AREA beyond which the part of your drawing of interest will not extend. e.g.,
if you wanted to draw the line y = mx + c (with m = 1 and c = 0, say) for x
such that 0 <= x <= 10, the window on the world that would accommodate
all of this line would be defined by {0,0} as minimum and {10,10} as maximum
coordinate, that is by a "rising diagonal" represented by the
sequence {{0,0},{10,10}}. I usually use a constant named WIN or variable
named win as the name of this rising diagonal.
VIEWPORT:
A viewport
defines the whole or a part of a graphical output area such as a pixel-graphics
screen on which you wish to draw. For instance, if your program uses a screen
640 pixels wide and 480 pixels high the smallest coordinate on the screen
would, in "machine coordinates", be {1,1} and the
largest
would be {640,480}. A viewport encompassing all of this screen would be defined
by the two-point "rising diagonal" {{1,1}, {640,480}}. If you wished
to draw only on the top left-hand quarter of this screen the viewport would be
defined by the diagonal {{1,1},{320,240}}. If you wanted to draw on the bottom
right-hand quarter the viewport diagonal would be {{320,480}, {640,480}}. And
so on for other lines, curves and shapes. I usually use a constant named VIEW
or variable named view as the name of this rising diagonal.
The actual
drawing is done by "mapping" points in the "window on real
world" onto points in the viewport, and the routines in the package are
dedicated to doing that. Provision is also made for converting viewport
coordinates back into "real world" coordinates so that you can
coordinate things like mouse-clicks with positions in the "real
world".
This section
describes the routines that are global, and so accessible directly by your
calling program, as well as some global constants and variables.
The routines
in file SScale.e do no physical input or output to devices, except to report
some errors to the programmer via DOS32 output, and so can be regarded as
machine-independent and suitable for use with any program, be it DOS-based or
Windows-based.
SetScale(sequence view, sequence win)
Procedure establishes a scaling regimen on
the basis of sequences view and win, where these are rising diagonals defining
the dimensions of a viewport view) and of a "view on the real world"
(win), e.g.,
view = {{1,1},{300,200}}
defines a
viewport with a rising diagonal stretching from the point x = 1, y = 1 to the point x = 300, y = 200. These 2
points would normally be the points defining the limits of the object you are
going to draw on a DOS screen-drawing area. view could also define merely part
of this output area if you wanted to use only that part of the area to draw on.
Sequence win is a "view on the real
world", e.g.,
win
= {{-2,-2},{60,40}}
meaning that
your "take" on the real world is a rectangle having a rising diagonal
stretching from Cartesian point {-2,-2} to Cartesian point 60,40}, and that you
will be doing your drawing inside this area using Cartesian coordinates. This
way of doing things lets you ignore machine coordinates and lets you use only
Cartesian coordinates in your drawing activities once procedure SetScale(view,
win) has been executed, if you use the drawing routines described later in this
document.
s = ScalePoly(sequence world_poly)
Your program must have
executed procedure SetScale(view, win) before using this function. When you
submit a polyline world_poly (in world coordinates) to this function, it
returns a sequence s, being the image of world_poly but scaled for correct
reproduction in the area defined by the current viewport.
s = BackScalePoly(sequence scale_poly)
Your program must have
executed procedure SetScale(view, win) before using this function. If you
submit a polyline scale_poly (in machine coordinates) to this function, it
returns a sequence s, being the image of scale_poly but scaled for correct
reproduction in the area defined by the current world coordinate system.
Essentially this does a reverse-scaling. I have used it to do things like
getting the coordinates of the mouse translated back to world coordinates.
s =
AskMachineCoord(sequence w_point)
Your program must have
executed procedure SetScale(view, win) before using this function. Submit a
coordinate w_point in world coordinates and this will return its scaled value
to sequence s.
Global Constants: MIN = 1 MAX = 2 -- Useful to refer to the elements
X = 1 Y = 2 -- of, e,g., a rising diagonal.
Global Variables: C_View: a copy of the viewport
diagonal you are using.
C_Win: a copy of the window diagonal you are using.
Don't alter these.
This file contains a variety of functions and procedures for
handling typical graphics needs in DOS32. If you use it, it
"includes" SScale.e for you, without your program having to
"include" that.
S_CreateViewport(integer
bgclr, atom frame_flag, object view, sequence win)
Use this function to
create the mapping between a world window (win) and a viewport. This function
calls procedure SetScale() and consequently will alter any scaling already set.
The calling parameters
are:
bgclr = DOS32 colour code (0-15)
viewport's ground (background) colour.
frame_flag = 0 for no framing line drawn around
viewport.
= 1 or 2 or ... 15 for a thin frame
of that colour.
view =
rising diagonal for viewport
win = rising diagonal for the world
coordinate system you will use.
s =
S_WorldMousePosition()
Returns to sequence s the
coordinates of the mouse converted to world coordinates. (STILL UNIMPLEMENTED).
S_DrawPolygon(atom clr,
integer fill, sequence polgon)
Procedure draws a polygon
on the viewport after scaling it.
Parameters are:
clr = the colour to use to draw the
polygon (0-15).
fill = 1 to fill the polygon with colour
clr, else
= 0 for no fill.
polgon = a polyline sequence defining the
boundary of the polygon, in
world coordinates.
S_DrawPolyline(atom clr,
sequence polyline, integer n_dashes)
Procedure draws a
polyline on the viewport after scaling it.
Parameters are:
clr = the colour to use to draw the polyline
(0-15).
polyline =
sequence containing the polyline to be drawn;
its coordinates should be in world coordinates.
n_dashes =
integer > 1, if you want the line to have its segments drawn
with n_dashes between the end-points of each segment.
= 0 if you want no dashing of line
segments.
Clipping
The DOS auto-clipping
often does not work well, leaving traces of earlier auto-clipped lines behind
at screen edges, which is annoying. To cater for this the package includes two
procedures:
S_DrawPolygonClip(atom
clr, integer fill, sequence polgon)
and
S_DrawPolylineClip(atom
clr, sequence polyline)
These do the same job as
S_DrawPolygon() and S_DrawPolyline() and take similar parameter lists as
S_DrawPolygon() and S_DrawPolyline() respectively. Use of S_DrawPolygonClip() and S_DrawPolylineClip() should clear
up any such problem you may encounter, at some sacrifice of speed.
Procedures
S_DrawPolygon() and S_DrawPolyline(), or their Clip variants, are the those you
will likely use most often for general drawing purposes.
S_DrawSequenceXor(sequence pline, atom fg)
This procedure draws a
polyline, in pline, exclusive-ORing it with the background, using colour fg.
This is not a scaled drawing of pline, which should accordingly contain machine
coordinates addressing the Picture, ClickPicture, or drawing control concerned
(which should be selected for drawing on before call). Program TestXOR.exw
gives a simple demo of using this procedure.
S_DrawPolyPic(sequence
wpicture, atom IsToClip)
-----------------------------------------------
This routine is intended
for quick and easy scaled drawing of a drawing structure, wpicture, onto a
viewport. wpicture is typically a modification of a drawing exported from
DrawBustV2, or some structure you have composed yourself. SEE S_DrawPolyPic in
file SPlotDOS.e for more detail.
---------------------------------------------------------------------------------------------------------------------
Include file SPlotDOS.e
also has the following procedures for drawing simple graphs, histograms and
pie-charts. Procedure CreateViewport() should be executed before using them.
S_Grapher(sequence
GrData,integer spot,integer IsToNumber)
This procedure draws a
graph on a bitmap using the input data described by the parameter list below,
and is the most complex procedure in this set.
Parameters are:
GrData = a
complex sequence ... SEE S_Grapher in file SPlotDOS.e.
spot = True if line segments are to be
highlighted by a "spot" drawn at
their ends.
= False if no "spots" are
wanted.
IsToNumber = True
if you want numerical scaling to appear on the graph.
= False if no scaling numbers are
wanted. (NOT YET IMPLEENTED)
S_Histo(sequence h_data,
atom font)
Procedure draws a simple
histogram on a viewport.
Parameters are:
h_data = a
sequence of form {Title, Data, Text}, in which
Title = a simple text title line for
the histogram.
Data
= a simple sequence containing raw data values for the
histogram.
Text
= a sequence containing as many text items as there are
items in Data, each text item
succinctly describing the
the corresponding datum in
Data.
font = the handle of a font with which to draw
the textual elements of
the output.
S_PieChart(sequence
p_data, atom font)
Procedure draws a simple
pie-chart on a viewport.
Parameters are:
p_data = a sequence
in the same form as h_data (above).
font = the handle of a font with which to draw
the textual elements of
the output.
The ForDos part of the
package comes with these demo programs:
TestScale.ex
Program presents an
introductory screen on which coloured polygons are drawn until you press a key.
The program then either presents a randomly generated graph, a random histogram
or a random pie-chart: respond to the prompt with 'Y' to see as many of these
as you wish; respond 'N' to end.
Purpose: illustrates use
of S_CreateViewport(), S_DrawPolygon() and calls to S_Grapher(), S_Histo() and
S_PieChart(), in a simple program.
Epicyc1.ex
Illustration (with
commentary) of generation of an epicycle. An old DOS program was adapted for
this.
Purpose: illustrates use
of S_CreateViewport() and S_DrawPolyline().
SailboatD.ex
Go into the folder
Sailboat and execute SailboatD.ex for this demo.
Purpose: illustrates use
of S_CreateViewport() and S_DrawPolyPic() for drawing a simple animation of a
boat sailing past an island with a winking Sun shining down. The bitmap (BMP)
background was created with Paint - had colour problems with this. The boat and
Sun were created by exportation from drawings produced with drawing program
DrawBustV2; the exportations were then manually modified into functions in
includable files, each file having a function that returns its canonical object
(the images could alternatively been pasted into the program as sequences).
---oooOooo---
Fred Mangan (2010)