home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power Programming
/
powerprogramming1994.iso
/
progtool
/
microcrn
/
issue_39.arc
/
MAN-JUL.FIG
< prev
next >
Wrap
Text File
|
1987-12-02
|
9KB
|
303 lines
/* MAN-JUL - generates Mandelbrot and Julia sets
This program supports an article on fractals in Micro Cornucopia issue #39.
I've only taken the code far enough to allow convenient generation of the sets.
The following problems WILL cause trouble for the sloppy typist:
-no error checking on numeric inputs
-doesn't check for existing file when saving a screen
-doesn't check for existing file when viewing a saved file. This is
particularly ugly since the user gets a text error message while still
in graphics mode. Do a <cr> to recover.
HERCLIB.C is required for compilation. As set up, it should be located in
your main TURBOC sub-directory. HERCLIB is a collection of Hercules graphics
functions from the same issue of Micro C.
I used Turbo C version 1.5 compact model for compilation.
This program will only run on Herc or Herc clone systems. To use it on a CGA
system (waste of time due to poor resolution) or an EGA system (good idea -
looks cool with all those colors) edit HERCLIB to use the BIOS graphics calls
or call your own graphics library. Be sure to change max_colors to reflect the
number of colors available on your system. Of course max_col and max_row need
to be changed in HERCLIB as well.
12-1-87 Larry Fogg Happy Holidays !!! */
#include <stdio.h>
#include "herclib.c" /* Herc graphics routines */
#define sqr(X) (X*X)
const int max_colors = 2;
char choice;
void first_screen () /* say hi */
{
int i;
clear_txt_scr ();
scr_write (0, 4,
" MAN-JUL ",
reverse);
scr_write (0, 5,
" Mandelbrot And Julia Set Generator ",
reverse);
scr_write (11, 24,
"Brought to you by Larry Fogg and Micro Cornucopia Magazine",
under_line);
sleep (4);
} /* first_screen */
char get_choice ()
{
char ch;
clear_txt_scr ();
scr_write (35, 6, "Mandelbrot", normal);
scr_write (35, 8, "Julia", normal);
scr_write (35, 10, "View a screen", normal);
scr_write (35, 12, "Quit", normal);
scr_write (20, 24, "Please enter your choice (M, J, V, or Q): ", normal);
return toupper (getch ());
} /* get_choice */
int bail_out () /* any shift key returns true (non-zero). Did this instead of
int 16 service 1 since Turbo won't allow access to the
flag register and inline assembler is buggy in vers 1.0 */
{
_AH = 2; /* get shift status */
geninterrupt (0x16);
return (_AL & 0x0f); /* tests for alt, control, and both shift keys */
} /* bail_out */
void get_params (int *K, int *M)
{
clear_txt_scr ();
scr_write (1, 7, "Please enter maximum number of iterations: ", normal);
scanf ("%d", K);
scr_write (1, 9, "Please enter maximum modulus: ", normal);
scanf ("%d", M);
} /* get_params */
void get_mandel_params (float *Pmax, float *Pmin, float *Qmax, float *Qmin)
{
clear_txt_scr ();
scr_write (5, 5, "Pmax = ", normal);
scr_write (5, 7, "Pmin = ", normal);
scr_write (5, 9, "Qmax = ", normal);
scr_write (5, 11, "Qmin = ", normal);
gotoXY (12, 5); scanf ("%f", Pmax);
gotoXY (12, 7); scanf ("%f", Pmin);
gotoXY (12, 9); scanf ("%f", Qmax);
gotoXY (12, 11); scanf ("%f", Qmin);
} /* get_mandel_params */
void get_julia_params (float *Xmax, float *Xmin, float *Ymax, float *Ymin,
float *P, float *Q)
{
clear_txt_scr ();
scr_write (5, 5, "Xmax = ", normal);
scr_write (5, 7, "Xmin = ", normal);
scr_write (5, 9, "Ymax = ", normal);
scr_write (5, 11, "Ymin = ", normal);
scr_write (5, 13, "P = ", normal);
scr_write (5, 15, "Q = ", normal);
gotoXY (12, 5); scanf ("%f", Xmax);
gotoXY (12, 7); scanf ("%f", Xmin);
gotoXY (12, 9); scanf ("%f", Ymax);
gotoXY (12, 11); scanf ("%f", Ymin);
gotoXY (9, 13); scanf ("%f", P);
gotoXY (9, 15); scanf ("%f", Q);
} /* get_julia_params */
void save_it (boolean *save, char f_name [13]) /* get file save info */
{
set_text ();
scr_write (5, 2, "Will you want to save this screen? (Y/N) ", normal);
if (toupper (getch ()) == 'Y')
{
scr_write (5, 4, "Please enter file name - ", normal);
scanf ("%s", f_name);
*save = yes;
}
else
*save = no;
clear_txt_scr ();
scr_write (6, 12,
" Press any shift key to quit drawing - then any key returns to menu ",
reverse);
sleep (4);
} /* save_it */
void view_it () /* view a previously saved screen */
{
char file_name [13];
clear_txt_scr ();
scr_write (5, 7, "When you finish viewing, press any key to return to menu.",
normal);
scr_write (5, 5, "Please enter name of file to be viewed: ", normal);
scanf ("%s", file_name);
set_graphics ();
get_screen (file_name, page0); /* show the screen */
getch (); /* display until a key is pressed */
set_text ();
} /* view_it */
void mandel ()
{
float Pmax, Pmin, Qmax, Qmin;
int color, row, col, max_iterations, max_size;
float P, Q, modulus, deltaP, deltaQ,
Xcur, Xlast, Ycur, Ylast;
boolean save;
char file_name [13];
get_params (&max_iterations, &max_size);
get_mandel_params (&Pmax, &Pmin, &Qmax, &Qmin);
save_it (&save, file_name); /* get screen save info */
set_graphics ();
deltaP = (Pmax - Pmin)/(max_col - 1.0); /* determine real axis increment */
deltaQ = (Qmax - Qmin)/(max_row - 1.0);/*determine imaginary axis increment*/
for (col = 0; col <= max_col; col++) /* look at each point on screen */
for (row = 0; row <= max_row; row++)
{
P = Pmin + col*deltaP; /* determine coordinates of point in C plane */
Q = Qmin + row*deltaQ;
Xlast = Ylast = modulus = 0.0;
color = 0;
while ((modulus < max_size) && (color < max_iterations))
{ /* go around until function blows up or until max_iterations */
Xcur = sqr (Xlast) - sqr (Ylast) + P; /* find components of next Z */
Ycur = 2 * Xlast * Ylast + Q;
color++;
Xlast = Xcur; /* update last Z */
Ylast = Ycur;
modulus = sqr (Xcur) + sqr (Ycur); /* find size of Z */
}
draw_point (col, row, (color % max_colors));
if (bail_out ()) /* does user want to quit? */
{
col = max_col + 1;
row = max_row + 1;
}
}
if (save)
save_screen (file_name, page0);
getch (); /* show fractal until key pressed */
set_text ();
} /* mandel */
void julia ()
{
float Xmax, Xmin, Ymax, Ymin, P, Q;
int color, row, col, max_iterations, max_size;
float modulus, deltaX, deltaY,
Xcur, Xlast, Ycur, Ylast;
boolean save;
char file_name [13];
get_params (&max_iterations, &max_size);
get_julia_params (&Xmax, &Xmin, &Ymax, &Ymin, &P, &Q);
save_it (&save, file_name); /* get screen save info */
set_graphics ();
deltaX = (Xmax - Xmin)/(max_col - 1.0); /* determine real axis increment */
deltaY = (Ymax - Ymin)/(max_row - 1.0);/*determine imaginary axis increment*/
for (col = 0; col <= max_col; col++) /* look at each point on screen */
for (row = 0; row <= max_row; row++)
{
modulus = 0.0;
color = 0;
Xlast = Xmin + col * deltaX; /* find coordinates of Z [0] */
Ylast = Ymin + row * deltaY;
while ((modulus < max_size) && (color < max_iterations))
{ /* go around until function blows up or until max_iterations */
Xcur = sqr (Xlast) - sqr (Ylast) + P; /* find components of next Z */
Ycur = 2 * Xlast * Ylast + Q;
color++;
Xlast = Xcur; /* update last Z */
Ylast = Ycur;
modulus = sqr (Xcur) + sqr (Ycur); /* find size of Z */
}
draw_point (col, row, (color % max_colors));
if (bail_out ()) /* does user want to bail out? */
{
col = max_col + 1;
row = max_row + 1;
}
}
if (save)
save_screen (file_name, page0);
getch (); /* show fractal until key pressed */
set_text ();
} /* julia */
main ()
{
init (); /* set up graphics globals */
first_screen ();
while ((choice = get_choice ()) != 'Q')
{
switch (choice)
{
case 'M':
mandel (); /* draw Mandelbrot set */
break;
case 'J':
julia (); /* draw Julia set */
break;
case 'V':
view_it (); /* look at a saved screen */
break;
default:
break;
}
}
clear_txt_scr ();
scr_write (36, 12, "bye ...", normal);
gotoXY (0, 23);
}