Happy Birthday, C++ and farewell, Dr. Mandelbrot

The happy news is that C++ is 25 years old.  The sad news is that Dr. Benoit Mandelbrot, father of fractal geometry, has passed away at the age of 85.  In honor of both these events, here’s a short C++ program that can generate fractals from the Mandelbrot set:

/*			 	The C++ source code for the Fractal Genorator
This is a relativly simple programm that displays the desired fractal
on the screen.  In brief, a fractal is basicaly a formula applied to every
point on a plane (Real numbers is the horizontal axis, Imaginary numbers
is the vertical axis).  For both Julia and Mandelbrot, the formula applied
is Z->Z^2+C.  Where Z is a complex variable(meaning a point on the
Real-Imaginary plane) and C is a complex constant.  This program loops
for every point on the screen and runs the formula above.  Throughout this
file, comments have been placed to explain what is going on.	*/


//	Basic C++ code, to define functions and other 'stuff'
#include <stdlib.h>
#include <graphics.h>
#include <conio.h>
#include <iostream.h>
#include <stdio.h>


// This defines my functions (those not availible premade by Borland C++)
// where the code for each function is found in this file
void menu(void);
void init(void);
void mandel(int, int);
void julia(int _x,int _y);
void options(void);


//  These are the global variables.  That means they can be changed from
//  any of my functions.  This is usfull for my options function.  That
//  means that these variables are 'user' variables and can be changed
//  and the changes will be stored for the displaying part of the program
float frac=1;             // Fractal type, 1=Julia, 2=Mandelbrot
float conx=-0.74;         // Real constant, horizontal axis (x)
float cony=0.1;             // Imaginary constant, verital axis (y)
float Maxx=2;             // Rightmost Real point of plane to be displayed
float Minx=-2;            // Leftmost Real point
float Maxy=1;             // Uppermost Imaginary point
float Miny=-1;            // Lowermost Imaginary point
float initer=50;          // # of times to repeat function

float pixcorx;            // 1 pixel on screen = this many units on the
float pixcory;            // plane for both x and y axis'

int scrsizex;             // Horizontal screen size in pixels
int scrsizey;             // Vertical screen size

int newcolor;             // Used to speed up generation
int lastcolor;            // See main function for more explination



//*****************	MAIN FUNCTION  ****************
/*   It begins by calling the menu function.  If the menu command returns
control to this function without exiting, the next funtion run is my
init(ilization) function (Changes the screen to graphics mode).
	  The next block is in essence, the whole program.  The outer loop is
for the y axis, the inner loop for the x axis.  Meaning, the entire x axis
for one y value is computed then repeated for the next y value.  If you run
the program, this can be seen by the way the pixels are colored in.  The exit
condition is if any button is pressed (keyboard hit or kbhit()).  What
happens for each pixel, in the above order, is either the my julia function
or my mandelbrot function, depending on the value of the frac variable,
which can be changed in the options.
		There is a little command used to speed up the process.  Only every
other pixel on each x axis is computed, if the last color and the new color
match, the pixel inbetween is assumed to be the same color also, otherwise
the function is run for that pixel inbetween.  This speeds up the process
when there are large areas of the same color.
		When the displaying is done, the program waits for you to press a key
before clearing the screen and starting over (back to the menu command in
the beging of the main function)
*/


int main(void)
{
starting:
	menu();
	init();

	int j=0;
	do                                     //Start vertical loop
	{
		int i=0;
		do							  				   //Start horizontal loop
		{

		if (frac) {
		julia(i,j);
		if (lastcolor!=newcolor) julia(i-1,j);
		else putpixel(i-1,j,lastcolor);
		}
		else {
		mandel(i,j);
		if (lastcolor!=newcolor) mandel(i-1,j);
      else putpixel(i-1,j,lastcolor);
		}

		newcolor=lastcolor;
		i+=2;}
		while ( (i<scrsizex) && !kbhit() );	  //End horizontal loop
	j++;}
	while ( (j<scrsizey) && !kbhit() );        //End vertical loop

	getch();
	closegraph();
   goto starting;
	return 0;
 }							//End of main





// **************  MENU FUNCTION *******************
/*   Displays the title and options using printf command.  It then checks
the pressed key.  If '3', the entire program is exited.  If '2' is pressed
the options function is called.  If '1' is pressed, the control of the
program is returned to the main function and the fractal is displayed with
the current options.
*/

void menu(void)
{
start:
	clrscr();
	printf("\t\t\tFractal Generator\n");
	printf("\t\t\t For Julia and Mandelbrot fractals");
	printf("\n\n\n 1.Display Fractal");
	printf("\n 2.Change Display Options");
	printf("\n 3.Exit");
   printf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\t\t\tProgrammed by John Dawson");
	int ink=getch();
	if (ink=='3') exit(1);
	if (ink=='1') return;
	if (ink=='2') options();
	goto start;
}



// ***************** OPTIONS FUNCTION *****************
/*  Display the options using printf.  The user enters the option.  If it
is '9', the program exits the options and goes back to the main menu.
Otherwise, it gets the new value and saves it in the global variable to
be used in computing the fractal.
*/
void options(void)
{
startop:
	clrscr();
	printf("1.Fractal type: %f\n",frac);
	printf("		Mandelbrot = 0				Julia = 1\n");
	printf("2.Real constant: %f\n",conx);
	printf("3.Imaginary constant: %f\n",cony);
	printf("4.Max real value: %f\n",Maxx);
	printf("5.Min real value: %f\n",Minx);
	printf("6.Max imaginary value: %f\n",Maxy);
	printf("7.Min imaginary value: %f\n",Miny);
	printf("8.Initerations: %f\n",initer);
	printf("9.Exit");
	int ans=getch();
	if (ans=='9') return;
	printf("\nEnter New Value:");
   float newval;
	scanf("%f",&newval);
	if (ans=='1') frac=newval;
	else if (ans=='2') conx=newval;
	else if (ans=='3') cony=newval;
	else if (ans=='4') Maxx=newval;
	else if (ans=='5') Minx=newval;
	else if (ans=='6') Maxy=newval;
	else if (ans=='7') Miny=newval;
	else if (ans=='8') initer=newval;
	goto startop;
}



// ***************** INITILIZATION FUNCTION *******************
//      Runs the c++ dos BGI graphics initilization
//  	  Checks for errors and defines the screen values in global variables

void init(void)
{
	int gdriver=DETECT,gmode;
	if (registerbgidriver(EGAVGA_driver) < 0) exit(1);
	initgraph(&gdriver,&gmode, "");

	int errorcode = graphresult();
	if (errorcode != grOk)      /* an error occurred */
	{
		printf("Graphics error: %s\n", grapherrormsg(errorcode));
		printf("Press any key to exit:");
		getch();
      exit(1);               /* terminate with an error code */
   }

	scrsizex= getmaxx() +1;
	scrsizey= getmaxy() +1;
	pixcorx=(Maxx-Minx)/scrsizex;
	pixcory=(Maxy-Miny)/scrsizey;
}





//	***************  JULIA FUNCTION ******************
/*  First, the pixel must be converted to its actual plane value (x,y).
Then it is passed through the function the number of times in the
gloabal variable initer(ations).  If the break condition is reached,
which has been mathmaticaly determined so that if the value of Z is
larger than that, the function will continue for ever to infinity.
Depending on the number of times the function was initerated before the
break value was reached, the color displayed on the screen changes. If
the break value is never reached, the point is considered to be part of
the set. The color for that is black (0).
	For the julia set, the Z is the point under consideration.  The
constant can be changed by the user.
*/

void julia(int xpt, int ypt)
{
	long double x=xpt*pixcorx+Minx;
	long double y=Maxy-ypt*pixcory;		//converting from pixels to points
	long double xnew=0;
	long double ynew=0;

	for(int k=0;k<=initer;k++)  // Each pixel loop
	{
	//The Julia Function Z=Z*Z+c (of complex numbers) into x and y parts
	xnew=x*x-y*y + conx;
	ynew=2*x*y   + cony;
	x=xnew;
	y=ynew;
	if ( (x*x+y*y)>4 ) break;  // Break condition Meaning the loop will go
										// on to a value of infinity.
	}                      // End each pixel loop

	int color = k;
	if (color>15) color=color%15;
	if (k>=initer)
	putpixel(xpt,ypt,0);
	else
	putpixel(xpt,ypt,color);
	
	newcolor=color;
}


//	*************  MANDELBROT FUNCTION ***************
/*  The mandelbrot function is the same as the Julia function except
that the Z is 0 and the constant is the point under consideration. 
*/

void mandel(int xpt, int ypt)
{
	long double x=0;
	long double y=0;		//converting from pixels to points
	long double xnew=0;
	long double ynew=0;

	for(int k=0;k<=initer;k++)  // Each pixel loop
	{
	//The Mandelbrot Function Z=Z*Z+c into x and y parts
	xnew=x*x-y*y + xpt*pixcorx+Minx;
	ynew=2*x*y   + Maxy-ypt*pixcory;
	x=xnew;
	y=ynew;
	if ( (x*x+y*y)>4 ) break;  // Break condition
	}                      // End each pixel loop

	int color = k;
	if (color>15) color=color%15;
	if (k>=initer)
	putpixel(xpt,ypt,0);
	else
	putpixel(xpt,ypt,color);

	newcolor=color;
}

The above was written by John Dawson, available at http://pages.infinit.net/garrick/fractals/program.html

Advertisements
  1. #1 by Joshua on October 17, 2010 - 8:23 AM

    Although there’s nothing C++ about that code. It will run fine in C. But it only runs on DOS. Also, I see a goto. Which would earn Mr. Dawson an F in any college programming course.

  2. #3 by Chadwick on October 18, 2010 - 2:23 PM

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: