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 2 include files, "SScale.e" and "SPlotEWG.ew".
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 "SPlotEWG.ew" (which
_includes_ "SScale.e") contains
the platform-specific routines for EuWinGUI and your EuWinGUI 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 "SPlotEWG.ew".
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, and it is easy to
alter the code of a EuWinGUI program that successfully uses the original
"Graphics Scaling" package so that it will use this "General
Scaling" package.
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) 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 a variable win as the name of
this rising diagonal.
VIEWPORT:
A viewport defines the whole or a part of
a graphical output object such as a bitmap or a EuWinGUI Picture or
ClickPicture on which you wish to draw. For instance, if your program creates a
bitmap 200 pixels wide and 100 pixels high the smallest coordinate on the
bitmap would, in "machine coordinates", be {0,0} and the largest
would be {200,100}. A viewport encompassing all of this bitmap would be defined
by the "rising diagonal" {{0,0},{200,100}}. If you wished to draw
only on the top right-hand quarter of this bitmap our viewport would be defined
by the diagonal {{0,0},{100,50}}. If we wanted to draw on the bottom left-hand
quarter the viewport diagonal would be {{100,50},{200,100}}. And so on . I
usually use VIEW or view as
the name for this 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
memory bitmap, a EuWinGUI Picture or
ClickPicture, or a DOS screen-drawing area).
view could also define merely part of any of these possible output areas
if you wanted to use only that part of the area to draw on.
Sequence win is a "window 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.
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; its
scaled value will be returned to sequence s.
Global Constants: MIN
= 1 MAX = 2
X = 1 Y
= 2
These are useful to refer to the elements of
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 when using EuWinGUI. If you
use it, it "includes" SScale.e for you, without your program having
to "include" it.
BMHwnd = S_CreateBitmap
(atom ctl, atom bgclr, integer PicType,
sequence view, sequence win)
Use this function to create the mapping between a world window (win) and
a memory bitmap. This function calls procedure SetScale() and consequently will
alter any previously set scaling.
The calling parameters are:
Ctl = handle of the control on which the
bitmap will be displayed.
Bgclr = RBG colour for
the bitmap's ground (background) colour.
PicType = Picture or ClickPicture as appropriate to describe ctl.
View = rising diagonal for viewport
Win = rising diagonal for the world
coordinate system you will use.
The function returns the handle of the bitmap it creates, so you can do
drawing on the bitmap as well as deleting the bitmap with DeleteImage() when
your program ends.
s = S_WorldMousePosition()
Returns to sequence s the coordinates of the mouse converted to world
co-ordinates. For this to work properly and most easily the output device for
visualising the bitmap image should be a ClickPicture.
S_DrawPolygon(atom clr, integer fill,
sequence polgon)
Procedure draws a polygon on the bitmap after scaling it and visualises
the result.
Parameters are:
clr = the RBG colour to use to draw the
polygon.
fill = True to fill the polygon with
colour clr, else False 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 bitmap after scaling it and visualises
the result.
Parameters are:
clr = the RBG colour to use to draw the
polyline.
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
I
find when using a EuWinGUI Picture or ClickPicture control, that the automatic
clipping of drawing elements at the edge of the control is sometimes less than
perfect and that traces of such drawing may be left at the 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 two 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 bitmap. wpicture is typically a modification of a
drawing exported from DrawBustV2, or some similar structure you have composed
yourself.
----------------------------------------------------------------------------------------------------------------------
Include file SPlotEWG.ew also has the following procedures for drawing
simple graphs, histograms and pie-charts. Function CreateBitmap() should be
executed before using them.
S_Grapher(sequence GrData, atom font,
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 sequence ... SEE SPlotEWG.ew for detail.
font = the handle of a font with which to draw the textual
elements of
the output.
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.
S_Histo(sequence h_data, atom font)
Procedure draws a simple histogram on a memory bitmap and visualises the
result.
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 memory bitmap and visualises the
result.
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 EuWinGUI part of the package comes with these demo programs:
TestScale.exw
Program presents an introductary screen on which coloured polygons are
drawn until you click the screen. The program then presents either a randomly
generated graph, a random histogram or a random pie-chart; keep on clicking to
see as many as you wish. Click [X] to end.
Purpose: illustrates use of
S_CreateBitmap(), S_DrawPolygon() and calls to S_Grapher(), S_Histo() and
S_PieChart(), in a simple program.
Asteroids.exw
A
resurection of the old asteroid-zapping game.
Purpose: illustrates use of
S_CreateBitmap(), S_DrawPolygonClip(), and S_DrawPolylineClip() in a more
challenging program.
Sailboat.exw
Go into the folder SailboatOOP and execute
Sailboat.exw for this demo.
Purpose: illustrates use of
S_CreateBitmap() and S_DrawPolyPic() for drawing complex structures in an
environment using EuCanOOP.e, so as to get multiple (5) objects moving around
on a scaled bitmap. The objects were all created by exportation from drawings
created 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)