Article View: net.micro.atari16
Article #1733Circle2 (source) - Scientific American, Computer Recreations
From: Dwight D McKay
Date: Mon, 08 Sep 1986 13:21
Date: Mon, 08 Sep 1986 13:21
409 lines
16869 bytes
16869 bytes
In A. K. Dewdney's "Computer Recreations" column in the September 1986,
Scientific American he describes several Mandelbrot inspired programs. I've
implemented the first of these, John E. Connett's CIRCLE2 in OSS Pascal. It
draws the pattern in a small window in the upper right hand corner of the
screen. A menu selection called "Commands" allows you to adjust the
parameters of the function as descibed in the "Computer Recreations" column,
as well as adjust the aspect ratio and number of colors used to draw the
patterns. It has been tested on a color monitor, but I believe it will work
just fine on monochrome.
This message contains the source for my implementation of circle2 and the
following message contains the uuencoded binary (for those who don't have
OSS Pascal and are able to uudecode successfully...).
--Dwight Mckay, ECN Text & Workstation Software Support
[arpanet: mckay@ee.ecn.purdue.edu, usenet: ...ihnp4!pur-ee!mckay]
[Compu-serve: 75776,1521, office: EE 348B, phone: (317) 494-3561]
-------------------------------- Cut Here --------------------------------
program circle2;
(* written by Dwight D. McKay - September 1986 *)
(* Circle2 - from SciAm Computer Recreations column, Sept. 86 *)
(* This is a public domain demo program. Feel free to *)
(* distribute it for free; please leave this message and the *)
(* message which is displayed in the "desk" menu item in place *)
(* as that message satisfys the license agreement with OSS. *)
const
{$I gemconst.pas}
Desk_Title = 3; { index of "desk" item in the menu bar }
MAX_X = 100;
MAX_Y = 100;
type
mode_type = (MONO, FOUR, SIXTEEN);
{$I gemtype.pas}
var
menu : Menu_Ptr;
dummy, which, handle : integer;
param_title, param0_item, param1_item, param2_item : integer;
param3_item : integer;
msg : Message_Buffer;
wind_type : integer;
title : Window_Title;
clrs : array [0..15] of integer;
cx, cy, sz : integer;
win_x, win_y, y_fix : integer;
color_mode : mode_type;
{$I gemsubs.pas}
procedure circle2;
{ run the circle2 loop with the specified parameters }
var
i, ii, j, c, ix, iy, w, h : integer;
x, y, z : real;
begin
{ get the window size, set clipping }
Work_Rect(handle, ix, iy, w, h);
Set_Clip(ix, iy, w, h);
{ clear display rectangle }
Paint_Style(Solid);
Paint_Color(White);
Paint_Rect(ix, iy, w, h);
if y_fix > 0 then w := trunc(w/2);
for ii := 0 to w do begin
i := ii * (y_fix + 1);
for j := 0 to h do begin
x := cx + (sz * (ii/100));
y := cy + (sz * (j/100));
z := sqr(x) + sqr(y);
c := trunc(z);
case color_mode of
MONO :
begin
if not(odd(c)) then begin
Line_Color(Black);
line(i+ix, j+iy, i+ix+y_fix, j+iy);
end;
end;
FOUR :
begin
Line_Color(clrs[(c mod 4)]);
line(i+ix, j+iy, i+ix+y_fix, j+iy);
end;
SIXTEEN :
begin
Line_Color(clrs[(c mod 16)]);
line(i+ix, j+iy, i+ix+y_fix, j+iy);
end;
end;
end;
end;
end;
procedure itos(num : integer; var t : Str255);
var
i, j, k : integer;
s : array [0..10] of char;
begin
k := num;
t := '';
j := 0;
if k < 0 then begin
t := '-';
k := -k;
end;
while not (k = 0) do begin
i := k - (10 * trunc(k/10));
k := trunc(k/10);
s[j] := chr(ord('0') + i);
j := j + 1;
end; { while }
for i:= j-1 downto 0 do
t := concat(t, s[i]);
end;
function stoi(text : Str255) : integer;
var
i, j, k : integer;
begin
k := 1;
j := 0;
for i := 1 to length(text) do
if text[i] = '-' then begin
k := -1;
end else if (ord(text[i]) >= ord('0')) or
(ord(text[i]) <= ord('9')) then begin
j := j + trunc(PwrOfTen(length(text) - i) * (ord(text[i]) - ord('0')));
end;
j := j * k;
stoi := j;
end;
procedure param_dialog;
var
param_box : Dialog_Ptr;
cx_idx, cy_idx, sz_idx, exit_btn : integer;
text : Str255;
begin
{ user picked the parameter changer }
param_box := New_Dialog(5,0,0,30,9);
cx_idx := Add_Ditem(param_box, G_FText, Editable,
1, 1, 22, 1, 0, Black * 256 | 128);
itos(cx, text);
Set_Dedit(param_box, cx_idx, ' Lower Left X ____ ', 'X999', text,
System_Font, TE_Left);
cy_idx := Add_Ditem(param_box, G_FText, Editable,
1, 3, 22, 1, 0, Black * 256 | 128);
itos(cy, text);
Set_Dedit(param_box, cy_idx, ' Lower Left Y ____ ', 'X999', text,
System_Font, TE_Left);
sz_idx := Add_Ditem(param_box, G_FText, Editable,
1, 5, 22, 1, 0, Black * 256 | 128);
itos(sz, text);
Set_Dedit(param_box, sz_idx, ' Length of a side ____ ', '9999', text,
System_Font, TE_Left);
exit_btn := Add_Ditem(param_box, G_Button,
Selectable|Default|Touch_Exit,
11, 7, 6, 1, 1, Black * 4096 | Black * 256);
Set_Dtext(param_box, exit_btn, ' Done ', System_Font, TE_Center);
Center_Dialog(param_box);
dummy := DO_Dialog(param_box, cx_idx);
Get_DEdit(param_box, cx_idx, text);
cx := stoi(text);
Get_DEdit(param_box, cy_idx, text);
cy := stoi(text);
Get_DEdit(param_box, sz_idx, text);
sz := stoi(text);
End_Dialog(param_box);
Delete_Dialog(param_box);
end;
procedure aspect_dialog;
var
aspect_box : Dialog_Ptr;
inst_aspect_idx, one_btn, two_btn, exit_btn : integer;
begin
{ aspect ratio correction box }
aspect_box := New_Dialog(5,0,0,18,7);
inst_aspect_idx := Add_DItem( aspect_box, G_Text, None,
1, 1, 14, 1, 0, Black * 256);
Set_DText(aspect_box, inst_aspect_idx,
'Aspect Ratio', System_Font, TE_Center);
one_btn := Add_DItem( aspect_box, G_Button, Selectable|Radio_Btn,
2, 3, 5, 1, 1, Black * 4096 | Black * 256);
Set_DText(aspect_box, one_btn, '1:1', System_Font, TE_Center);
two_btn := Add_DItem( aspect_box, G_Button, Selectable|Radio_Btn,
9, 3, 5, 1, 1, Black * 4096 | Black * 256);
Set_DText(aspect_box, two_btn, '2:1', System_Font, TE_Center);
exit_btn := Add_DItem( aspect_box, G_Button,
Selectable|Default|Touch_Exit,
5, 5, 6, 1, 1, Black * 4096 | Black * 256);
Set_DText(aspect_box, exit_btn, ' Done ', System_Font, TE_Center);
if y_fix = 0 then
Obj_SetState(aspect_box, one_btn, Selected, false)
else
Obj_SetState(aspect_box, two_btn, Selected, false);
Center_Dialog(aspect_box);
dummy := Do_Dialog(aspect_box, 0);
if Obj_State(aspect_box, one_btn) & Selected <> 0 then
y_fix := 0
else
y_fix := 1;
End_Dialog(aspect_box);
Delete_Dialog(aspect_box);
end;
procedure color_dialog;
var
color_box : Dialog_ptr;
inst_color, two_btn, four_btn, sixteen_btn, exit_btn : integer;
begin
{ number of colors to use dialog }
color_box := New_Dialog(5,0,0,18,7);
inst_color := Add_DItem( color_box, G_Text, None,
1, 1, 16, 1, 0, Black * 256);
Set_DText( color_box, inst_color, 'Number of Colors', System_Font,
TE_Center);
two_btn := Add_DItem( color_box, G_Button, Selectable|Radio_Btn,
3, 3, 3, 1, 1, Black * 4096 | Black * 256);
Set_DText( color_box, two_btn, '2', System_Font, TE_Center);
four_btn := Add_DItem( color_box, G_Button, Selectable|Radio_Btn,
7, 3, 3, 1, 1, Black * 4096 | Black * 256);
Set_DText( color_box, four_btn, '4', System_Font, TE_Center);
sixteen_btn := Add_DItem( color_box, G_Button, Selectable|Radio_Btn,
11, 3, 4, 1, 1, Black * 4096 | Black * 256);
Set_DText( color_box, sixteen_btn, '16', System_Font, TE_Center);
exit_btn := Add_DItem( color_box, G_Button,
Selectable|Default|Touch_Exit,
6, 5, 6, 1, 1, Black * 4096 | Black * 256);
Set_DText( color_box, exit_btn, 'Done', System_Font, TE_Center);
case color_mode of
MONO: Obj_SetState( color_box, two_btn, Selected, false);
FOUR: Obj_SetState( color_box, four_btn, Selected, false);
SIXTEEN:Obj_SetState( color_box, sixteen_btn, Selected, false);
end; { case }
Center_Dialog( color_box );
dummy := Do_Dialog( color_box, 0);
if Obj_State( color_box, two_btn) & Selected <> 0 then
color_mode := MONO
else if Obj_State( color_box, four_btn) & Selected <> 0 then
color_mode := FOUR
else
color_mode := SIXTEEN;
End_Dialog( color_box );
Delete_Dialog( color_box );
end;
procedure do_menu(title, item : integer);
{ take care of what happens when the user hits a menu item }
var
alert : Str255;
begin
if title = Desk_Title then begin
{ user picked the "desk" item, show program info }
alert := '[0][';
alert := Concat(alert, ' Circle2|');
alert := Concat(alert, ' Written by Dwight D. Mckay|');
alert := Concat(alert, ' Portions of this product are|');
alert := Concat(alert, 'Copyright (c) 1986, OSS and CCD.|');
alert := Concat(alert, ' Used by Permission of OSS.]');
alert := Concat(alert, '[ OK ]');
dummy := Do_Alert(alert,1);
end else if title = param_title then begin
if item = param0_item then param_dialog
else if item = param1_item then aspect_dialog
else if item = param2_item then color_dialog
else if item = param3_item then begin
Hide_Mouse;
Begin_Update;
circle2;
End_Update;
Show_Mouse;
end;
end;
{ turn the selected menu off again }
Menu_Normal(menu, title);
end; { procedure do_menu }
begin { circle2 }
{ set initial parameters }
cx := -20;
cy := -20;
sz := 40;
clrs[0] := White;
clrs[1] := Black;
clrs[2] := Red;
clrs[3] := Green;
clrs[4] := Blue;
clrs[5] := Cyan;
clrs[6] := Yellow;
clrs[7] := Magenta;
clrs[8] := L_White;
clrs[9] := L_Black;
clrs[10] := L_Red;
clrs[11] := L_Green;
clrs[12] := L_Blue;
clrs[13] := L_Cyan;
clrs[14] := L_Yellow;
clrs[15] := L_Magenta;
color_mode := MONO;
y_fix := 0;
if Init_Gem >= 0 then begin { we got a good GEM startup... }
{ first set up for a window }
Set_Mouse(M_Bee);
wind_type := G_Size|G_Move|G_Close|G_Name;
title := ' Circle2 ';
handle := New_Window(wind_type, title, 0, 0, 0, 0);
{ next set up for the menu bar }
menu := New_Menu(6, ' About Circle2 ');
param_title := Add_MTitle(menu, ' Commands ');
param0_item := Add_MItem(menu, param_title, ' Parameters ');
param1_item := Add_Mitem(menu, param_title, ' Aspect Ratio ');
param2_item := Add_MItem(menu, param_title, ' Colors ');
param3_item := Add_Mitem(menu, param_title, ' Redraw ');
{ OK, now do it... }
Draw_Menu(menu);
Open_Window(handle, 10, 20, MAX_X, MAX_Y);
{ now loop until the user closes the window, handling events }
Set_Mouse(M_Arrow);
repeat
{ check for an event }
which := Get_Event(E_Message, 0, 0, 0, 2000,
false, 0, 0, 0, 0, false, 0, 0, 0, 0,
msg, dummy, dummy, dummy, dummy, dummy, dummy);
{ if we got some message, deal with it }
if which & E_Message <> 0 then
case msg[0] of
{ redraw the window }
WM_Redraw :
begin
Hide_Mouse;
Begin_Update;
circle2;
End_Update;
Show_Mouse;
end;
{ moved or sized, fix things up... }
WM_Sized, WM_Moved :
begin
win_x := msg[6];
win_y := msg[7];
Set_WSize(handle,
msg[4],
msg[5],
msg[6],
msg[7]);
Hide_Mouse;
Begin_Update;
circle2;
End_Update;
Show_Mouse;
end;
{ some menu was hit... }
MN_Selected :
do_menu(msg[3], msg[4]);
end;
until msg[0] = WM_Closed;
{ user hit the "close" box, so clean up and exit }
Close_Window(handle);
Delete_Window(handle);
Erase_menu(menu);
Exit_Gem;
end;
end.
Technical Details
Message-ID:
<8609081321.AA02528@ee.ecn.purdue.edu>Path:
arc1-ca.pugleaf.net!utzoo!mnetor!seismo!lll-crg!nike!ucbcad!ucbvax!EE.ECN.PURDUE.EDU!mckayShow Full Headers
Complete Article Headers
Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: arc1-ca.pugleaf.net!utzoo!mnetor!seismo!lll-crg!nike!ucbcad!ucbvax!EE.ECN.PURDUE.EDU!mckay From: mckay@EE.ECN.PURDUE.EDU (Dwight D McKay) Newsgroups: net.micro.atari16 Subject: Circle2 (source) - Scientific American, Computer Recreations Message-ID: <8609081321.AA02528@ee.ecn.purdue.edu> Date: Mon, 8-Sep-86 09:21:22 EDT Article-I.D.: ee.8609081321.AA02528 Posted: Mon Sep 8 09:21:22 1986 Date-Received: Mon, 8-Sep-86 20:44:25 EDT Sender: daemon@ucbvax.BERKELEY.EDU Organization: The ARPA Internet Lines: 409