A C program to plot the mandlebrot set.
/************************************************************************/
/* mandelbrot set generator by Stanley Garvey 2008 */
/* compile using: */
/*cc -I/usr/include/X11 -L/usr/X11/lib -o mandlebrot mandlebrot.c -lX11 */
/************************************************************************/
/* I am going to use the both the Standard input-output and the X Window*/
/* librarys. I need those librarys header files. I include them here */
#include <stdio.h>
#include <X11/Xlib.h>
/* Now for the program definitions: */
/* I am going to need some boilerplate X definitions */
Display *display;
Window window;
XSetWindowAttributes attributes;
XGCValues gr_values;
XFontStruct *fontinfo;
GC gr_context;
Visual *visual;
int depth;
int screen;
XEvent event;
XColor color, dummy;
/* I want to use a function for the Attractor so I define it here */
unsigned short int attractor();
/* All C programs need a main function. This is where execution starts */
main (argc, argv)
char *argv[];
int argc;
{
/* I need 2 variables for the X window system */
char *colour;
colour="green";
unsigned long forground;
forground= 0xff00;
/* I am going to map the complex plane onto a window so I need to hold */
/* the horizontal & vertical size of the portion of the complex plane */
/* I am viewing, */
float horizontal_size, vertical_size;
/* so that I can map them to the top, bottom, right and left to the */
/* window */
float right, left, top, bottom;
float step_real, step_imag;
/* Variables for the attractor function */
float j, i;
/* Lets make sure that I don't get caught in an infinite loop!! */
unsigned short int iteration_limit=256; /* Set our bail-out value */
/* These are the variables for the window with some defaults filled in */
/*Our drawable area will be 720 pixels wide */
unsigned short int screen_x=720;
/*By 540 pixels high */
unsigned short int screen_y=540;
/* This is the colour I will draw in */
unsigned short int pix_colour;
/* This is where I will Draw */
register int i1, j1;
/* These are the defaults for the complex plane, origin centre of the */
/* window, offset by -.6 west */
float origin_x= -.6;
float origin_y= 0.0;
/* The scale factor will be PI at 100 percent zoom */
float z_range=3.1415927;
float percent_zoom=100;
horizontal_size=(z_range*100)/percent_zoom;
/* Calculate vertical range with a 4:3 aspect ratio */
vertical_size=(horizontal_size)*.8;
/* Map complex plane to middle of drawable */
left= origin_x-(horizontal_size/2);
right=left+horizontal_size;
bottom= origin_y-(vertical_size/2);
top=bottom+vertical_size;
step_real=horizontal_size/screen_x;
step_imag=vertical_size/screen_y;
/* Open an X window */
display = XOpenDisplay(NULL);
screen = DefaultScreen(display);
visual = DefaultVisual(display,screen);
depth = DefaultDepth(display,screen);
attributes.background_pixel = XBlackPixel(display,screen);
window = XCreateWindow( display,XRootWindow(display,screen),
200, 200, screen_x, screen_y, 5, depth, InputOutput,
visual ,CWBackPixel, &attributes);
XSelectInput(display,window,ExposureMask | KeyPressMask) ;
fontinfo = XLoadQueryFont(display,"6x10");
XAllocNamedColor(display, DefaultColormap(display, screen),"red",
&color,&dummy);
gr_values.font = fontinfo->fid;
gr_values.foreground = color.pixel;
gr_context=XCreateGC(display,window,GCFont+GCForeground, &gr_values);
XFlush(display);
XMapWindow(display,window);
/* Start mapping the set */
printf("Generating set.\n");
j1=0;
for(j=bottom;j<top;(j+=step_imag))
{
i1=0;
for(i=left;i<right;(i+=step_real))
{
/* call the attractor function the colour == number of iterations */
pix_colour=attractor(i, j, iteration_limit);
/* I have 77 colours in my palete so I set colour to modulus 78 */
pix_colour=(pix_colour % 78);
/* set the colour to a valid X11 named colour */
/* This is a bit clunky and should be rewritten as a function */
switch(pix_colour)
{
case 0:colour="grey100";break;
case 1:colour="grey96";break;
case 2:colour="grey92";break;
case 3:colour="grey88";break;
case 4:colour="grey84";break;
case 5:colour="grey80";break;
case 6:colour="grey76";break;
case 7:colour="grey72";break;
case 8:colour="grey68";break;
case 9:colour="grey64";break;
case 10:colour="grey60";break;
case 11:colour="grey56";break;
case 12:colour="grey52";break;
case 13:colour="grey48";break;
case 14:colour="grey46";break;
case 15:colour="grey42";break;
case 16:colour="grey38";break;
case 17:colour="grey36";break;
case 18:colour="grey32";break;
case 19:colour="grey28";break;
case 20:colour="grey26";break;
case 21:colour="grey22";break;
case 22:colour="grey18";break;
case 23:colour="grey16";break;
case 24:colour="grey12";break;
case 25:colour="NavyBlue";break;
case 26:colour="MidnightBlue";break;
case 27:colour="DarkSlateBlue";break;
case 28:colour="SlateBlue";break;
case 29:colour="blue";break;
case 30:colour="RoyalBlue";break;
case 31:colour="DodgerBlue";break;
case 32:colour="DeepSkyBlue";break;
case 33:colour="SkyBlue";break;
case 34:colour="LightSkyBlue";break;
case 35:colour="turquiose";break;
case 36:colour="DarkTurquiose";break;
case 37:colour="LightGreen";break;
case 38:colour="green";break;
case 39:colour="SeaGreen";break;
case 40:colour="DarkSeaGreen";break;
case 41:colour="MediumSeaGreen";break;
case 42:colour="LightSeaGreen";break;
case 43:colour="DarkYellow";break;
case 44:colour="yellow";break;
case 45:colour="LightYellow";break;
case 46:colour="DarkOrange";break;
case 47:colour="orange";break;
case 48:colour="LightOrange";break;
case 49:colour="DarkGreen";break;
case 50:colour="yellow";break;
case 51:colour="DarkYellow";break;
case 52:colour="orange";break;
case 53:colour="DarkOrange";break;
case 54:colour="magenta";break;
case 55:colour="red";break;
case 56:colour="DarkRed";break;
case 57:colour="Violetred";break;
case 58:colour="purple";break;
case 59:colour="cyan";break;
case 60:colour="yellow";break;
case 61:colour="DarkYellow";break;
case 62:colour="orange";break;
case 63:colour="DarkOrange";break;
case 64:colour="red";break;
case 65:colour="DarkRed";break;
case 66:colour="VioletRed";break;
case 67:colour="DeepPink";break;
case 68:colour="purple";break;
case 69:colour="cyan";break;
case 70:colour="yellow";break;
case 71:colour="DarkYellow";break;
case 72:colour="MediumVioletRed";break;
case 73:colour="PaleVioletRed";break;
case 74:colour="OrangeRed";break;
case 75:colour="tomato";break;
case 76:colour="IndianRed";break;
case 77:colour="red";break;
default: colour="black";
}
/* Block of x Window code to draw the pixel */
XAllocNamedColor(display,
DefaultColormap(display, screen),colour, &color,&dummy);
gr_values.foreground = color.pixel;
gr_context=XCreateGC(display,window,GCFont+GCForeground, &gr_values);
XDrawPoint(display,window,gr_context,i1,j1);
i1++;
}
j1++;
XFlush(display);
}
/* Block of x Window code; loops until keypress then closes window */
while(1){
XNextEvent(display,&event);
switch(event.type){
case Expose:
printf("Set done.\n ");
break;
case KeyPress:
XCloseDisplay(display);
exit(0);
/* Okay we're done here, nothing to see, move along please */
}
}
}
/* Mandlebrot attractor Function Definition */
unsigned short int attractor(i, j, iteration_limit)
/* here we declare our parameters */
/* passed from the calling function */
float i;
float j;
unsigned short int iteration_limit;
{
/* our local Variables are declared here */
/* count number of times round the loop */
unsigned short int number_iterations=0;
float x, y, x2, y2;
/* keep doing the calculation as long as it does not start to aproach */
/* infinity and it has not hit my bail out Value */
while(number_iterations<iteration_limit && (x2+y2)<=4)
{
y2=(y*y);
x2=(x*x);
y=(2*x*y)+j;
x=(x2-y2)+i;
number_iterations++;
}
/* Not interested in the calculation, */
/* only the number times round the loop */
return(number_iterations);
}