home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 10 Tools
/
10-Tools.zip
/
pmos2002.zip
/
DEMO
/
SRC
/
LINEDEMO.MOD
< prev
next >
Wrap
Text File
|
1996-11-08
|
16KB
|
492 lines
MODULE LineDemo;
(********************************************************)
(* *)
(* Demonstration of GWindows *)
(* *)
(* Programmer: S. Lontis, P. Moylan *)
(* Last edited: 8 November 1996 *)
(* Status: Working *)
(* *)
(* Note: This is an EGA demonstration. I've *)
(* done some scaling to make it work with other *)
(* screen resolutions, but I lost patience for *)
(* covering the completely general case. *)
(* *)
(********************************************************)
FROM TaskControl IMPORT
(* type *) Lock,
(* proc *) CreateTask, CreateLock, Obtain, Release;
FROM Semaphores IMPORT
(* type *) Semaphore,
(* proc *) CreateSemaphore, Wait, Signal;
FROM ScreenGeometry IMPORT
(* type *) Point;
FROM Graphics IMPORT
(* type *) ColourType,
(* proc *) GetScreenShape;
FROM GWindows IMPORT
(* type *) Window, BorderType,
(* proc *) OpenWindow, Line, PutPixel2, WriteString, ClearWindow,
CloseWindow, WindowMemory, SetColour, InitGraphics;
FROM MATHLIB IMPORT
(* proc *) Sin, Cos, Exp;
FROM Keyboard IMPORT
(* proc *) InKey;
FROM Timer IMPORT
(* proc *) Sleep;
(************************************************************************)
CONST pi = 3.14159;
TYPE Vector2 = RECORD
x, y: LONGREAL;
END;
VAR
Xmax, Ymax, CharHeight: CARDINAL;
maxcolour: ColourType;
(************************************************************************)
(*
PROCEDURE Sleep (time: CARDINAL);
(* Dummy procedure to prevent Timer.Sleep from being called. *)
(* Needed only during debugging. *)
BEGIN
END Sleep;
*)
(************************************************************************)
(* "PRESS ANY KEY TO CONTINUE" *)
(************************************************************************)
PROCEDURE Pause;
VAR dummy: CHAR; w: Window;
BEGIN
OpenWindow(w,Xmax DIV 2,30,Xmax DIV 2 + 205,40+CharHeight,0,3,single);
WriteString (w, "Press any key to continue");
dummy := InKey();
CloseWindow (w);
END Pause;
(************************************************************************)
(* FLOATING POINT ROUND *)
(************************************************************************)
PROCEDURE ROUND (x: LONGREAL): INTEGER;
VAR negative: BOOLEAN; result: INTEGER;
BEGIN
negative := FALSE;
IF x < 0.0 THEN
x := -x; negative := TRUE;
END (*IF*);
x := x + 0.5;
IF x >= VAL(LONGREAL, MAX(INTEGER)) THEN result := MAX(INTEGER)
ELSE result := VAL (INTEGER, x);
END (*IF*);
IF negative THEN RETURN -result
ELSE RETURN result;
END (*IF*);
END ROUND;
(************************************************************************)
PROCEDURE Round2 (fpoint: Vector2): Point;
(* Converts floating point (x,y) coordinates to cardinal. *)
VAR result: Point;
BEGIN
result.x := ROUND (fpoint.x);
result.y := ROUND (fpoint.y);
RETURN result;
END Round2;
(************************************************************************)
(* CRO SIMULATION *)
(************************************************************************)
VAR
(* Data shared between the DataGenerator and CROdemo tasks. *)
ToPlot: RECORD
ready: Semaphore;
access: Lock;
datum: LONGREAL;
END (*RECORD*);
(************************************************************************)
PROCEDURE DataGenerator;
(* Runs as a separate task, generating data for task CROdemo to plot.*)
CONST tincr = 0.002; M0 = 0.8;
alpha = 5.0; omega = 10.0;
VAR t, value, M: LONGREAL;
BEGIN
t := 0.0; M := M0;
LOOP
value := M*(1.0 - 2.0*Exp(-alpha*t)*Cos(omega*t));
WITH ToPlot DO
Obtain (access);
datum := value;
Release (access);
Signal (ready);
END (*WITH*);
t := t + tincr;
IF t > 1.0 THEN
t := 0.0; M := -M;
END (*IF*);
Sleep (120);
END (*LOOP*);
END DataGenerator;
(************************************************************************)
TYPE index = [10..190];
VAR data: ARRAY index OF CARDINAL;
PROCEDURE CROdemo;
(* Runs as a separate task, plotting a moving waveform *)
(* Colours on the default palette are: *)
(* 0 black 1 blue 2 green 3 cyan *)
(* 4 red 5 magenta 6 brown 7 white *)
(* 8 grey 9 lt blue 10 lt green 11 lt cyan *)
(* 12 lt red 13 lt magenta 14 yellow 15 very white *)
CONST colour = 10;
VAR CRO: Window; t: index;
newval: LONGREAL; scaledval: INTEGER;
background: CARDINAL;
PROCEDURE Blob (x, y: INTEGER);
BEGIN
PutPixel2 (CRO, x, y);
PutPixel2 (CRO, x+1, y);
PutPixel2 (CRO, x, y+1);
PutPixel2 (CRO, x+1, y+1);
PutPixel2 (CRO, x, y-1);
PutPixel2 (CRO, x+1, y-1);
END Blob;
(********************************************************************)
BEGIN
IF maxcolour > 8 THEN background := 8
ELSE background := 0
END (*IF*);
OpenWindow (CRO,Xmax-200,Ymax-CharHeight-140,Xmax,Ymax-CharHeight-10,
0,background,single);
WindowMemory (CRO, FALSE);
WITH ToPlot DO
CreateSemaphore (ready, 0);
CreateLock (access);
END (*WITH*);
FOR t := MIN(index) TO MAX(index) DO
PutPixel2 (CRO, t, 30);
data[t] := 30;
END (*FOR*);
CreateTask (DataGenerator, 4, "Data for CRO");
t := MIN(index);
LOOP
WITH ToPlot DO
Wait (ready);
Obtain (access);
newval := datum;
Release (access);
END (*WITH*);
scaledval := 60 + VAL(INTEGER,30.0*newval);
(* Original version: non-shifting:
SetColour (CRO, background);
PutPixel2 (CRO, t, data[t]);
SetColour (CRO, colour);
PutPixel2 (CRO, t, scaledval);
data[t] := scaledval;
IF t = MAX(index) THEN t := MIN(index) ELSE INC(t) END(*IF*);
*)
(* New version: shift data in window *)
FOR t := MIN(index) TO MAX(index)-1 DO
SetColour (CRO, background);
PutPixel2 (CRO, t, data[t]);
data[t] := data[t+1];
SetColour (CRO, colour);
PutPixel2 (CRO, t, data[t]);
END (*FOR*);
t := MAX(index);
SetColour (CRO, background);
Blob (t, data[t]);
data[t] := scaledval;
SetColour (CRO, 15);
Blob (t, scaledval);
END (*LOOP*);
CloseWindow (CRO);
END CROdemo;
(************************************************************************)
(* MISCELLANEOUS DEMO PLOTS *)
(************************************************************************)
PROCEDURE Spiral (w: Window; centre: Point;
radius, ang: LONGREAL; n: CARDINAL);
CONST thinc = 0.05*pi;
VAR theta, r: LONGREAL;
i, ptnumber: CARDINAL;
pt, pt1: Point;
BEGIN
theta := ang; pt := centre;
ptnumber := 40*n;
FOR i := 1 TO ptnumber DO
theta := theta+thinc; r:= radius*VAL(LONGREAL,i)/VAL(LONGREAL,ptnumber);
pt1.x := ROUND(3.0*r*Cos(theta)) + centre.x;
pt1.y := ROUND(2.0*r*Sin(theta)) + centre.y;
Line (w, pt, pt1);
pt := pt1;
END (* FOR *)
END Spiral;
(************************************************************************)
PROCEDURE Rose(w: Window; xoffset, yoffset: INTEGER;
scale, m, n: CARDINAL);
VAR inner, outer: ARRAY [1..100] OF Point;
i, j: CARDINAL;
r, theta, thinc: LONGREAL;
BEGIN
thinc := 2.0*pi/VAL(LONGREAL,n);
FOR i := 1 TO n DO
inner[i].x := xoffset;
inner[i].y := yoffset;
END (* FOR *);
FOR j := 1 TO m DO
theta := -VAL(LONGREAL,j)*pi/VAL(LONGREAL,n);
r := VAL(LONGREAL,j*scale)/VAL(LONGREAL,m);
FOR i := 1 TO n DO
theta := theta+thinc;
outer[i].x := xoffset + ROUND (3.0*r*Cos(theta));
outer[i].y := yoffset + ROUND (2.0*r*Sin(theta));
END (* FOR *);
FOR i:= 1 TO n DO
Line (w, outer[i], outer[(i MOD n) + 1]);
Line (w, outer[(i MOD n) + 1], inner[i]);
Line (w, inner[i], outer[i]);
inner[i] := outer[i];
END (* FOR *);
END (* FOR *)
END Rose;
(************************************************************************)
PROCEDURE SquareinSquare (w: Window; xoffset, yoffset, size: LONGREAL);
CONST mu = 0.1;
VAR pt, ptd: ARRAY[1..4] OF Vector2;
i, j, nextj: INTEGER;
um: LONGREAL;
pti: Point;
BEGIN
pt[1].x:= xoffset+size*2.5; pt[1].y:= yoffset+size*2.0;
pt[2].x:= xoffset+size*2.5; pt[2].y:= yoffset;
pt[3].x:= xoffset; pt[3].y:= yoffset;
pt[4].x:= xoffset; pt[4].y:= yoffset+size*2.0;
um:= 1.0-mu;
FOR i:= 1 TO 21 DO
pti := Round2 (pt[4]);
FOR j:= 1 TO 4 DO
Line(w, Round2 (pt[j]), pti);
pti := Round2 (pt[j]);
nextj:= (j MOD 4) + 1;
ptd[j].x:= um*pt[j].x + mu*pt[nextj].x;
ptd[j].y:= um*pt[j].y + mu*pt[nextj].y
END (* FOR *);
FOR j:= 1 TO 4 DO pt[j]:= ptd[j] END (* FOR *)
END (* FOR *)
END SquareinSquare;
(************************************************************************)
PROCEDURE SpiroGraph(w: Window; xcenter, ycenter: INTEGER;
a, b, d: CARDINAL);
CONST Scale= 6.0; Xscale = 1.6*Scale; steps = 50;
VAR pt, oldpt: Point;
i: CARDINAL;
phi, theta, thinc: LONGREAL;
(********************************************************************)
PROCEDURE hcf (i, j: CARDINAL) : CARDINAL;
VAR remain: CARDINAL;
BEGIN
REPEAT
remain := i MOD j;
i := j; j := remain;
UNTIL remain = 0;
RETURN i;
END hcf;
(********************************************************************)
BEGIN
theta := 0.0; thinc:= 2.0*pi/VAL(LONGREAL,steps);
oldpt.x := xcenter + ROUND(Xscale*VAL(LONGREAL,a - b + d));
oldpt.y := ycenter;
FOR i := 1 TO steps*(b DIV hcf(a,b)) DO
theta:= theta + thinc; phi:= theta*VAL(LONGREAL,a-b)/VAL(LONGREAL,b);
pt.x := xcenter+ROUND(Xscale*(VAL(LONGREAL,a-b)*Cos(theta)
+ VAL(LONGREAL,d)*Cos(phi)));
pt.y := ycenter+ROUND(Scale*(VAL(LONGREAL,a-b)*Sin(theta)
- VAL(LONGREAL,d)*Sin(phi)));
Line (w, pt, oldpt);
oldpt := pt;
END (* FOR *)
END SpiroGraph;
(************************************************************************)
PROCEDURE StringPoly (w: Window; xcentre, ycentre, radius, n: CARDINAL);
(* Draws a polygon of n vertices, with every vertex connected to *)
(* every other. *)
VAR pt: ARRAY[1..100] OF Point;
i, j: CARDINAL;
theta, thinc: LONGREAL;
BEGIN
theta:=0.0; thinc:= 2.0*pi/VAL(LONGREAL,n);
FOR i := 1 TO n DO
pt[i].x := VAL(INTEGER,xcentre) + ROUND(VAL(LONGREAL,3*radius-20)*Cos(theta));
pt[i].y := VAL(INTEGER,ycentre) + ROUND(VAL(LONGREAL,2*radius)*Sin(theta));
theta:= theta + thinc;
END (* FOR *);
FOR i:= 1 TO n-1 DO
FOR j:= i+1 TO n DO
Line (w, pt[i], pt[j]);
END (* FOR *)
END (* FOR *);
END StringPoly;
(************************************************************************)
(* THE MAIN DEMONSTRATION TASK *)
(************************************************************************)
PROCEDURE RunTheDemo;
VAR w1, w2, w3, w4, w5: Window;
i: [5..15]; b, c: [1..4];
point: Point;
xc, yc: CARDINAL;
radius: LONGREAL;
BEGIN
OpenWindow(w5,15,Ymax-CharHeight-8,275,Ymax,1,3,single);
WriteString (w5,' Demonstration of line graphics');
IF Xmax > 400 THEN
xc := Xmax-201;
CreateTask (CROdemo, 3, "CRO demo");
ELSE
xc := 3*Xmax DIV 4;
END (*IF*);
yc := 7*Ymax DIV 8;
OpenWindow(w1,0,0,xc,yc,7,6,single);
WriteString (w1,'Spiral');
xc := xc DIV 2; yc := yc DIV 2;
IF xc DIV 3 < yc DIV 2 THEN
radius := 0.3*VAL(LONGREAL,xc);
ELSE
radius := 0.5*VAL(LONGREAL,yc);
END (*IF*);
point.x := xc; point.y := yc;
Spiral (w1, point, radius, 0.0, 8);
Sleep(2000);
FOR i:= 5 TO 15 BY 2 DO
ClearWindow (w1);
WriteString (w1, 'Rose Pattern');
Rose (w1,xc,yc,VAL(CARDINAL,radius),i,i);
Sleep (1000);
END (* FOR *);
xc := xc DIV 2;
yc := yc DIV 2;
radius := 0.5*radius;
OpenWindow(w4,Xmax DIV 3,Ymax DIV 3,
Xmax DIV 3+2*xc,Ymax DIV 3+2*yc,0,3,double);
StringPoly (w4,xc,yc,VAL(CARDINAL,radius),17);
Sleep(1000);
OpenWindow(w2,320,40,620,180,4,7,single);
WriteString (w2,' Rotating Squares');
SquareinSquare (w2, 125.0, 20.0, 50.0);
SquareinSquare (w2, 15.0, 30.0, 40.0);
Sleep(1000);
OpenWindow(w3,20,20,240,180,14,6,double);
FOR b := 2 TO 3 DO
ClearWindow(w3);
WriteString (w3,'SpiroGraphs');
FOR c := 2 TO 4 DO
SpiroGraph(w3,110,70,9,b,c);
Sleep(1000);
END (* FOR *)
END (* FOR *);
Pause;
Sleep(1000); CloseWindow (w1);
Sleep(1000); CloseWindow (w2);
Sleep(1000); CloseWindow (w3);
Sleep(1000); CloseWindow (w4);
Sleep(1000); CloseWindow (w5);
END RunTheDemo;
(************************************************************************)
BEGIN
InitGraphics(18);
GetScreenShape (Xmax, Ymax, maxcolour, CharHeight);
RunTheDemo;
END LineDemo.